diff --git a/extensions/rest-client/deployment/src/main/java/io/quarkus/restclient/deployment/RestClientProcessor.java b/extensions/rest-client/deployment/src/main/java/io/quarkus/restclient/deployment/RestClientProcessor.java index 0312f8ca1372c..9d979968517f3 100644 --- a/extensions/rest-client/deployment/src/main/java/io/quarkus/restclient/deployment/RestClientProcessor.java +++ b/extensions/rest-client/deployment/src/main/java/io/quarkus/restclient/deployment/RestClientProcessor.java @@ -21,6 +21,7 @@ import org.eclipse.microprofile.config.Config; import org.eclipse.microprofile.config.ConfigProvider; import org.eclipse.microprofile.rest.client.annotation.ClientHeaderParam; +import org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders; import org.eclipse.microprofile.rest.client.annotation.RegisterProvider; import org.eclipse.microprofile.rest.client.annotation.RegisterProviders; import org.eclipse.microprofile.rest.client.ext.DefaultClientHeadersFactoryImpl; @@ -89,6 +90,7 @@ class RestClientProcessor { private static final DotName REGISTER_PROVIDER = DotName.createSimple(RegisterProvider.class.getName()); private static final DotName REGISTER_PROVIDERS = DotName.createSimple(RegisterProviders.class.getName()); + private static final DotName REGISTER_CLIENT_HEADERS = DotName.createSimple(RegisterClientHeaders.class.getName()); private static final DotName CLIENT_REQUEST_FILTER = DotName.createSimple(ClientRequestFilter.class.getName()); private static final DotName CLIENT_RESPONSE_FILTER = DotName.createSimple(ClientResponseFilter.class.getName()); @@ -421,6 +423,12 @@ void registerProviders(BuildProducer reflectiveClass, .produce(new ReflectiveClassBuildItem(false, false, annotationInstance.value().asClass().toString())); } + // Register @RegisterClientHeaders for reflection + for (AnnotationInstance annotationInstance : index.getAnnotations(REGISTER_CLIENT_HEADERS)) { + reflectiveClass + .produce(new ReflectiveClassBuildItem(false, false, annotationInstance.value().asClass().toString())); + } + // now retain all un-annotated implementations of ClientRequestFilter and ClientResponseFilter // in case they are programmatically registered by applications for (ClassInfo info : index.getAllKnownImplementors(CLIENT_REQUEST_FILTER)) { @@ -438,6 +446,7 @@ AdditionalBeanBuildItem registerProviderBeans(CombinedIndexBuildItem combinedInd for (AnnotationInstance annotation : index.getAnnotations(REGISTER_PROVIDERS)) { allInstances.addAll(Arrays.asList(annotation.value().asNestedArray())); } + allInstances.addAll(index.getAnnotations(REGISTER_CLIENT_HEADERS)); AdditionalBeanBuildItem.Builder builder = AdditionalBeanBuildItem.builder().setUnremovable(); for (AnnotationInstance annotationInstance : allInstances) { // Make sure all providers not annotated with @Provider but used in @RegisterProvider are registered as beans diff --git a/extensions/rest-client/deployment/src/test/java/io/quarkus/restclient/registerclientheaders/EchoClient.java b/extensions/rest-client/deployment/src/test/java/io/quarkus/restclient/registerclientheaders/EchoClient.java new file mode 100644 index 0000000000000..37ace0002b57f --- /dev/null +++ b/extensions/rest-client/deployment/src/test/java/io/quarkus/restclient/registerclientheaders/EchoClient.java @@ -0,0 +1,23 @@ +package io.quarkus.restclient.registerclientheaders; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders; +import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; + +@Path("/echo") +@RegisterRestClient +@RegisterClientHeaders(MyHeadersFactory.class) +public interface EchoClient { + + @GET + @Produces(MediaType.TEXT_PLAIN) + @Consumes(MediaType.TEXT_PLAIN) + String echo(@QueryParam("message") String message); + +} diff --git a/extensions/rest-client/deployment/src/test/java/io/quarkus/restclient/registerclientheaders/EchoResource.java b/extensions/rest-client/deployment/src/test/java/io/quarkus/restclient/registerclientheaders/EchoResource.java new file mode 100644 index 0000000000000..ec7aa4476789a --- /dev/null +++ b/extensions/rest-client/deployment/src/test/java/io/quarkus/restclient/registerclientheaders/EchoResource.java @@ -0,0 +1,26 @@ +package io.quarkus.restclient.registerclientheaders; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.eclipse.microprofile.rest.client.inject.RestClient; + +@Path("/echo") +public class EchoResource { + + @RestClient + EchoClient client; + + @GET + @Produces(MediaType.TEXT_PLAIN) + @Consumes(MediaType.TEXT_PLAIN) + public String echo(@QueryParam("message") String message, @HeaderParam("foo") String foo) { + return message + foo; + } + +} diff --git a/extensions/rest-client/deployment/src/test/java/io/quarkus/restclient/registerclientheaders/MyHeadersFactory.java b/extensions/rest-client/deployment/src/test/java/io/quarkus/restclient/registerclientheaders/MyHeadersFactory.java new file mode 100644 index 0000000000000..08fce91855ae6 --- /dev/null +++ b/extensions/rest-client/deployment/src/test/java/io/quarkus/restclient/registerclientheaders/MyHeadersFactory.java @@ -0,0 +1,26 @@ +package io.quarkus.restclient.registerclientheaders; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import javax.enterprise.inject.spi.BeanManager; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.ws.rs.core.MultivaluedMap; + +import org.eclipse.microprofile.rest.client.ext.ClientHeadersFactory; + +@Singleton +public class MyHeadersFactory implements ClientHeadersFactory { + + @Inject + BeanManager beanManager; + + @Override + public MultivaluedMap update(MultivaluedMap incomingHeaders, + MultivaluedMap clientOutgoingHeaders) { + assertNotNull(beanManager); + incomingHeaders.add("foo", "bar"); + return incomingHeaders; + } + +} diff --git a/extensions/rest-client/deployment/src/test/java/io/quarkus/restclient/registerclientheaders/RegisterClientHeadersTest.java b/extensions/rest-client/deployment/src/test/java/io/quarkus/restclient/registerclientheaders/RegisterClientHeadersTest.java new file mode 100644 index 0000000000000..0d219666c8ef1 --- /dev/null +++ b/extensions/rest-client/deployment/src/test/java/io/quarkus/restclient/registerclientheaders/RegisterClientHeadersTest.java @@ -0,0 +1,32 @@ +package io.quarkus.restclient.registerclientheaders; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.eclipse.microprofile.rest.client.inject.RestClient; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.StringAsset; +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 RegisterClientHeadersTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class) + .addClasses(EchoResource.class, EchoClient.class, MyHeadersFactory.class) + .addAsResource( + new StringAsset("io.quarkus.restclient.registerclientheaders.EchoClient/mp-rest/url=${test.url}"), + "application.properties")); + + @RestClient + EchoClient client; + + @Test + public void testProvider() { + assertEquals("ping:bar", client.echo("ping:")); + } + +}