diff --git a/extensions/resteasy-classic/rest-client-config/runtime/src/main/java/io/quarkus/restclient/config/RestClientConfig.java b/extensions/resteasy-classic/rest-client-config/runtime/src/main/java/io/quarkus/restclient/config/RestClientConfig.java index e9d1bf22249fe..80a0e6445a2a2 100644 --- a/extensions/resteasy-classic/rest-client-config/runtime/src/main/java/io/quarkus/restclient/config/RestClientConfig.java +++ b/extensions/resteasy-classic/rest-client-config/runtime/src/main/java/io/quarkus/restclient/config/RestClientConfig.java @@ -41,6 +41,7 @@ public class RestClientConfig { EMPTY.hostnameVerifier = Optional.empty(); EMPTY.connectionTTL = Optional.empty(); EMPTY.connectionPoolSize = Optional.empty(); + EMPTY.keepAliveEnabled = Optional.empty(); EMPTY.maxRedirects = Optional.empty(); EMPTY.headers = Collections.emptyMap(); EMPTY.shared = Optional.empty(); @@ -196,6 +197,12 @@ public class RestClientConfig { @ConfigItem public Optional connectionPoolSize; + /** + * If set to false disables the keep alive completely. + */ + @ConfigItem(defaultValue = "true") + public Optional keepAliveEnabled; + /** * The maximum number of redirection a request can follow. * @@ -263,6 +270,7 @@ public static RestClientConfig load(String configKey) { instance.hostnameVerifier = getConfigValue(configKey, "hostname-verifier", String.class); instance.connectionTTL = getConfigValue(configKey, "connection-ttl", Integer.class); instance.connectionPoolSize = getConfigValue(configKey, "connection-pool-size", Integer.class); + instance.keepAliveEnabled = getConfigValue(configKey, "keep-alive-enabled", Boolean.class); instance.maxRedirects = getConfigValue(configKey, "max-redirects", Integer.class); instance.headers = getConfigValues(configKey, "headers", String.class, String.class); instance.shared = getConfigValue(configKey, "shared", Boolean.class); @@ -297,6 +305,7 @@ public static RestClientConfig load(Class interfaceClass) { instance.hostnameVerifier = getConfigValue(interfaceClass, "hostname-verifier", String.class); instance.connectionTTL = getConfigValue(interfaceClass, "connection-ttl", Integer.class); instance.connectionPoolSize = getConfigValue(interfaceClass, "connection-pool-size", Integer.class); + instance.keepAliveEnabled = getConfigValue(interfaceClass, "keep-alive-enabled", Boolean.class); instance.maxRedirects = getConfigValue(interfaceClass, "max-redirects", Integer.class); instance.headers = getConfigValues(interfaceClass, "headers", String.class, String.class); instance.shared = getConfigValue(interfaceClass, "shared", Boolean.class); diff --git a/extensions/resteasy-classic/rest-client-config/runtime/src/main/java/io/quarkus/restclient/config/RestClientsConfig.java b/extensions/resteasy-classic/rest-client-config/runtime/src/main/java/io/quarkus/restclient/config/RestClientsConfig.java index 59e7646849ffd..c6e66c40876e3 100644 --- a/extensions/resteasy-classic/rest-client-config/runtime/src/main/java/io/quarkus/restclient/config/RestClientsConfig.java +++ b/extensions/resteasy-classic/rest-client-config/runtime/src/main/java/io/quarkus/restclient/config/RestClientsConfig.java @@ -168,6 +168,14 @@ public class RestClientsConfig { @ConfigItem public Optional connectionPoolSize; + /** + * If set to false disables the keep alive completely. + * + * Can be overwritten by client-specific settings. + */ + @ConfigItem(defaultValue = "true") + public Optional keepAliveEnabled; + /** * The maximum number of redirection a request can follow. * diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/ConfigurationTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/ConfigurationTest.java index 21b749444d7f6..ffc73d2756307 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/ConfigurationTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/ConfigurationTest.java @@ -87,6 +87,8 @@ private void verifyClientConfig(RestClientConfig clientConfig, boolean checkExtr assertThat(clientConfig.connectionTTL.get()).isEqualTo(30000); assertThat(clientConfig.connectionPoolSize).isPresent(); assertThat(clientConfig.connectionPoolSize.get()).isEqualTo(10); + assertThat(clientConfig.keepAliveEnabled).isPresent(); + assertThat(clientConfig.keepAliveEnabled.get()).isFalse(); assertThat(clientConfig.maxRedirects).isPresent(); assertThat(clientConfig.maxRedirects.get()).isEqualTo(5); } diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/GlobalConfigurationTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/GlobalConfigurationTest.java index 463c52f8949ec..77609b1a1e5d8 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/GlobalConfigurationTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/GlobalConfigurationTest.java @@ -68,6 +68,7 @@ void checkGlobalConfigValues() { .isEqualTo("io.quarkus.rest.client.reactive.HelloClientWithBaseUri$MyHostnameVerifier"); assertThat(configRoot.connectionTTL.get()).isEqualTo(20000); // value in ms, will be converted to seconds assertThat(configRoot.connectionPoolSize.get()).isEqualTo(2); + assertThat(configRoot.keepAliveEnabled.get()).isTrue(); assertThat(configRoot.maxRedirects.get()).isEqualTo(2); assertThat(configRoot.followRedirects.get()).isTrue(); assertThat(configRoot.providers.get()) diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/resources/configuration-test-application.properties b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/resources/configuration-test-application.properties index afd86c296770c..d240d98e8330d 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/resources/configuration-test-application.properties +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/resources/configuration-test-application.properties @@ -16,6 +16,7 @@ quarkus.rest-client."io.quarkus.rest.client.reactive.HelloClientWithBaseUri".que quarkus.rest-client."io.quarkus.rest.client.reactive.HelloClientWithBaseUri".hostname-verifier=io.quarkus.rest.client.reactive.HelloClientWithBaseUri$MyHostnameVerifier quarkus.rest-client."io.quarkus.rest.client.reactive.HelloClientWithBaseUri".connection-ttl=30000 quarkus.rest-client."io.quarkus.rest.client.reactive.HelloClientWithBaseUri".connection-pool-size=10 +quarkus.rest-client."io.quarkus.rest.client.reactive.HelloClientWithBaseUri".keep-alive-enabled=false quarkus.rest-client."io.quarkus.rest.client.reactive.HelloClientWithBaseUri".max-redirects=5 quarkus.rest-client."io.quarkus.rest.client.reactive.HelloClientWithBaseUri".headers.message=hi quarkus.rest-client."io.quarkus.rest.client.reactive.HelloClientWithBaseUri".headers.suffix=! @@ -32,6 +33,7 @@ quarkus.rest-client.client-prefix.query-param-style=COMMA_SEPARATED quarkus.rest-client.client-prefix.hostname-verifier=io.quarkus.rest.client.reactive.HelloClientWithBaseUri$MyHostnameVerifier quarkus.rest-client.client-prefix.connection-ttl=30000 quarkus.rest-client.client-prefix.connection-pool-size=10 +quarkus.rest-client.client-prefix.keep-alive-enabled=false quarkus.rest-client.client-prefix.max-redirects=5 quarkus.rest-client.client-prefix.headers.user-agent=MP REST Client quarkus.rest-client.client-prefix.headers.foo=bar diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/resources/global-configuration-test-application.properties b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/resources/global-configuration-test-application.properties index 68bfa98b8c643..473ed229a6259 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/resources/global-configuration-test-application.properties +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/resources/global-configuration-test-application.properties @@ -21,6 +21,7 @@ quarkus.rest-client.headers.foo=bar quarkus.rest-client.hostname-verifier=io.quarkus.rest.client.reactive.HelloClientWithBaseUri$MyHostnameVerifier quarkus.rest-client.connection-ttl=20000 quarkus.rest-client.connection-pool-size=2 +quarkus.rest-client.keep-alive-enabled=true quarkus.rest-client.max-redirects=2 quarkus.rest-client.follow-redirects=true quarkus.rest-client.providers=io.quarkus.rest.client.reactive.HelloClientWithBaseUri$MyResponseFilter 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 da933186bb855..c74d840829b97 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 @@ -98,6 +98,12 @@ private void configureCustomProperties(RestClientBuilder builder) { builder.property(QuarkusRestClientProperties.CONNECTION_TTL, connectionTTLSeconds); } + Optional keepAliveEnabled = oneOf(clientConfigByClassName().keepAliveEnabled, + clientConfigByConfigKey().keepAliveEnabled, configRoot.keepAliveEnabled); + if (keepAliveEnabled.isPresent()) { + builder.property(QuarkusRestClientProperties.KEEP_ALIVE_ENABLED, keepAliveEnabled.get()); + } + Map headers = clientConfigByClassName().headers; if (headers == null || headers.isEmpty()) { headers = clientConfigByConfigKey().headers; 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 2b913fc0870f0..058e6043593b5 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 @@ -105,6 +105,7 @@ public void testClientSpecificConfigs() { Mockito.verify(restClientBuilderMock).hostnameVerifier(Mockito.any(MyHostnameVerifier1.class)); Mockito.verify(restClientBuilderMock).property(QuarkusRestClientProperties.CONNECTION_TTL, 10); // value converted to seconds Mockito.verify(restClientBuilderMock).property(QuarkusRestClientProperties.CONNECTION_POOL_SIZE, 103); + Mockito.verify(restClientBuilderMock).property(QuarkusRestClientProperties.KEEP_ALIVE_ENABLED, false); Mockito.verify(restClientBuilderMock).property(QuarkusRestClientProperties.MAX_REDIRECTS, 104); Mockito.verify(restClientBuilderMock).followRedirects(true); Mockito.verify(restClientBuilderMock).register(MyResponseFilter1.class); @@ -147,6 +148,7 @@ public void testGlobalConfigs() { Mockito.verify(restClientBuilderMock).hostnameVerifier(Mockito.any(MyHostnameVerifier2.class)); Mockito.verify(restClientBuilderMock).property(QuarkusRestClientProperties.CONNECTION_TTL, 20); Mockito.verify(restClientBuilderMock).property(QuarkusRestClientProperties.CONNECTION_POOL_SIZE, 203); + Mockito.verify(restClientBuilderMock).property(QuarkusRestClientProperties.KEEP_ALIVE_ENABLED, true); Mockito.verify(restClientBuilderMock).property(QuarkusRestClientProperties.MAX_REDIRECTS, 204); Mockito.verify(restClientBuilderMock).followRedirects(true); Mockito.verify(restClientBuilderMock).register(MyResponseFilter2.class); @@ -176,6 +178,7 @@ private static RestClientsConfig createSampleConfigRoot() { .of("io.quarkus.rest.client.reactive.runtime.RestClientCDIDelegateBuilderTest$MyHostnameVerifier2"); configRoot.connectionTTL = Optional.of(20000); // value in ms, will be converted to seconds configRoot.connectionPoolSize = Optional.of(203); + configRoot.keepAliveEnabled = Optional.of(true); configRoot.maxRedirects = Optional.of(204); configRoot.followRedirects = Optional.of(true); configRoot.providers = Optional @@ -214,6 +217,7 @@ private static RestClientConfig createSampleClientConfig() { .of("io.quarkus.rest.client.reactive.runtime.RestClientCDIDelegateBuilderTest$MyHostnameVerifier1"); clientConfig.connectionTTL = Optional.of(10000); // value in milliseconds, will be converted to seconds clientConfig.connectionPoolSize = Optional.of(103); + clientConfig.keepAliveEnabled = Optional.of(false); clientConfig.maxRedirects = Optional.of(104); clientConfig.followRedirects = Optional.of(true); clientConfig.providers = Optional diff --git a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/api/QuarkusRestClientProperties.java b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/api/QuarkusRestClientProperties.java index cdd7524a5913a..b07920d8789c6 100644 --- a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/api/QuarkusRestClientProperties.java +++ b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/api/QuarkusRestClientProperties.java @@ -36,6 +36,11 @@ public class QuarkusRestClientProperties { */ public static final String CONNECTION_POOL_SIZE = "io.quarkus.rest.client.connection-pool-size"; + /** + * A boolean value used to determine whether the keep alive is enabled or disabled. + */ + public static final String KEEP_ALIVE_ENABLED = "io.quarkus.rest.client.keep-alive-enabled"; + public static final String STATIC_HEADERS = "io.quarkus.rest.client.static-headers"; /** diff --git a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientImpl.java b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientImpl.java index 2d341b6ea35d0..d867b6848bf97 100644 --- a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientImpl.java +++ b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientImpl.java @@ -3,6 +3,7 @@ import static org.jboss.resteasy.reactive.client.api.QuarkusRestClientProperties.CONNECTION_POOL_SIZE; import static org.jboss.resteasy.reactive.client.api.QuarkusRestClientProperties.CONNECTION_TTL; import static org.jboss.resteasy.reactive.client.api.QuarkusRestClientProperties.CONNECT_TIMEOUT; +import static org.jboss.resteasy.reactive.client.api.QuarkusRestClientProperties.KEEP_ALIVE_ENABLED; import static org.jboss.resteasy.reactive.client.api.QuarkusRestClientProperties.MAX_HEADER_SIZE; import static org.jboss.resteasy.reactive.client.api.QuarkusRestClientProperties.MAX_INITIAL_LINE_LENGTH; import static org.jboss.resteasy.reactive.client.api.QuarkusRestClientProperties.MAX_REDIRECTS; @@ -156,6 +157,16 @@ public Vertx get() { } options.setMaxPoolSize((int) connectionPoolSize); + Object keepAliveEnabled = configuration.getProperty(KEEP_ALIVE_ENABLED); + if (keepAliveEnabled != null) { + Boolean enabled = (Boolean) keepAliveEnabled; + options.setKeepAlive(enabled); + + if (!enabled) { + log.debug("keep alive disabled"); + } + } + if (loggingScope == LoggingScope.ALL) { options.setLogActivity(true); }