Skip to content

Commit d3ef710

Browse files
committed
Add RestClient support
1 parent c4260e7 commit d3ef710

File tree

5 files changed

+135
-16
lines changed

5 files changed

+135
-16
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2012-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.freefair.spring.okhttp;
18+
19+
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
20+
import org.springframework.boot.autoconfigure.condition.NoneNestedConditions;
21+
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
22+
23+
/**
24+
* {@link SpringBootCondition} that applies only when running in a non-reactive web
25+
* application.
26+
*
27+
* @author Phillip Webb
28+
*/
29+
class NotReactiveWebApplicationCondition extends NoneNestedConditions {
30+
31+
NotReactiveWebApplicationCondition() {
32+
super(ConfigurationPhase.PARSE_CONFIGURATION);
33+
}
34+
35+
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
36+
private static class ReactiveWebApplication {
37+
38+
}
39+
40+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.freefair.spring.okhttp;
2+
3+
import okhttp3.OkHttpClient;
4+
import org.springframework.boot.autoconfigure.AutoConfiguration;
5+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
6+
import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration;
7+
import org.springframework.boot.web.client.RestClientCustomizer;
8+
import org.springframework.context.annotation.Bean;
9+
import org.springframework.context.annotation.Conditional;
10+
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
11+
import org.springframework.web.client.RestClient;
12+
13+
/**
14+
* @author Lars Grefer
15+
* @see RestClientAutoConfiguration
16+
*/
17+
@AutoConfiguration
18+
@ConditionalOnClass({RestClientCustomizer.class, RestClient.class})
19+
@Conditional(NotReactiveWebApplicationCondition.class)
20+
public class OkHttpRestClientAutoConfiguration {
21+
22+
@Bean
23+
public RestClientCustomizer okHttpRestClientCustomizer(OkHttpClient okHttpClient) {
24+
return restClientBuilder -> restClientBuilder.requestFactory(new OkHttp3ClientHttpRequestFactory(okHttpClient));
25+
}
26+
27+
}

autoconfigure/src/main/java/io/freefair/spring/okhttp/OkHttpRestTemplateAutoConfiguration.java

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
import org.springframework.boot.autoconfigure.AutoConfiguration;
55
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
66
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
7-
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
8-
import org.springframework.boot.autoconfigure.condition.NoneNestedConditions;
97
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
108
import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;
119
import org.springframework.boot.autoconfigure.web.client.RestTemplateBuilderConfigurer;
@@ -23,7 +21,7 @@
2321
*/
2422
@AutoConfiguration(before = RestTemplateAutoConfiguration.class, after = HttpMessageConvertersAutoConfiguration.class)
2523
@ConditionalOnClass({RestTemplateCustomizer.class, RestTemplate.class})
26-
@Conditional(OkHttpRestTemplateAutoConfiguration.NotReactiveWebApplicationCondition.class)
24+
@Conditional(NotReactiveWebApplicationCondition.class)
2725
public class OkHttpRestTemplateAutoConfiguration {
2826

2927
@Bean
@@ -36,17 +34,4 @@ public RestTemplateBuilder restTemplateBuilder(RestTemplateBuilderConfigurer res
3634
return restTemplateBuilderConfigurer.configure(builder);
3735
}
3836

39-
static class NotReactiveWebApplicationCondition extends NoneNestedConditions {
40-
41-
NotReactiveWebApplicationCondition() {
42-
super(ConfigurationPhase.PARSE_CONFIGURATION);
43-
}
44-
45-
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
46-
private static class ReactiveWebApplication {
47-
48-
}
49-
50-
}
51-
5237
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
io.freefair.spring.okhttp.OkHttp3AutoConfiguration
2+
io.freefair.spring.okhttp.OkHttpRestClientAutoConfiguration
23
io.freefair.spring.okhttp.OkHttpRestTemplateAutoConfiguration
34
io.freefair.spring.okhttp.metrics.OkHttpMetricsAutoConfiguration
45
io.freefair.spring.okhttp.logging.OkHttp3LoggingInterceptorAutoConfiguration
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package io.freefair.spring.okhttp;
2+
3+
import okhttp3.OkHttpClient;
4+
import org.junit.jupiter.api.Test;
5+
import org.springframework.beans.factory.annotation.Autowired;
6+
import org.springframework.boot.SpringBootConfiguration;
7+
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
8+
import org.springframework.boot.test.context.SpringBootTest;
9+
import org.springframework.http.client.AbstractClientHttpRequestFactoryWrapper;
10+
import org.springframework.http.client.ClientHttpRequestFactory;
11+
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
12+
import org.springframework.web.client.RestClient;
13+
14+
import java.lang.reflect.Field;
15+
import java.time.Duration;
16+
17+
import static org.assertj.core.api.Assertions.assertThat;
18+
19+
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
20+
properties = {
21+
"okhttp.read-timeout=21s",
22+
"okhttp.connect-timeout=21s",
23+
"okhttp.write-timeout=21s"
24+
})
25+
class OkHttpRestClientAutoConfigurationTest {
26+
27+
@Autowired
28+
private RestClient.Builder restClientBuilder;
29+
30+
@Test
31+
void testTimeouts() throws NoSuchFieldException, IllegalAccessException {
32+
RestClient restTemplate = restClientBuilder.build();
33+
34+
OkHttpClient client = extractClient(restTemplate);
35+
36+
assertThat(client.connectTimeoutMillis()).isEqualTo(Duration.ofSeconds(21).toMillis());
37+
assertThat(client.readTimeoutMillis()).isEqualTo(Duration.ofSeconds(21).toMillis());
38+
assertThat(client.writeTimeoutMillis()).isEqualTo(Duration.ofSeconds(21).toMillis());
39+
}
40+
41+
private OkHttpClient extractClient(RestClient restClient) throws NoSuchFieldException, IllegalAccessException {
42+
43+
Field clientRequestFactoryField = restClient.getClass().getDeclaredField("clientRequestFactory");
44+
clientRequestFactoryField.setAccessible(true);
45+
ClientHttpRequestFactory requestFactory = (ClientHttpRequestFactory) clientRequestFactoryField.get(restClient);
46+
47+
while (requestFactory instanceof AbstractClientHttpRequestFactoryWrapper) {
48+
Field field = AbstractClientHttpRequestFactoryWrapper.class.getDeclaredField("requestFactory");
49+
field.setAccessible(true);
50+
requestFactory = (ClientHttpRequestFactory) field.get(requestFactory);
51+
}
52+
53+
assertThat(requestFactory).isInstanceOf(OkHttp3ClientHttpRequestFactory.class);
54+
55+
Field field = OkHttp3ClientHttpRequestFactory.class.getDeclaredField("client");
56+
field.setAccessible(true);
57+
return (OkHttpClient) field.get(requestFactory);
58+
}
59+
60+
61+
@SpringBootConfiguration
62+
@EnableAutoConfiguration
63+
public static class TestConfiguration {
64+
65+
}
66+
}

0 commit comments

Comments
 (0)