From e3e44887e34db643d43a6178dd6dff4abc28d38d Mon Sep 17 00:00:00 2001 From: Jose Date: Tue, 25 Apr 2023 07:41:51 +0200 Subject: [PATCH] Provide new API to programmatically create REST Client reactive The new API includes these additional options: - verifyHost - trustStore by truststore and password (it was requested in #31891) - proxyUser - proxyPassword - nonProxyHosts Fix https://github.com/quarkusio/quarkus/issues/32856 --- .../main/asciidoc/rest-client-reactive.adoc | 46 +++- ...entObjectMapperForClientAndServerTest.java | 6 +- .../reactive/jackson/test/MultiSseTest.java | 8 +- .../reactive/jaxb/test/SimpleJaxbTest.java | 6 +- .../reactive/ArrayPairsQueryParamTest.java | 3 +- .../ClientAndServerSharingResponseTest.java | 4 +- .../reactive/ConnectionPoolSizeTest.java | 9 +- ...sViaProgrammaticallyClientCreatedTest.java | 5 +- .../rest/client/reactive/EmptyPostTest.java | 3 +- .../rest/client/reactive/FormTest.java | 3 +- .../rest/client/reactive/InvalidHostTest.java | 3 +- .../rest/client/reactive/InvalidURITest.java | 3 +- .../rest/client/reactive/MapParamsTest.java | 5 +- .../rest/client/reactive/MultiNdjsonTest.java | 3 +- .../client/reactive/NoPathInTheAppTest.java | 3 +- .../timeout/BuilderReadTimeoutTest.java | 8 +- .../reactive/QuarkusRestClientBuilder.java | 232 ++++++++++++++++++ .../runtime/QuarkusRestClientBuilderImpl.java | 186 ++++++++++++++ .../ReactiveRestClientBuilderFactory.java | 3 +- .../runtime/RestClientCDIDelegateBuilder.java | 38 ++- .../RestClientCDIDelegateBuilderTest.java | 4 +- .../client/main/ClientCallingResource.java | 18 +- .../ClientWithCustomObjectMapperTest.java | 6 +- 23 files changed, 521 insertions(+), 84 deletions(-) create mode 100644 extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/QuarkusRestClientBuilder.java create mode 100644 extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/QuarkusRestClientBuilderImpl.java diff --git a/docs/src/main/asciidoc/rest-client-reactive.adoc b/docs/src/main/asciidoc/rest-client-reactive.adoc index f4ae3aef37ec6..fc5d15b90b510 100644 --- a/docs/src/main/asciidoc/rest-client-reactive.adoc +++ b/docs/src/main/asciidoc/rest-client-reactive.adoc @@ -351,11 +351,11 @@ There are two interesting parts in this listing: <1> the client stub is injected with the `@RestClient` annotation instead of the usual CDI `@Inject` -== Programmatic client creation with RestClientBuilder +== Programmatic client creation with QuarkusRestClientBuilder Instead of annotating the client with `@RegisterRestClient`, and injecting a client with `@RestClient`, you can also create REST Client programmatically. -You do that with `RestClientBuilder`. +You do that with the `QuarkusRestClientBuilder`. With this approach the client interface could look as follows: @@ -381,7 +381,7 @@ And the service as follows: ---- package org.acme.rest.client; -import org.eclipse.microprofile.rest.client.RestClientBuilder; +import io.quarkus.rest.client.reactive.QuarkusRestClientBuilder; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; @@ -394,7 +394,7 @@ public class ExtensionsResource { private final ExtensionsService extensionsService; public ExtensionsResource() { - extensionsService = RestClientBuilder.newBuilder() + extensionsService = QuarkusRestClientBuilder.newBuilder() .baseUri(URI.create("https://stage.code.quarkus.io/api")) .build(ExtensionsService.class); } @@ -407,6 +407,38 @@ public class ExtensionsResource { } ---- +[TIP] +==== +The `QuarkusRestClientBuilder` interface is a Quarkus-specific API to programmatically create clients with additional configuration options. Otherwise, you can also use the `RestClientBuilder` interface from the Microprofile API: + +[source,java] +---- +package org.acme.rest.client; + +import org.eclipse.microprofile.rest.client.RestClientBuilder; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import java.net.URI; +import java.util.Set; + +@Path("/extension") +public class ExtensionsResource { + + private final ExtensionsService extensionsService; + + public ExtensionsResource() { + extensionsService = RestClientBuilder.newBuilder() + .baseUri(URI.create("https://stage.code.quarkus.io/api")) + .build(ExtensionsService.class); + } + + // ... +} +---- + +==== + == Use Custom HTTP Options The REST Client Reactive internally uses https://vertx.io/docs/apidocs/io/vertx/core/http/HttpClient.html[the Vert.x HTTP Client] to make the network connections. The REST Client Reactive extensions allows configuring some settings via properties, for example: @@ -450,7 +482,7 @@ Another approach is to provide the custom HTTP Client options when creating the ---- package org.acme.rest.client; -import org.eclipse.microprofile.rest.client.RestClientBuilder; +import io.quarkus.rest.client.reactive.QuarkusRestClientBuilder; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; @@ -465,7 +497,7 @@ public class ExtensionsResource { private final ExtensionsService extensionsService; public ExtensionsResource() { - extensionsService = RestClientBuilder.newBuilder() + extensionsService = QuarkusRestClientBuilder.newBuilder() .baseUri(URI.create("https://stage.code.quarkus.io/api")) .register(CustomHttpClientOptions.class) <1> .build(ExtensionsService.class); @@ -562,7 +594,7 @@ public class ExtensionsResource { private final ExtensionsService extensionsService; public ExtensionsResource() { - extensionsService = RestClientBuilder.newBuilder() + extensionsService = QuarkusRestClientBuilder.newBuilder() .baseUri(URI.create("https://stage.code.quarkus.io/api")) .register(AlwaysRedirectHandler.class) <1> .build(ExtensionsService.class); diff --git a/extensions/resteasy-reactive/rest-client-reactive-jackson/deployment/src/test/java/io/quarkus/rest/client/reactive/jackson/test/DifferentObjectMapperForClientAndServerTest.java b/extensions/resteasy-reactive/rest-client-reactive-jackson/deployment/src/test/java/io/quarkus/rest/client/reactive/jackson/test/DifferentObjectMapperForClientAndServerTest.java index fb887c900e599..8652317dc3605 100644 --- a/extensions/resteasy-reactive/rest-client-reactive-jackson/deployment/src/test/java/io/quarkus/rest/client/reactive/jackson/test/DifferentObjectMapperForClientAndServerTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive-jackson/deployment/src/test/java/io/quarkus/rest/client/reactive/jackson/test/DifferentObjectMapperForClientAndServerTest.java @@ -19,7 +19,6 @@ import jakarta.ws.rs.ext.ContextResolver; import org.apache.http.HttpStatus; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.eclipse.microprofile.rest.client.annotation.RegisterProvider; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -30,6 +29,7 @@ import com.fasterxml.jackson.databind.SerializationFeature; import io.quarkus.jackson.ObjectMapperCustomizer; +import io.quarkus.rest.client.reactive.QuarkusRestClientBuilder; import io.quarkus.test.QuarkusUnitTest; import io.quarkus.test.common.http.TestHTTPResource; @@ -45,10 +45,10 @@ public class DifferentObjectMapperForClientAndServerTest { @BeforeEach public void setup() { - clientUnwrappingRootElement = RestClientBuilder.newBuilder().baseUri(uri) + clientUnwrappingRootElement = QuarkusRestClientBuilder.newBuilder().baseUri(uri) .build(MyClientUnwrappingRootElement.class); - clientNotUnwrappingRootElement = RestClientBuilder.newBuilder().baseUri(uri) + clientNotUnwrappingRootElement = QuarkusRestClientBuilder.newBuilder().baseUri(uri) .build(MyClientNotUnwrappingRootElement.class); } diff --git a/extensions/resteasy-reactive/rest-client-reactive-jackson/deployment/src/test/java/io/quarkus/rest/client/reactive/jackson/test/MultiSseTest.java b/extensions/resteasy-reactive/rest-client-reactive-jackson/deployment/src/test/java/io/quarkus/rest/client/reactive/jackson/test/MultiSseTest.java index df9f9b662d31b..aa715e04fb948 100644 --- a/extensions/resteasy-reactive/rest-client-reactive-jackson/deployment/src/test/java/io/quarkus/rest/client/reactive/jackson/test/MultiSseTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive-jackson/deployment/src/test/java/io/quarkus/rest/client/reactive/jackson/test/MultiSseTest.java @@ -15,7 +15,6 @@ import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; import org.jboss.resteasy.reactive.RestStreamElementType; import org.jboss.resteasy.reactive.server.jackson.JacksonBasicMessageBodyReader; @@ -24,6 +23,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import io.quarkus.rest.client.reactive.QuarkusRestClientBuilder; import io.quarkus.test.QuarkusUnitTest; import io.quarkus.test.common.http.TestHTTPResource; import io.smallrye.mutiny.Multi; @@ -101,7 +101,7 @@ void shouldSendPayloadAndConsumeAsParametrizedType() { @Test void shouldRestStreamElementTypeOverwriteProducesAtClassLevel() { var resultList = new CopyOnWriteArrayList<>(); - RestClientBuilder.newBuilder().baseUri(uri) + QuarkusRestClientBuilder.newBuilder().baseUri(uri) .build(SeeWithRestStreamElementTypeClient.class) .getJson() .subscribe() @@ -113,7 +113,9 @@ void shouldRestStreamElementTypeOverwriteProducesAtClassLevel() { } private SseClient createClient() { - return RestClientBuilder.newBuilder().baseUri(uri).register(new JacksonBasicMessageBodyReader(new ObjectMapper())) + return QuarkusRestClientBuilder.newBuilder() + .baseUri(uri) + .register(new JacksonBasicMessageBodyReader(new ObjectMapper())) .build(SseClient.class); } diff --git a/extensions/resteasy-reactive/rest-client-reactive-jaxb/deployment/src/test/java/io/quarkus/rest/client/reactive/jaxb/test/SimpleJaxbTest.java b/extensions/resteasy-reactive/rest-client-reactive-jaxb/deployment/src/test/java/io/quarkus/rest/client/reactive/jaxb/test/SimpleJaxbTest.java index 601bbb8558083..4efea63bf3fe6 100644 --- a/extensions/resteasy-reactive/rest-client-reactive-jaxb/deployment/src/test/java/io/quarkus/rest/client/reactive/jaxb/test/SimpleJaxbTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive-jaxb/deployment/src/test/java/io/quarkus/rest/client/reactive/jaxb/test/SimpleJaxbTest.java @@ -11,10 +11,10 @@ import jakarta.ws.rs.core.MediaType; import jakarta.xml.bind.annotation.XmlRootElement; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import io.quarkus.rest.client.reactive.QuarkusRestClientBuilder; import io.quarkus.test.QuarkusUnitTest; import io.quarkus.test.common.http.TestHTTPResource; @@ -28,14 +28,14 @@ public class SimpleJaxbTest { @Test void shouldConsumeXMLEntity() { - var dto = RestClientBuilder.newBuilder().baseUri(uri).build(XmlClient.class) + var dto = QuarkusRestClientBuilder.newBuilder().baseUri(uri).build(XmlClient.class) .dto(); assertThat(dto).isEqualTo(new Dto("foo", "bar")); } @Test void shouldConsumePlainXMLEntity() { - var dto = RestClientBuilder.newBuilder().baseUri(uri).build(XmlClient.class) + var dto = QuarkusRestClientBuilder.newBuilder().baseUri(uri).build(XmlClient.class) .plain(); assertThat(dto).isEqualTo(new Dto("foo", "bar")); } diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/ArrayPairsQueryParamTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/ArrayPairsQueryParamTest.java index 7771e5c0a3932..e1d2d3fdc3f64 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/ArrayPairsQueryParamTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/ArrayPairsQueryParamTest.java @@ -16,7 +16,6 @@ import jakarta.ws.rs.Path; import jakarta.ws.rs.QueryParam; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.eclipse.microprofile.rest.client.ext.QueryParamStyle; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -87,7 +86,7 @@ private void setupServer() throws InterruptedException, ExecutionException { } private Client createClient() { - return RestClientBuilder.newBuilder() + return QuarkusRestClientBuilder.newBuilder() .queryParamStyle(QueryParamStyle.ARRAY_PAIRS) .baseUri(URI.create("http://localhost:8082")) .build(Client.class); diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/ClientAndServerSharingResponseTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/ClientAndServerSharingResponseTest.java index c154d7e6e2dd7..a250d8c370d25 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/ClientAndServerSharingResponseTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/ClientAndServerSharingResponseTest.java @@ -19,7 +19,6 @@ import jakarta.ws.rs.core.Response; import org.eclipse.microprofile.config.inject.ConfigProperty; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -65,11 +64,10 @@ public Endpoint(ObjectMapper mapper, @ConfigProperty(name = "quarkus.http.test-port", defaultValue = "8081") Integer testPort) throws MalformedURLException { this.mapper = mapper; - this.headersService = RestClientBuilder.newBuilder() + this.headersService = QuarkusRestClientBuilder.newBuilder() .baseUrl(new URL(String.format("http://localhost:%d", testPort))) .readTimeout(1, TimeUnit.SECONDS) .build(HeadersService.class); - ; } @POST diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/ConnectionPoolSizeTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/ConnectionPoolSizeTest.java index d2042f8782ada..2a1c23e065989 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/ConnectionPoolSizeTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/ConnectionPoolSizeTest.java @@ -12,7 +12,6 @@ import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.jboss.resteasy.reactive.client.api.QuarkusRestClientProperties; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; @@ -37,7 +36,7 @@ public class ConnectionPoolSizeTest { @Test void shouldPerform20CallsWithoutQueuing() throws InterruptedException { - Client client = RestClientBuilder.newBuilder().baseUri(uri) + Client client = QuarkusRestClientBuilder.newBuilder().baseUri(uri) .build(Client.class); CountDownLatch latch = executeCalls(client, 20); @@ -50,7 +49,7 @@ void shouldPerform20CallsWithoutQueuing() throws InterruptedException { @Test @Timeout(5) void shouldPerform21CallsWithQueuing() throws InterruptedException { - Client client = RestClientBuilder.newBuilder().baseUri(uri) + Client client = QuarkusRestClientBuilder.newBuilder().baseUri(uri) .build(Client.class); long start = System.currentTimeMillis(); @@ -63,7 +62,7 @@ void shouldPerform21CallsWithQueuing() throws InterruptedException { @Test @Timeout(5) void shouldPerform5CallsWithoutQueueingOnQueue6() throws InterruptedException { - Client client = RestClientBuilder.newBuilder().baseUri(uri) + Client client = QuarkusRestClientBuilder.newBuilder().baseUri(uri) .property(QuarkusRestClientProperties.CONNECTION_POOL_SIZE, 6) .build(Client.class); @@ -77,7 +76,7 @@ void shouldPerform5CallsWithoutQueueingOnQueue6() throws InterruptedException { @Test @Timeout(5) void shouldPerform5CallsWithQueueingOnQueue4() throws InterruptedException { - Client client = RestClientBuilder.newBuilder().baseUri(uri) + Client client = QuarkusRestClientBuilder.newBuilder().baseUri(uri) .property(QuarkusRestClientProperties.CONNECTION_POOL_SIZE, 4) .build(Client.class); diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/CustomHttpOptionsViaProgrammaticallyClientCreatedTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/CustomHttpOptionsViaProgrammaticallyClientCreatedTest.java index e95793ef8915e..f5d36c89e09fa 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/CustomHttpOptionsViaProgrammaticallyClientCreatedTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/CustomHttpOptionsViaProgrammaticallyClientCreatedTest.java @@ -10,7 +10,6 @@ import jakarta.ws.rs.Path; import jakarta.ws.rs.ext.ContextResolver; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.jboss.resteasy.reactive.RestResponse; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -33,12 +32,12 @@ public class CustomHttpOptionsViaProgrammaticallyClientCreatedTest { @Test void shouldUseCustomHttpOptions() { // First verify the standard configuration - assertThat(RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class).get()) + assertThat(QuarkusRestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class).get()) .isEqualTo(EXPECTED_VALUE); // Now, it should fail if we use a custom http client options with a very limited max header size: - Client client = RestClientBuilder.newBuilder().baseUri(baseUri) + Client client = QuarkusRestClientBuilder.newBuilder().baseUri(baseUri) .register(CustomHttpClientOptionsWithLimit.class) .build(Client.class); assertThatThrownBy(() -> client.get()).hasMessageContaining("HTTP header is larger than 1 bytes."); diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/EmptyPostTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/EmptyPostTest.java index 72d3b069f470c..197602e8ec99d 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/EmptyPostTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/EmptyPostTest.java @@ -9,7 +9,6 @@ import jakarta.ws.rs.Path; import org.eclipse.microprofile.config.ConfigProvider; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -29,7 +28,7 @@ void shouldWork() { } private Client clientWithUri(String uri) { - return RestClientBuilder.newBuilder().baseUri(URI.create(uri)).build(Client.class); + return QuarkusRestClientBuilder.newBuilder().baseUri(URI.create(uri)).build(Client.class); } @Path("/foo") diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/FormTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/FormTest.java index 4c7426ff74168..0692a32a3f1d8 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/FormTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/FormTest.java @@ -12,7 +12,6 @@ import jakarta.ws.rs.core.Form; import jakarta.ws.rs.core.MediaType; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -29,7 +28,7 @@ public class FormTest { @Test void shouldPassUrlEncodedAsForm() { - Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class); + Client client = QuarkusRestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class); assertThat(client.echo(new Form().param("name", "World"))).isEqualTo("Hello, World!"); } diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/InvalidHostTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/InvalidHostTest.java index bb5550b2c5e8e..2280f60b33352 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/InvalidHostTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/InvalidHostTest.java @@ -8,7 +8,6 @@ import jakarta.ws.rs.core.Response; import org.assertj.core.api.Assertions; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -22,7 +21,7 @@ public class InvalidHostTest { @Test void shouldThrowDummyException() { - Client client = RestClientBuilder.newBuilder().baseUri(URI.create("http://localhost2:1234/")) + Client client = QuarkusRestClientBuilder.newBuilder().baseUri(URI.create("http://localhost2:1234/")) .register(DummyExceptionMapper.class).build(Client.class); Assertions.assertThatThrownBy(client::get).isInstanceOf(DummyException.class); diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/InvalidURITest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/InvalidURITest.java index 5abe15c964d57..63e1a520ba589 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/InvalidURITest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/InvalidURITest.java @@ -9,7 +9,6 @@ import org.assertj.core.api.Assertions; import org.eclipse.microprofile.config.ConfigProvider; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -57,7 +56,7 @@ void shouldWork() { } private Client clientWithUri(String uri) { - return RestClientBuilder.newBuilder().baseUri(URI.create(uri)).build(Client.class); + return QuarkusRestClientBuilder.newBuilder().baseUri(URI.create(uri)).build(Client.class); } @Path("/foo") diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/MapParamsTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/MapParamsTest.java index 58ce21d52f25c..840ddf52fa94a 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/MapParamsTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/MapParamsTest.java @@ -14,7 +14,6 @@ import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.UriInfo; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.jboss.resteasy.reactive.RestQuery; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -33,14 +32,14 @@ public class MapParamsTest { @Test void testQueryParamsWithRegularMap() { - Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class); + Client client = QuarkusRestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class); String response = client.regularMap(Map.of("foo", "bar", "k", "v")); assertThat(response).contains("foo=bar").contains("k=v"); } @Test void testQueryParamsWithMultiMap() { - Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class); + Client client = QuarkusRestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class); MultivaluedMap map = new MultivaluedHashMap<>(); map.putSingle("first", 1); map.put("second", List.of(2, 4, 6)); diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/MultiNdjsonTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/MultiNdjsonTest.java index 55e116ad49c4f..10f85b0505755 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/MultiNdjsonTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/MultiNdjsonTest.java @@ -17,7 +17,6 @@ import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.jboss.resteasy.reactive.RestStreamElementType; import org.jboss.resteasy.reactive.common.util.RestMediaType; import org.junit.jupiter.api.Test; @@ -110,7 +109,7 @@ void shouldReadNdjsonFromSingleMessage() throws InterruptedException { } private Client createClient(URI uri) { - return RestClientBuilder.newBuilder().baseUri(uri).register(new TestJacksonBasicMessageBodyReader()) + return QuarkusRestClientBuilder.newBuilder().baseUri(uri).register(new TestJacksonBasicMessageBodyReader()) .build(Client.class); } diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/NoPathInTheAppTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/NoPathInTheAppTest.java index 4e0790b5aff0a..697a0afa6efcc 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/NoPathInTheAppTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/NoPathInTheAppTest.java @@ -5,7 +5,6 @@ import java.net.URI; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -40,7 +39,7 @@ public void shutdown() { @Test void shouldGet() { - PlaylistService client = RestClientBuilder.newBuilder().baseUri(URI.create("http://localhost:8181/hello")) + PlaylistService client = QuarkusRestClientBuilder.newBuilder().baseUri(URI.create("http://localhost:8181/hello")) .build(PlaylistService.class); assertThat(client.get()).isEqualTo("hello, world!"); } diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/timeout/BuilderReadTimeoutTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/timeout/BuilderReadTimeoutTest.java index e870bcf7b64ea..d8429e7334243 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/timeout/BuilderReadTimeoutTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/timeout/BuilderReadTimeoutTest.java @@ -15,10 +15,10 @@ import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import io.quarkus.rest.client.reactive.QuarkusRestClientBuilder; import io.quarkus.test.QuarkusUnitTest; import io.quarkus.test.common.http.TestHTTPResource; @@ -34,7 +34,7 @@ public class BuilderReadTimeoutTest { @Test void shouldTimeoutIfReadTimeoutSetShort() { - Client client = RestClientBuilder.newBuilder() + Client client = QuarkusRestClientBuilder.newBuilder() .baseUri(uri) .readTimeout(1, TimeUnit.SECONDS) .build(Client.class); @@ -45,7 +45,7 @@ void shouldTimeoutIfReadTimeoutSetShort() { @Test void shouldNotTimeoutOnFastResponse() { - Client client = RestClientBuilder.newBuilder() + Client client = QuarkusRestClientBuilder.newBuilder() .baseUri(uri) .readTimeout(1, TimeUnit.SECONDS) .build(Client.class); @@ -55,7 +55,7 @@ void shouldNotTimeoutOnFastResponse() { @Test void shouldNotTimeoutOnDefaultTimeout() { - Client client = RestClientBuilder.newBuilder() + Client client = QuarkusRestClientBuilder.newBuilder() .baseUri(uri) .build(Client.class); diff --git a/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/QuarkusRestClientBuilder.java b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/QuarkusRestClientBuilder.java new file mode 100644 index 0000000000000..8b8ed80329f44 --- /dev/null +++ b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/QuarkusRestClientBuilder.java @@ -0,0 +1,232 @@ +package io.quarkus.rest.client.reactive; + +import java.net.URI; +import java.net.URL; +import java.security.KeyStore; +import java.util.ServiceLoader; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; + +import jakarta.ws.rs.core.Configurable; + +import org.eclipse.microprofile.rest.client.RestClientBuilder; +import org.eclipse.microprofile.rest.client.RestClientDefinitionException; +import org.eclipse.microprofile.rest.client.ext.QueryParamStyle; +import org.eclipse.microprofile.rest.client.spi.RestClientBuilderListener; + +import io.quarkus.rest.client.reactive.runtime.QuarkusRestClientBuilderImpl; +import io.quarkus.rest.client.reactive.runtime.RestClientBuilderImpl; + +/** + * This is the main entry point for creating a Type Safe Quarkus Rest Client. + *

+ * Invoking {@link #newBuilder()} is intended to always create a new instance, not use a cached version. + *

+ *

+ * The QuarkusRestClientBuilder is based on {@link RestClientBuilder} class but Quarkus specific. + *

+ */ +public interface QuarkusRestClientBuilder extends Configurable { + + static QuarkusRestClientBuilder newBuilder() { + RestClientBuilderImpl proxy = new RestClientBuilderImpl(); + for (RestClientBuilderListener listener : ServiceLoader.load(RestClientBuilderListener.class)) { + listener.onNewBuilder(proxy); + } + + return new QuarkusRestClientBuilderImpl(proxy); + } + + /** + * Specifies the base URL to be used when making requests. Assuming that the interface has a + * @Path("/api") at the interface level and a url is given with + * http://my-service:8080/service then all REST calls will be invoked with a url of + * http://my-service:8080/service/api in addition to any @Path annotations included on the + * method. + * + * Subsequent calls to this method will replace the previously specified baseUri/baseUrl. + * + * @param url the base Url for the service. + * @return the current builder with the baseUrl set. + */ + QuarkusRestClientBuilder baseUrl(URL url); + + /** + * Specifies the base URI to be used when making requests. Assuming that the interface has a + * @Path("/api") at the interface level and a uri is given with + * http://my-service:8080/service then all REST calls will be invoked with a uri of + * http://my-service:8080/service/api in addition to any @Path annotations included on the + * method. + * + * Subsequent calls to this method will replace the previously specified baseUri/baseUrl. + * + * @param uri the base URI for the service. + * @return the current builder with the baseUri set + * @throws IllegalArgumentException if the passed in URI is invalid + */ + QuarkusRestClientBuilder baseUri(URI uri); + + /** + * Set the connect timeout. + *

+ * Like JAX-RS's jakarta.ws.rs.client.ClientBuilder's connectTimeout method, specifying a + * timeout of 0 represents infinity, and negative values are not allowed. + *

+ *

+ * If the client instance is injected via CDI and the + * "fully.qualified.InterfaceName/mp-rest/connectTimeout" property is set via MicroProfile + * Config, that property's value will override, the value specified to this method. + *

+ * + * @param timeout the maximum time to wait. + * @param unit the time unit of the timeout argument. + * @return the current builder with the connect timeout set. + * @throws IllegalArgumentException if the value of timeout is negative. + */ + QuarkusRestClientBuilder connectTimeout(long timeout, TimeUnit unit); + + /** + * Set the read timeout. + *

+ * Like JAX-RS's jakarta.ws.rs.client.ClientBuilder's readTimeout method, specifying a + * timeout of 0 represents infinity, and negative values are not allowed. + *

+ *

+ * Also like the JAX-RS Client API, if the read timeout is reached, the client interface method will throw a + * jakarta.ws.rs.ProcessingException. + *

+ *

+ * If the client instance is injected via CDI and the + * "fully.qualified.InterfaceName/mp-rest/readTimeout" property is set via MicroProfile Config, + * that property's value will override, the value specified to this method. + *

+ * + * @param timeout the maximum time to wait. + * @param unit the time unit of the timeout argument. + * @return the current builder with the connect timeout set. + * @throws IllegalArgumentException if the value of timeout is negative. + */ + QuarkusRestClientBuilder readTimeout(long timeout, TimeUnit unit); + + /** + * Specifies the SSL context to use when creating secured transport connections to server endpoints from web targets + * created by the client instance that is using this SSL context. + * + * @param sslContext the ssl context + * @return the current builder with ssl context set + * @throws NullPointerException if the sslContext parameter is null. + */ + QuarkusRestClientBuilder sslContext(SSLContext sslContext); + + /** + * Set whether hostname verification is enabled. + * + * @param verifyHost whether the hostname verification is enabled. + * @return the current builder with the hostname verification set. + */ + QuarkusRestClientBuilder verifyHost(boolean verifyHost); + + /** + * Set the client-side trust store. + * + * @param trustStore key store + * @return the current builder with the trust store set + * @throws NullPointerException if the trustStore parameter is null. + */ + QuarkusRestClientBuilder trustStore(KeyStore trustStore); + + /** + * Set the client-side trust store. + * + * @param trustStore key store + * @param trustStorePassword the password for the specified trustStore + * @return the current builder with the trust store set + * @throws NullPointerException if the trustStore parameter is null. + */ + QuarkusRestClientBuilder trustStore(KeyStore trustStore, String trustStorePassword); + + /** + * Set the client-side key store. + * + * @param keyStore key store + * @param keystorePassword the password for the specified keyStore + * @return the current builder with the key store set + * @throws NullPointerException if the keyStore parameter is null. + */ + QuarkusRestClientBuilder keyStore(KeyStore keyStore, String keystorePassword); + + /** + * Set the hostname verifier to verify the endpoint's hostname + * + * @param hostnameVerifier the hostname verifier + * @return the current builder with hostname verifier set + * @throws NullPointerException if the hostnameVerifier parameter is null. + */ + QuarkusRestClientBuilder hostnameVerifier(HostnameVerifier hostnameVerifier); + + /** + * Specifies whether client built by this builder should follow HTTP redirect responses (30x) or not. + * + * @param follow true if the client should follow HTTP redirects, false if not. + * @return the current builder with the followRedirect property set. + */ + QuarkusRestClientBuilder followRedirects(boolean follow); + + /** + * Specifies the HTTP proxy hostname/IP address and port to use for requests from client instances. + * + * @param proxyHost hostname or IP address of proxy server - must be non-null + * @param proxyPort port of proxy server + * @throws IllegalArgumentException if the proxyHost is null or the proxyPort is invalid + * @return the current builder with the proxy host set + */ + QuarkusRestClientBuilder proxyAddress(String proxyHost, int proxyPort); + + /** + * Specifies the proxy username. + * + * @param proxyUser the proxy username. + * @return the current builder + */ + QuarkusRestClientBuilder proxyUser(String proxyUser); + + /** + * Specifies the proxy password. + * + * @param proxyPassword the proxy password. + * @return the current builder + */ + QuarkusRestClientBuilder proxyPassword(String proxyPassword); + + /** + * Specifies the hosts to access without proxy. + * + * @param nonProxyHosts the hosts to access without proxy. + * @return the current builder + */ + QuarkusRestClientBuilder nonProxyHosts(String nonProxyHosts); + + /** + * Specifies the URI formatting style to use when multiple query parameter values are passed to the client. + * + * @param style the URI formatting style to use for multiple query parameter values + * @return the current builder with the style of query params set + */ + QuarkusRestClientBuilder queryParamStyle(QueryParamStyle style); + + /** + * Based on the configured QuarkusRestClientBuilder, creates a new instance of the given REST interface to invoke API calls + * against. + * + * @param clazz the interface that defines REST API methods for use + * @param the type of the interface + * @return a new instance of an implementation of this REST interface that + * @throws IllegalStateException + * if not all pre-requisites are satisfied for the builder, this exception may get thrown. For instance, + * if the base URI/URL has not been set. + * @throws RestClientDefinitionException if the passed-in interface class is invalid. + */ + T build(Class clazz) throws IllegalStateException, RestClientDefinitionException; +} diff --git a/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/QuarkusRestClientBuilderImpl.java b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/QuarkusRestClientBuilderImpl.java new file mode 100644 index 0000000000000..0a6a18756dfa0 --- /dev/null +++ b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/QuarkusRestClientBuilderImpl.java @@ -0,0 +1,186 @@ +package io.quarkus.rest.client.reactive.runtime; + +import java.net.URI; +import java.net.URL; +import java.security.KeyStore; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; + +import jakarta.ws.rs.core.Configuration; + +import org.eclipse.microprofile.rest.client.RestClientDefinitionException; +import org.eclipse.microprofile.rest.client.ext.QueryParamStyle; + +import io.quarkus.rest.client.reactive.QuarkusRestClientBuilder; + +public class QuarkusRestClientBuilderImpl implements QuarkusRestClientBuilder { + + private final RestClientBuilderImpl proxy; + + public QuarkusRestClientBuilderImpl(RestClientBuilderImpl proxy) { + this.proxy = proxy; + } + + @Override + public QuarkusRestClientBuilder baseUrl(URL url) { + proxy.baseUrl(url); + return this; + } + + @Override + public QuarkusRestClientBuilder baseUri(URI uri) { + proxy.baseUri(uri); + return this; + } + + @Override + public QuarkusRestClientBuilder connectTimeout(long timeout, TimeUnit unit) { + proxy.connectTimeout(timeout, unit); + return this; + } + + @Override + public QuarkusRestClientBuilder readTimeout(long timeout, TimeUnit unit) { + proxy.readTimeout(timeout, unit); + return this; + } + + @Override + public QuarkusRestClientBuilder sslContext(SSLContext sslContext) { + proxy.sslContext(sslContext); + return this; + } + + @Override + public QuarkusRestClientBuilder verifyHost(boolean verifyHost) { + proxy.verifyHost(verifyHost); + return this; + } + + @Override + public QuarkusRestClientBuilder trustStore(KeyStore trustStore) { + proxy.trustStore(trustStore); + return this; + } + + @Override + public QuarkusRestClientBuilder trustStore(KeyStore trustStore, String trustStorePassword) { + proxy.trustStore(trustStore, trustStorePassword); + return this; + } + + @Override + public QuarkusRestClientBuilder keyStore(KeyStore keyStore, String keystorePassword) { + proxy.keyStore(keyStore, keystorePassword); + return this; + } + + @Override + public QuarkusRestClientBuilder hostnameVerifier(HostnameVerifier hostnameVerifier) { + proxy.hostnameVerifier(hostnameVerifier); + return this; + } + + @Override + public QuarkusRestClientBuilder followRedirects(boolean follow) { + proxy.followRedirects(follow); + return this; + } + + @Override + public QuarkusRestClientBuilder proxyAddress(String proxyHost, int proxyPort) { + proxy.proxyAddress(proxyHost, proxyPort); + return this; + } + + @Override + public QuarkusRestClientBuilder proxyPassword(String proxyPassword) { + proxy.proxyPassword(proxyPassword); + return this; + } + + @Override + public QuarkusRestClientBuilder proxyUser(String proxyUser) { + proxy.proxyUser(proxyUser); + return this; + } + + @Override + public QuarkusRestClientBuilder nonProxyHosts(String nonProxyHosts) { + proxy.nonProxyHosts(nonProxyHosts); + return this; + } + + @Override + public QuarkusRestClientBuilder queryParamStyle(QueryParamStyle style) { + proxy.queryParamStyle(style); + return this; + } + + @Override + public Configuration getConfiguration() { + return proxy.getConfiguration(); + } + + @Override + public QuarkusRestClientBuilder property(String name, Object value) { + proxy.property(name, value); + return this; + } + + @Override + public QuarkusRestClientBuilder register(Class componentClass) { + proxy.register(componentClass); + return this; + } + + @Override + public QuarkusRestClientBuilder register(Class componentClass, int priority) { + proxy.register(componentClass, priority); + return this; + } + + @Override + public QuarkusRestClientBuilder register(Class componentClass, Class... contracts) { + proxy.register(componentClass, contracts); + return null; + } + + @Override + public QuarkusRestClientBuilder register(Class componentClass, Map, Integer> contracts) { + proxy.register(componentClass, contracts); + return this; + } + + @Override + public QuarkusRestClientBuilder register(Object component) { + proxy.register(component); + return this; + } + + @Override + public QuarkusRestClientBuilder register(Object component, int priority) { + proxy.register(component, priority); + return this; + } + + @Override + public QuarkusRestClientBuilder register(Object component, Class... contracts) { + proxy.register(component, contracts); + return this; + } + + @Override + public QuarkusRestClientBuilder register(Object component, Map, Integer> contracts) { + proxy.register(component, contracts); + return this; + } + + @Override + public T build(Class clazz) throws IllegalStateException, RestClientDefinitionException { + return proxy.build(clazz); + } +} diff --git a/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/ReactiveRestClientBuilderFactory.java b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/ReactiveRestClientBuilderFactory.java index d055bda239e18..5a0a1c1481dc5 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/ReactiveRestClientBuilderFactory.java +++ b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/ReactiveRestClientBuilderFactory.java @@ -18,9 +18,10 @@ public RestClientBuilder newBuilder(Class proxyType, RestClientsConfig restCl } RestClientBuilderImpl restClientBuilder = new RestClientBuilderImpl(); + QuarkusRestClientBuilderImpl quarkusRestClientBuilder = new QuarkusRestClientBuilderImpl(restClientBuilder); RestClientCDIDelegateBuilder restClientBase = new RestClientCDIDelegateBuilder<>(proxyType, baseUri, configKey, restClientsConfigRoot); - restClientBase.configureBuilder(restClientBuilder); + restClientBase.configureBuilder(quarkusRestClientBuilder); return restClientBuilder; } diff --git a/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilder.java b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilder.java index 88d27766b8874..2173915ef0054 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilder.java +++ b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilder.java @@ -19,11 +19,11 @@ import javax.net.ssl.HostnameVerifier; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.eclipse.microprofile.rest.client.ext.QueryParamStyle; import org.jboss.resteasy.reactive.client.api.QuarkusRestClientProperties; import io.netty.handler.codec.http.multipart.HttpPostRequestEncoder; +import io.quarkus.rest.client.reactive.QuarkusRestClientBuilder; import io.quarkus.restclient.config.RestClientConfig; import io.quarkus.restclient.config.RestClientsConfig; @@ -55,16 +55,12 @@ private RestClientCDIDelegateBuilder(Class jaxrsInterface, String baseUriFrom } private T build() { - RestClientBuilder builder = RestClientBuilder.newBuilder(); - if (!(builder instanceof RestClientBuilderImpl)) { - throw new IllegalStateException("Expected RestClientBuilder to be an instance of " - + RestClientBuilderImpl.class.getName() + ", got " + builder.getClass().getName()); - } - configureBuilder((RestClientBuilderImpl) builder); + QuarkusRestClientBuilder builder = QuarkusRestClientBuilder.newBuilder(); + configureBuilder(builder); return builder.build(jaxrsInterface); } - void configureBuilder(RestClientBuilderImpl builder) { + void configureBuilder(QuarkusRestClientBuilder builder) { configureBaseUrl(builder); configureTimeouts(builder); configureProviders(builder); @@ -76,7 +72,7 @@ void configureBuilder(RestClientBuilderImpl builder) { configureCustomProperties(builder); } - private void configureCustomProperties(RestClientBuilder builder) { + private void configureCustomProperties(QuarkusRestClientBuilder builder) { Optional encoder = configRoot.multipartPostEncoderMode; if (encoder != null && encoder.isPresent()) { HttpPostRequestEncoder.EncoderMode mode = HttpPostRequestEncoder.EncoderMode @@ -135,7 +131,7 @@ private void configureCustomProperties(RestClientBuilder builder) { } } - private void configureProxy(RestClientBuilderImpl builder) { + private void configureProxy(QuarkusRestClientBuilder builder) { Optional maybeProxy = oneOf(clientConfigByClassName().proxyAddress, clientConfigByConfigKey().proxyAddress, configRoot.proxyAddress); if (maybeProxy.isEmpty()) { @@ -158,7 +154,7 @@ private void configureProxy(RestClientBuilderImpl builder) { } } - private void configureQueryParamStyle(RestClientBuilder builder) { + private void configureQueryParamStyle(QuarkusRestClientBuilder builder) { Optional maybeQueryParamStyle = oneOf(clientConfigByClassName().queryParamStyle, clientConfigByConfigKey().queryParamStyle, configRoot.queryParamStyle); if (maybeQueryParamStyle.isPresent()) { @@ -167,7 +163,7 @@ private void configureQueryParamStyle(RestClientBuilder builder) { } } - private void configureRedirects(RestClientBuilder builder) { + private void configureRedirects(QuarkusRestClientBuilder builder) { Optional maxRedirects = oneOf(clientConfigByClassName().maxRedirects, clientConfigByConfigKey().maxRedirects, configRoot.maxRedirects); if (maxRedirects.isPresent()) { @@ -181,7 +177,7 @@ private void configureRedirects(RestClientBuilder builder) { } } - private void configureShared(RestClientBuilder builder) { + private void configureShared(QuarkusRestClientBuilder builder) { Optional shared = oneOf(clientConfigByClassName().shared, clientConfigByConfigKey().shared); if (shared.isPresent()) { @@ -198,7 +194,7 @@ private void configureShared(RestClientBuilder builder) { } } - private void configureSsl(RestClientBuilderImpl builder) { + private void configureSsl(QuarkusRestClientBuilder builder) { Optional maybeTrustStore = oneOf(clientConfigByClassName().trustStore, clientConfigByConfigKey().trustStore, configRoot.trustStore); @@ -222,7 +218,7 @@ private void configureSsl(RestClientBuilderImpl builder) { .ifPresent(builder::verifyHost); } - private void registerHostnameVerifier(String verifier, RestClientBuilder builder) { + private void registerHostnameVerifier(String verifier, QuarkusRestClientBuilder builder) { try { Class verifierClass = Thread.currentThread().getContextClassLoader().loadClass(verifier); builder.hostnameVerifier((HostnameVerifier) verifierClass.getDeclaredConstructor().newInstance()); @@ -242,7 +238,7 @@ private void registerHostnameVerifier(String verifier, RestClientBuilder builder } } - private void registerKeyStore(String keyStorePath, RestClientBuilder builder) { + private void registerKeyStore(String keyStorePath, QuarkusRestClientBuilder builder) { Optional keyStorePassword = oneOf(clientConfigByClassName().keyStorePassword, clientConfigByConfigKey().keyStorePassword, configRoot.keyStorePassword); Optional keyStoreType = oneOf(clientConfigByClassName().keyStoreType, @@ -268,7 +264,7 @@ private void registerKeyStore(String keyStorePath, RestClientBuilder builder) { } } - private void registerTrustStore(String trustStorePath, RestClientBuilderImpl builder) { + private void registerTrustStore(String trustStorePath, QuarkusRestClientBuilder builder) { Optional maybeTrustStorePassword = oneOf(clientConfigByClassName().trustStorePassword, clientConfigByConfigKey().trustStorePassword, configRoot.trustStorePassword); Optional maybeTrustStoreType = oneOf(clientConfigByClassName().trustStoreType, @@ -319,7 +315,7 @@ private InputStream locateStream(String path) throws FileNotFoundException { } } - private void configureProviders(RestClientBuilder builder) { + private void configureProviders(QuarkusRestClientBuilder builder) { Optional maybeProviders = oneOf(clientConfigByClassName().providers, clientConfigByConfigKey().providers, configRoot.providers); if (maybeProviders.isPresent()) { @@ -327,7 +323,7 @@ private void configureProviders(RestClientBuilder builder) { } } - private void registerProviders(RestClientBuilder builder, String providersAsString) { + private void registerProviders(QuarkusRestClientBuilder builder, String providersAsString) { for (String s : providersAsString.split(",")) { builder.register(providerClassForName(s.trim())); } @@ -341,7 +337,7 @@ private Class providerClassForName(String name) { } } - private void configureTimeouts(RestClientBuilder builder) { + private void configureTimeouts(QuarkusRestClientBuilder builder) { Long connectTimeout = oneOf(clientConfigByClassName().connectTimeout, clientConfigByConfigKey().connectTimeout).orElse(this.configRoot.connectTimeout); if (connectTimeout != null) { @@ -355,7 +351,7 @@ private void configureTimeouts(RestClientBuilder builder) { } } - private void configureBaseUrl(RestClientBuilder builder) { + private void configureBaseUrl(QuarkusRestClientBuilder builder) { Optional propertyOptional = oneOf(clientConfigByClassName().uri, clientConfigByConfigKey().uri); diff --git a/extensions/resteasy-reactive/rest-client-reactive/runtime/src/test/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilderTest.java b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/test/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilderTest.java index 058e6043593b5..b5a42ff851837 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/runtime/src/test/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilderTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/test/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilderTest.java @@ -79,7 +79,7 @@ public void testClientSpecificConfigs() { // when - RestClientBuilderImpl restClientBuilderMock = Mockito.mock(RestClientBuilderImpl.class); + QuarkusRestClientBuilderImpl restClientBuilderMock = Mockito.mock(QuarkusRestClientBuilderImpl.class); new RestClientCDIDelegateBuilder<>(TestClient.class, "http://localhost:8080", "test-client", @@ -123,7 +123,7 @@ public void testGlobalConfigs() { // when - RestClientBuilderImpl restClientBuilderMock = Mockito.mock(RestClientBuilderImpl.class); + QuarkusRestClientBuilderImpl restClientBuilderMock = Mockito.mock(QuarkusRestClientBuilderImpl.class); new RestClientCDIDelegateBuilder<>(TestClient.class, "http://localhost:8080", "test-client", 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 3aa318a5a515d..6c4f6498d007b 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 @@ -11,7 +11,6 @@ import jakarta.inject.Inject; import jakarta.ws.rs.core.MediaType; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.eclipse.microprofile.rest.client.inject.RestClient; import org.jboss.resteasy.reactive.RestResponse; @@ -23,6 +22,7 @@ import io.quarkus.it.rest.client.main.MyResponseExceptionMapper.MyException; import io.quarkus.it.rest.client.main.selfsigned.ExternalSelfSignedClient; import io.quarkus.it.rest.client.main.wronghost.WrongHostClient; +import io.quarkus.rest.client.reactive.QuarkusRestClientBuilder; import io.smallrye.mutiny.Uni; import io.vertx.core.Future; import io.vertx.core.json.Json; @@ -62,7 +62,7 @@ void init(@Observes Router router) { router.post("/call-client-with-exception-mapper").blockingHandler(rc -> { String url = rc.getBody().toString(); - ClientWithExceptionMapper client = RestClientBuilder.newBuilder().baseUri(URI.create(url)) + ClientWithExceptionMapper client = QuarkusRestClientBuilder.newBuilder().baseUri(URI.create(url)) .register(MyResponseExceptionMapper.class) .build(ClientWithExceptionMapper.class); callGet(rc, client); @@ -78,7 +78,7 @@ void init(@Observes Router router) { router.route("/call-client").blockingHandler(rc -> { String url = rc.getBody().toString(); - AppleClient client = RestClientBuilder.newBuilder().baseUri(URI.create(url)) + AppleClient client = QuarkusRestClientBuilder.newBuilder().baseUri(URI.create(url)) .build(AppleClient.class); Uni apple1 = Uni.createFrom().item(client.swapApple(new Apple("lobo"))); Uni apple2 = Uni.createFrom().completionStage(client.completionSwapApple(new Apple("lobo2"))); @@ -107,7 +107,7 @@ void init(@Observes Router router) { router.route("/call-client-retry").blockingHandler(rc -> { String url = rc.getBody().toString(); - AppleClient client = RestClientBuilder.newBuilder().baseUri(URI.create(url + "/does-not-exist")) + AppleClient client = QuarkusRestClientBuilder.newBuilder().baseUri(URI.create(url + "/does-not-exist")) .build(AppleClient.class); AtomicInteger count = new AtomicInteger(0); client.uniSwapApple(new Apple("lobo")).onFailure().retry().until(t -> count.incrementAndGet() <= 3) @@ -123,7 +123,7 @@ void init(@Observes Router router) { router.route("/call-hello-client").blockingHandler(rc -> { String url = rc.getBody().toString(); - HelloClient client = RestClientBuilder.newBuilder().baseUri(URI.create(url)) + HelloClient client = QuarkusRestClientBuilder.newBuilder().baseUri(URI.create(url)) .build(HelloClient.class); String greeting = client.greeting("John", 2); rc.response().end(greeting); @@ -131,7 +131,7 @@ void init(@Observes Router router) { router.route("/call-hello-client-trace").blockingHandler(rc -> { String url = rc.getBody().toString(); - HelloClient client = RestClientBuilder.newBuilder().baseUri(URI.create(url)) + HelloClient client = QuarkusRestClientBuilder.newBuilder().baseUri(URI.create(url)) .build(HelloClient.class); String greeting = client.greeting("Mary", 3); rc.response().end(greeting); @@ -139,7 +139,7 @@ void init(@Observes Router router) { router.route("/call-helloFromMessage-client").blockingHandler(rc -> { String url = rc.getBody().toString(); - HelloClient client = RestClientBuilder.newBuilder().baseUri(URI.create(url)) + HelloClient client = QuarkusRestClientBuilder.newBuilder().baseUri(URI.create(url)) .build(HelloClient.class); String greeting = client.fromMessage(new HelloClient.Message("Hello world")); rc.response().end(greeting); @@ -150,7 +150,7 @@ void init(@Observes Router router) { router.route("/call-params-client-with-param-first").blockingHandler(rc -> { String url = rc.getBody().toString(); - ParamClient client = RestClientBuilder.newBuilder().baseUri(URI.create(url)) + ParamClient client = QuarkusRestClientBuilder.newBuilder().baseUri(URI.create(url)) .build(ParamClient.class); String result = client.getParam(Param.FIRST); rc.response().end(result); @@ -158,7 +158,7 @@ void init(@Observes Router router) { router.route("/rest-response").blockingHandler(rc -> { String url = rc.getBody().toString(); - RestResponseClient client = RestClientBuilder.newBuilder().baseUri(URI.create(url)) + RestResponseClient client = QuarkusRestClientBuilder.newBuilder().baseUri(URI.create(url)) .property("microprofile.rest.client.disable.default.mapper", true) .build(RestResponseClient.class); RestResponse restResponse = client.response(); diff --git a/integration-tests/rest-client-reactive/src/test/java/io/quarkus/it/rest/client/ClientWithCustomObjectMapperTest.java b/integration-tests/rest-client-reactive/src/test/java/io/quarkus/it/rest/client/ClientWithCustomObjectMapperTest.java index f925704718c3b..ffa0788537139 100644 --- a/integration-tests/rest-client-reactive/src/test/java/io/quarkus/it/rest/client/ClientWithCustomObjectMapperTest.java +++ b/integration-tests/rest-client-reactive/src/test/java/io/quarkus/it/rest/client/ClientWithCustomObjectMapperTest.java @@ -19,7 +19,6 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.ext.ContextResolver; -import org.eclipse.microprofile.rest.client.RestClientBuilder; import org.jboss.resteasy.reactive.ClientWebApplicationException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -31,6 +30,7 @@ import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.client.WireMock; +import io.quarkus.rest.client.reactive.QuarkusRestClientBuilder; import io.quarkus.test.junit.QuarkusTest; import io.smallrye.mutiny.Uni; @@ -48,12 +48,12 @@ public void setUp() throws MalformedURLException { wireMockServer = new WireMockServer(options().port(20001)); wireMockServer.start(); - clientAllowsUnknown = RestClientBuilder.newBuilder() + clientAllowsUnknown = QuarkusRestClientBuilder.newBuilder() .baseUrl(new URL(wireMockServer.baseUrl())) .register(ClientObjectMapperUnknown.class) .build(MyClient.class); - clientDisallowsUnknown = RestClientBuilder.newBuilder() + clientDisallowsUnknown = QuarkusRestClientBuilder.newBuilder() .baseUrl(new URL(wireMockServer.baseUrl())) .register(ClientObjectMapperNoUnknown.class) .build(MyClient.class);