From 231aecc31ac1cf5b8e3e9e020c6fea88cc292372 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Fri, 1 Oct 2021 10:32:11 +0300 Subject: [PATCH 1/2] Fix Cookie handling in reactive rest client Original discussion in https://quarkusio.zulipchat.com/#narrow/stream/187030-users/topic/Reactive.20Client.20Cookies --- .../JaxrsClientReactiveProcessor.java | 46 +++++++++++++++++ .../client/reactive/headers/CookieTest.java | 50 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/headers/CookieTest.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 e65f266d47fab..3bb3612ca6e17 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 @@ -678,6 +678,21 @@ A more full example of generated client (with sub-resource) can is at the bottom handleHeaderMethod.getMethodParam(1)); handleHeaderMethod.returnValue(invocationBuilderRef); invocationBuilderEnrichers.put(handleHeaderDescriptor, paramValue); + } else if (param.parameterType == ParameterType.COOKIE) { + // cookies are added at the invocation builder level + MethodDescriptor handleCookieDescriptor = MethodDescriptor.ofMethod(subName, + subMethod.getName() + "$$" + subMethodIndex + "$$handleCookie$$" + paramIdx, + Invocation.Builder.class, + Invocation.Builder.class, param.type); + MethodCreator handleCookieMethod = sub.getMethodCreator(handleCookieDescriptor); + + AssignableResultHandle invocationBuilderRef = handleCookieMethod + .createVariable(Invocation.Builder.class); + handleCookieMethod.assign(invocationBuilderRef, handleCookieMethod.getMethodParam(0)); + addCookieParam(handleCookieMethod, invocationBuilderRef, param.name, + handleCookieMethod.getMethodParam(1)); + handleCookieMethod.returnValue(invocationBuilderRef); + invocationBuilderEnrichers.put(handleCookieDescriptor, paramValue); } else if (param.parameterType == ParameterType.FORM) { formParams = createIfAbsent(subMethodCreator, formParams); subMethodCreator.invokeInterfaceMethod(MULTIVALUED_MAP_ADD, formParams, @@ -751,6 +766,22 @@ A more full example of generated client (with sub-resource) can is at the bottom handleHeaderMethod.returnValue(invocationBuilderRef); invocationBuilderEnrichers.put(handleHeaderDescriptor, subMethodCreator.getMethodParam(paramIdx)); + } else if (param.parameterType == ParameterType.COOKIE) { + // cookies are added at the invocation builder level + MethodDescriptor handleHeaderDescriptor = MethodDescriptor.ofMethod(subName, + subMethod.getName() + "$$" + subMethodIndex + "$$handleCookie$$" + paramIdx, + Invocation.Builder.class, + Invocation.Builder.class, param.type); + MethodCreator handleCookieMethod = c.getMethodCreator(handleHeaderDescriptor); + + AssignableResultHandle invocationBuilderRef = handleCookieMethod + .createVariable(Invocation.Builder.class); + handleCookieMethod.assign(invocationBuilderRef, handleCookieMethod.getMethodParam(0)); + addCookieParam(handleCookieMethod, invocationBuilderRef, param.name, + handleCookieMethod.getMethodParam(1)); + handleCookieMethod.returnValue(invocationBuilderRef); + invocationBuilderEnrichers.put(handleHeaderDescriptor, + subMethodCreator.getMethodParam(paramIdx)); } else if (param.parameterType == ParameterType.FORM) { formParams = createIfAbsent(subMethodCreator, formParams); subMethodCreator.invokeInterfaceMethod(MULTIVALUED_MAP_ADD, formParams, @@ -907,6 +938,21 @@ A more full example of generated client (with sub-resource) can is at the bottom handleHeaderMethod.getMethodParam(1)); handleHeaderMethod.returnValue(invocationBuilderRef); invocationBuilderEnrichers.put(handleHeaderDescriptor, methodCreator.getMethodParam(paramIdx)); + } else if (param.parameterType == ParameterType.COOKIE) { + // headers are added at the invocation builder level + MethodDescriptor handleHeaderDescriptor = MethodDescriptor.ofMethod(name, + method.getName() + "$$" + methodIndex + "$$handleCookie$$" + paramIdx, + Invocation.Builder.class, + Invocation.Builder.class, param.type); + MethodCreator handleCookieMethod = c.getMethodCreator(handleHeaderDescriptor); + + AssignableResultHandle invocationBuilderRef = handleCookieMethod + .createVariable(Invocation.Builder.class); + handleCookieMethod.assign(invocationBuilderRef, handleCookieMethod.getMethodParam(0)); + addCookieParam(handleCookieMethod, invocationBuilderRef, param.name, + handleCookieMethod.getMethodParam(1)); + handleCookieMethod.returnValue(invocationBuilderRef); + invocationBuilderEnrichers.put(handleHeaderDescriptor, methodCreator.getMethodParam(paramIdx)); } else if (param.parameterType == ParameterType.FORM) { formParams = createIfAbsent(methodCreator, formParams); methodCreator.invokeInterfaceMethod(MULTIVALUED_MAP_ADD, formParams, diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/headers/CookieTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/headers/CookieTest.java new file mode 100644 index 0000000000000..29f493e21b5bc --- /dev/null +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/headers/CookieTest.java @@ -0,0 +1,50 @@ +package io.quarkus.rest.client.reactive.headers; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.net.URI; + +import javax.enterprise.context.ApplicationScoped; +import javax.ws.rs.CookieParam; +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import org.eclipse.microprofile.rest.client.RestClientBuilder; +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; +import io.quarkus.test.common.http.TestHTTPResource; + +public class CookieTest { + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(Resource.class)); + + @TestHTTPResource + URI baseUri; + + @Test + void testCookie() { + Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class); + assertThat(client.sendCookie("bar")).isEqualTo("bar"); + } + + @Path("/") + @ApplicationScoped + public static class Resource { + @GET + public String returnCookieValue(@CookieParam("foo") String cookie) { + return cookie; + } + } + + public interface Client { + + @GET + String sendCookie(@CookieParam("foo") String cookie); + } + +} From 8507474da0b62b2bce35d1866c9e4cd7d6f6afc9 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Fri, 1 Oct 2021 14:40:37 +0300 Subject: [PATCH 2/2] Fix issue with headers and cookie handling of subresources in rest client reactive --- .../JaxrsClientReactiveProcessor.java | 8 +-- .../client/reactive/headers/CookieTest.java | 22 +++++++ .../client/reactive/headers/HeaderTest.java | 57 +++++++++++++++++++ 3 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/headers/HeaderTest.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 3bb3612ca6e17..ee0b30d5d974b 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 @@ -666,7 +666,7 @@ A more full example of generated client (with sub-resource) can is at the bottom } else if (param.parameterType == ParameterType.HEADER) { // headers are added at the invocation builder level MethodDescriptor handleHeaderDescriptor = MethodDescriptor.ofMethod(subName, - subMethod.getName() + "$$" + subMethodIndex + "$$handleHeader$$" + paramIdx, + subMethod.getName() + "$$" + subMethodIndex + "$$handleHeader$$param" + paramIdx, Invocation.Builder.class, Invocation.Builder.class, param.type); MethodCreator handleHeaderMethod = sub.getMethodCreator(handleHeaderDescriptor); @@ -681,7 +681,7 @@ A more full example of generated client (with sub-resource) can is at the bottom } else if (param.parameterType == ParameterType.COOKIE) { // cookies are added at the invocation builder level MethodDescriptor handleCookieDescriptor = MethodDescriptor.ofMethod(subName, - subMethod.getName() + "$$" + subMethodIndex + "$$handleCookie$$" + paramIdx, + subMethod.getName() + "$$" + subMethodIndex + "$$handleCookie$$param" + paramIdx, Invocation.Builder.class, Invocation.Builder.class, param.type); MethodCreator handleCookieMethod = sub.getMethodCreator(handleCookieDescriptor); @@ -756,7 +756,7 @@ A more full example of generated client (with sub-resource) can is at the bottom subMethod.getName() + "$$" + subMethodIndex + "$$handleHeader$$" + paramIdx, Invocation.Builder.class, Invocation.Builder.class, param.type); - MethodCreator handleHeaderMethod = c.getMethodCreator(handleHeaderDescriptor); + MethodCreator handleHeaderMethod = sub.getMethodCreator(handleHeaderDescriptor); AssignableResultHandle invocationBuilderRef = handleHeaderMethod .createVariable(Invocation.Builder.class); @@ -772,7 +772,7 @@ A more full example of generated client (with sub-resource) can is at the bottom subMethod.getName() + "$$" + subMethodIndex + "$$handleCookie$$" + paramIdx, Invocation.Builder.class, Invocation.Builder.class, param.type); - MethodCreator handleCookieMethod = c.getMethodCreator(handleHeaderDescriptor); + MethodCreator handleCookieMethod = sub.getMethodCreator(handleHeaderDescriptor); AssignableResultHandle invocationBuilderRef = handleCookieMethod .createVariable(Invocation.Builder.class); diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/headers/CookieTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/headers/CookieTest.java index 29f493e21b5bc..35fc2b9ae41d6 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/headers/CookieTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/headers/CookieTest.java @@ -32,6 +32,12 @@ void testCookie() { assertThat(client.sendCookie("bar")).isEqualTo("bar"); } + @Test + void testCookiesWithSubresource() { + Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class); + assertThat(client.cookieSub("bar", "bar2").send("bar3", "bar4")).isEqualTo("bar:bar2:bar3:bar4"); + } + @Path("/") @ApplicationScoped public static class Resource { @@ -39,12 +45,28 @@ public static class Resource { public String returnCookieValue(@CookieParam("foo") String cookie) { return cookie; } + + @Path("2") + @GET + public String returnCookieValue2(@CookieParam("foo") String cookie, @CookieParam("foo2") String cookie2, + @CookieParam("foo3") String cookie3, @CookieParam("foo4") String cookie4) { + return cookie + ":" + cookie2 + ":" + cookie3 + ":" + cookie4; + } } public interface Client { @GET String sendCookie(@CookieParam("foo") String cookie); + + @Path("2") + SubClient cookieSub(@CookieParam("foo") String cookie, @CookieParam("foo2") String cookie2); + } + + public interface SubClient { + + @GET + String send(@CookieParam("foo3") String cookie3, @CookieParam("foo4") String cookie4); } } diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/headers/HeaderTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/headers/HeaderTest.java new file mode 100644 index 0000000000000..6b715952d6757 --- /dev/null +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/headers/HeaderTest.java @@ -0,0 +1,57 @@ +package io.quarkus.rest.client.reactive.headers; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.net.URI; + +import javax.enterprise.context.ApplicationScoped; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; + +import org.eclipse.microprofile.rest.client.RestClientBuilder; +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; +import io.quarkus.test.common.http.TestHTTPResource; + +public class HeaderTest { + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(Resource.class)); + + @TestHTTPResource + URI baseUri; + + @Test + void testHeadersWithSubresource() { + Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class); + assertThat(client.cookieSub("bar", "bar2").send("bar3", "bar4")).isEqualTo("bar:bar2:bar3:bar4"); + } + + @Path("/") + @ApplicationScoped + public static class Resource { + @GET + public String returnHeaders(@HeaderParam("foo") String header, @HeaderParam("foo2") String header2, + @HeaderParam("foo3") String header3, @HeaderParam("foo4") String header4) { + return header + ":" + header2 + ":" + header3 + ":" + header4; + } + } + + public interface Client { + + @Path("/") + SubClient cookieSub(@HeaderParam("foo") String cookie, @HeaderParam("foo2") String cookie2); + } + + public interface SubClient { + + @GET + String send(@HeaderParam("foo3") String cookie3, @HeaderParam("foo4") String cookie4); + } + +}