Skip to content

Commit 70f8efc

Browse files
committed
Add support for the Proxy connect timeout in Quarkus REST Client
Closes: quarkusio#48976
1 parent 9d63713 commit 70f8efc

File tree

7 files changed

+72
-4
lines changed

7 files changed

+72
-4
lines changed

extensions/resteasy-classic/rest-client-config/runtime/src/main/java/io/quarkus/restclient/config/RestClientsConfig.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.quarkus.restclient.config;
22

33
import java.io.InputStream;
4+
import java.time.Duration;
45
import java.util.Map;
56
import java.util.Optional;
67
import java.util.OptionalInt;
@@ -89,6 +90,16 @@ public interface RestClientsConfig {
8990
*/
9091
Optional<String> nonProxyHosts();
9192

93+
/**
94+
* Proxy connection timeout
95+
* <p>
96+
* Can be overwritten by client-specific settings.
97+
* <p>
98+
* This property is not applicable to the RESTEasy Client.
99+
*/
100+
@ConfigDocDefault("10s")
101+
Optional<Duration> proxyConnectTimeout();
102+
92103
/**
93104
* A timeout in milliseconds that REST clients should wait to connect to the remote endpoint.
94105
* <p>
@@ -484,6 +495,14 @@ default Optional<String> uriReload() {
484495
*/
485496
Optional<String> nonProxyHosts();
486497

498+
/**
499+
* Proxy connection timeout
500+
* <p>
501+
* This property is not applicable to the RESTEasy Client.
502+
*/
503+
@ConfigDocDefault("10s")
504+
Optional<Duration> proxyConnectTimeout();
505+
487506
/**
488507
* An enumerated type string value with possible values of "MULTI_PAIRS" (default), "COMMA_SEPARATED",
489508
* or "ARRAY_PAIRS" that specifies the format in which multiple values for the same query parameter is used.

extensions/resteasy-reactive/rest-client/runtime/src/main/java/io/quarkus/rest/client/reactive/QuarkusRestClientBuilder.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.net.URI;
44
import java.net.URL;
55
import java.security.KeyStore;
6+
import java.time.Duration;
67
import java.util.ServiceLoader;
78
import java.util.concurrent.TimeUnit;
89

@@ -226,6 +227,14 @@ static QuarkusRestClientBuilder newBuilder() {
226227
*/
227228
QuarkusRestClientBuilder nonProxyHosts(String nonProxyHosts);
228229

230+
/**
231+
* Specifies the connect timeout for the proxy connection
232+
*
233+
* @param connectTimeout proxy connect timeout.
234+
* @return the current builder
235+
*/
236+
QuarkusRestClientBuilder proxyConnectTimeout(Duration connectTimeout);
237+
229238
/**
230239
* Specifies the URI formatting style to use when multiple query parameter values are passed to the client.
231240
*

extensions/resteasy-reactive/rest-client/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/QuarkusRestClientBuilderImpl.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.net.URI;
44
import java.net.URL;
55
import java.security.KeyStore;
6+
import java.time.Duration;
67
import java.util.Map;
78
import java.util.concurrent.TimeUnit;
89

@@ -127,6 +128,12 @@ public QuarkusRestClientBuilder nonProxyHosts(String nonProxyHosts) {
127128
return this;
128129
}
129130

131+
@Override
132+
public QuarkusRestClientBuilder proxyConnectTimeout(Duration connectTimeout) {
133+
delegate.proxyConnectTimeout(connectTimeout);
134+
return this;
135+
}
136+
130137
@Override
131138
public QuarkusRestClientBuilder multipartPostEncoderMode(String mode) {
132139
delegate.multipartPostEncoderMode(mode);

extensions/resteasy-reactive/rest-client/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientBuilderImpl.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.net.URISyntaxException;
88
import java.net.URL;
99
import java.security.KeyStore;
10+
import java.time.Duration;
1011
import java.util.ArrayList;
1112
import java.util.Comparator;
1213
import java.util.List;
@@ -81,6 +82,7 @@ public class RestClientBuilderImpl implements RestClientBuilder {
8182
private String proxyUser;
8283
private String proxyPassword;
8384
private String nonProxyHosts;
85+
private Duration proxyConnectTimeout;
8486

8587
private ClientLogger clientLogger;
8688
private LoggingScope loggingScope;
@@ -237,6 +239,11 @@ public RestClientBuilderImpl nonProxyHosts(String nonProxyHosts) {
237239
return this;
238240
}
239241

242+
public RestClientBuilderImpl proxyConnectTimeout(Duration proxyConnectTimeout) {
243+
this.proxyConnectTimeout = proxyConnectTimeout;
244+
return this;
245+
}
246+
240247
public RestClientBuilderImpl multipartPostEncoderMode(String mode) {
241248
this.multipartPostEncoderMode = mode;
242249
return this;
@@ -568,11 +575,16 @@ public <T> T build(Class<T> aClass) throws IllegalStateException, RestClientDefi
568575
}
569576

570577
if (proxyHost != null) {
571-
configureProxy(proxyHost, proxyPort, proxyUser, proxyPassword, nonProxyHosts);
578+
configureProxy(proxyHost, proxyPort, proxyUser, proxyPassword, nonProxyHosts, proxyConnectTimeout);
572579
} else if (restClients.proxyAddress().isPresent()) {
573580
HostAndPort globalProxy = ProxyAddressUtil.parseAddress(restClients.proxyAddress().get());
574-
configureProxy(globalProxy.host, globalProxy.port, restClients.proxyUser().orElse(null),
575-
restClients.proxyPassword().orElse(null), restClients.nonProxyHosts().orElse(null));
581+
configureProxy(
582+
globalProxy.host,
583+
globalProxy.port,
584+
restClients.proxyUser().orElse(null),
585+
restClients.proxyPassword().orElse(null),
586+
restClients.nonProxyHosts().orElse(null),
587+
restClients.proxyConnectTimeout().orElse(null));
576588
}
577589

578590
if (!clientBuilder.getConfiguration().hasProperty(QuarkusRestClientProperties.MULTIPART_ENCODER_MODE)) {
@@ -604,7 +616,7 @@ public <T> T build(Class<T> aClass) throws IllegalStateException, RestClientDefi
604616
}
605617

606618
private void configureProxy(String proxyHost, Integer proxyPort, String proxyUser, String proxyPassword,
607-
String nonProxyHosts) {
619+
String nonProxyHosts, Duration proxyConnectTimeout) {
608620
if (proxyHost != null) {
609621
clientBuilder.proxy(proxyHost, proxyPort);
610622
if (proxyUser != null && proxyPassword != null) {
@@ -615,6 +627,10 @@ private void configureProxy(String proxyHost, Integer proxyPort, String proxyUse
615627
if (nonProxyHosts != null) {
616628
clientBuilder.nonProxyHosts(nonProxyHosts);
617629
}
630+
631+
if (proxyConnectTimeout != null) {
632+
clientBuilder.proxyConnectTimeout(proxyConnectTimeout);
633+
}
618634
}
619635
}
620636

extensions/resteasy-reactive/rest-client/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilder.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ private void configureProxy(QuarkusRestClientBuilder builder) {
194194
oneOf(restClientConfig.proxyUser(), configRoot.proxyUser()).ifPresent(builder::proxyUser);
195195
oneOf(restClientConfig.proxyPassword(), configRoot.proxyPassword()).ifPresent(builder::proxyPassword);
196196
oneOf(restClientConfig.nonProxyHosts(), configRoot.nonProxyHosts()).ifPresent(builder::nonProxyHosts);
197+
oneOf(restClientConfig.proxyConnectTimeout(), configRoot.proxyConnectTimeout())
198+
.ifPresent(builder::proxyConnectTimeout);
197199
}
198200
}
199201

extensions/resteasy-reactive/rest-client/runtime/src/test/java/io/quarkus/rest/client/reactive/runtime/RestClientCDIDelegateBuilderTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.security.KeyStoreException;
2626
import java.security.NoSuchAlgorithmException;
2727
import java.security.cert.CertificateException;
28+
import java.time.Duration;
2829
import java.util.HashMap;
2930
import java.util.List;
3031
import java.util.Map;
@@ -134,6 +135,7 @@ public List<RegisteredRestClient> getRestClients() {
134135
verify(restClientBuilderMock).proxyUser("proxyUser1");
135136
verify(restClientBuilderMock).proxyPassword("proxyPassword1");
136137
verify(restClientBuilderMock).nonProxyHosts("nonProxyHosts1");
138+
verify(restClientBuilderMock).proxyConnectTimeout(Duration.ofSeconds(20));
137139
verify(restClientBuilderMock).connectTimeout(100, MILLISECONDS);
138140
verify(restClientBuilderMock).readTimeout(101, MILLISECONDS);
139141
verify(restClientBuilderMock).userAgent("agent1");
@@ -188,6 +190,7 @@ public List<RegisteredRestClient> getRestClients() {
188190
verify(restClientBuilderMock).proxyUser("proxyUser2");
189191
verify(restClientBuilderMock).proxyPassword("proxyPassword2");
190192
verify(restClientBuilderMock).nonProxyHosts("nonProxyHosts2");
193+
verify(restClientBuilderMock).proxyConnectTimeout(Duration.ofSeconds(30));
191194
verify(restClientBuilderMock).connectTimeout(200, MILLISECONDS);
192195
verify(restClientBuilderMock).readTimeout(201, MILLISECONDS);
193196
verify(restClientBuilderMock).userAgent("agent2");
@@ -215,6 +218,7 @@ private static Map<String, String> createSampleConfigRoot() {
215218
rootConfig.put("quarkus.rest-client.proxy-user", "proxyUser2");
216219
rootConfig.put("quarkus.rest-client.proxy-password", "proxyPassword2");
217220
rootConfig.put("quarkus.rest-client.non-proxy-hosts", "nonProxyHosts2");
221+
rootConfig.put("quarkus.rest-client.proxy-connect-timeout", "30s");
218222
rootConfig.put("quarkus.rest-client.connect-timeout", "200");
219223
rootConfig.put("quarkus.rest-client.read-timeout", "201");
220224
rootConfig.put("quarkus.rest-client.user-agent", "agent2");
@@ -250,6 +254,7 @@ private static Map<String, String> createSampleClientConfig(final String restCli
250254
clientConfig.put("quarkus.rest-client." + restClientName + ".proxy-user", "proxyUser1");
251255
clientConfig.put("quarkus.rest-client." + restClientName + ".proxy-password", "proxyPassword1");
252256
clientConfig.put("quarkus.rest-client." + restClientName + ".non-proxy-hosts", "nonProxyHosts1");
257+
clientConfig.put("quarkus.rest-client." + restClientName + ".proxy-connect-timeout", "20s");
253258
clientConfig.put("quarkus.rest-client." + restClientName + ".connect-timeout", "100");
254259
clientConfig.put("quarkus.rest-client." + restClientName + ".read-timeout", "101");
255260
clientConfig.put("quarkus.rest-client." + restClientName + ".user-agent", "agent1");

independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientBuilderImpl.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.security.KeyStoreException;
1010
import java.security.NoSuchAlgorithmException;
1111
import java.security.cert.CertificateException;
12+
import java.time.Duration;
1213
import java.util.List;
1314
import java.util.Map;
1415
import java.util.Optional;
@@ -56,6 +57,7 @@ public class ClientBuilderImpl extends ClientBuilder {
5657
private String proxyPassword;
5758
private String proxyUser;
5859
private String nonProxyHosts;
60+
private Duration proxyConnectTimeout;
5961

6062
private boolean followRedirects;
6163

@@ -255,6 +257,9 @@ public ClientImpl build() {
255257
if (proxyUser != null && !proxyUser.isBlank()) {
256258
proxyOptions.setUsername(proxyUser);
257259
}
260+
if (proxyConnectTimeout != null) {
261+
proxyOptions.setConnectTimeout(proxyConnectTimeout);
262+
}
258263
options.setProxyOptions(proxyOptions);
259264
configureNonProxyHosts(options, nonProxyHosts);
260265
}
@@ -491,4 +496,9 @@ public ClientBuilderImpl nonProxyHosts(String nonProxyHosts) {
491496
this.nonProxyHosts = nonProxyHosts;
492497
return this;
493498
}
499+
500+
public ClientBuilderImpl proxyConnectTimeout(Duration proxyConnectTimeout) {
501+
this.proxyConnectTimeout = proxyConnectTimeout;
502+
return this;
503+
}
494504
}

0 commit comments

Comments
 (0)