Skip to content

Commit 255ea92

Browse files
committed
Add HttpClientTransport factory support
Update `JettyClientHttpRequestFactoryBuilder` and `JettyClientHttpConnectorBuilder` with support for create the `HttpClientTransport` from a factory function. Closes gh-47251
1 parent b01dc92 commit 255ea92

File tree

5 files changed

+105
-7
lines changed

5 files changed

+105
-7
lines changed

module/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/JettyClientHttpRequestFactoryBuilder.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Collection;
2121
import java.util.List;
2222
import java.util.function.Consumer;
23+
import java.util.function.Function;
2324
import java.util.function.UnaryOperator;
2425

2526
import org.eclipse.jetty.client.HttpClient;
@@ -78,6 +79,20 @@ public JettyClientHttpRequestFactoryBuilder withHttpClientCustomizer(Consumer<Ht
7879
this.httpClientBuilder.withCustomizer(httpClientCustomizer));
7980
}
8081

82+
/**
83+
* Return a new {@link JettyClientHttpRequestFactoryBuilder} that uses the given
84+
* factory to create the {@link HttpClientTransport}.
85+
* @param httpClientTransportFactory the {@link HttpClientTransport} factory to use
86+
* @return a new {@link JettyClientHttpRequestFactoryBuilder} instance
87+
* @since 4.0.0
88+
*/
89+
public JettyClientHttpRequestFactoryBuilder withHttpClientTransportFactory(
90+
Function<ClientConnector, HttpClientTransport> httpClientTransportFactory) {
91+
Assert.notNull(httpClientTransportFactory, "'httpClientTransportFactory' must not be null");
92+
return new JettyClientHttpRequestFactoryBuilder(getCustomizers(),
93+
this.httpClientBuilder.withHttpClientTransportFactory(httpClientTransportFactory));
94+
}
95+
8196
/**
8297
* Return a new {@link JettyClientHttpRequestFactoryBuilder} that applies additional
8398
* customization to the underlying {@link HttpClientTransport}.

module/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/JettyHttpClientBuilder.java

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.time.Duration;
2020
import java.util.concurrent.TimeUnit;
2121
import java.util.function.Consumer;
22+
import java.util.function.Function;
2223

2324
import javax.net.ssl.SSLContext;
2425

@@ -48,22 +49,31 @@ public final class JettyHttpClientBuilder {
4849

4950
private final Consumer<HttpClient> customizer;
5051

52+
private final Function<ClientConnector, HttpClientTransport> httpClientTransportFactory;
53+
5154
private final Consumer<HttpClientTransport> httpClientTransportCustomizer;
5255

5356
private final Consumer<ClientConnector> clientConnectorCustomizerCustomizer;
5457

5558
public JettyHttpClientBuilder() {
56-
this(Empty.consumer(), Empty.consumer(), Empty.consumer());
59+
this(Empty.consumer(), JettyHttpClientBuilder::createHttpClientTransport, Empty.consumer(), Empty.consumer());
5760
}
5861

5962
private JettyHttpClientBuilder(Consumer<HttpClient> customizer,
63+
Function<ClientConnector, HttpClientTransport> httpClientTransportFactory,
6064
Consumer<HttpClientTransport> httpClientTransportCustomizer,
6165
Consumer<ClientConnector> clientConnectorCustomizerCustomizer) {
6266
this.customizer = customizer;
67+
this.httpClientTransportFactory = httpClientTransportFactory;
6368
this.httpClientTransportCustomizer = httpClientTransportCustomizer;
6469
this.clientConnectorCustomizerCustomizer = clientConnectorCustomizerCustomizer;
6570
}
6671

72+
private static HttpClientTransport createHttpClientTransport(ClientConnector connector) {
73+
return (connector.getSslContextFactory() != null) ? new HttpClientTransportDynamic(connector)
74+
: new HttpClientTransportOverHTTP(connector);
75+
}
76+
6777
/**
6878
* Return a new {@link JettyClientHttpRequestFactoryBuilder} that applies additional
6979
* customization to the underlying {@link HttpClient}.
@@ -72,8 +82,22 @@ private JettyHttpClientBuilder(Consumer<HttpClient> customizer,
7282
*/
7383
public JettyHttpClientBuilder withCustomizer(Consumer<HttpClient> customizer) {
7484
Assert.notNull(customizer, "'customizer' must not be null");
75-
return new JettyHttpClientBuilder(this.customizer.andThen(customizer), this.httpClientTransportCustomizer,
76-
this.clientConnectorCustomizerCustomizer);
85+
return new JettyHttpClientBuilder(this.customizer.andThen(customizer), this.httpClientTransportFactory,
86+
this.httpClientTransportCustomizer, this.clientConnectorCustomizerCustomizer);
87+
}
88+
89+
/**
90+
* Return a new {@link JettyClientHttpRequestFactoryBuilder} that uses the given
91+
* factory to create the {@link HttpClientTransport}.
92+
* @param httpClientTransportFactory the {@link HttpClientTransport} factory to use
93+
* @return a new {@link JettyClientHttpRequestFactoryBuilder} instance
94+
* @since 4.0.0
95+
*/
96+
public JettyHttpClientBuilder withHttpClientTransportFactory(
97+
Function<ClientConnector, HttpClientTransport> httpClientTransportFactory) {
98+
Assert.notNull(httpClientTransportFactory, "'httpClientTransportFactory' must not be null");
99+
return new JettyHttpClientBuilder(this.customizer, httpClientTransportFactory,
100+
this.httpClientTransportCustomizer, this.clientConnectorCustomizerCustomizer);
77101
}
78102

79103
/**
@@ -85,7 +109,7 @@ public JettyHttpClientBuilder withCustomizer(Consumer<HttpClient> customizer) {
85109
public JettyHttpClientBuilder withHttpClientTransportCustomizer(
86110
Consumer<HttpClientTransport> httpClientTransportCustomizer) {
87111
Assert.notNull(httpClientTransportCustomizer, "'httpClientTransportCustomizer' must not be null");
88-
return new JettyHttpClientBuilder(this.customizer,
112+
return new JettyHttpClientBuilder(this.customizer, this.httpClientTransportFactory,
89113
this.httpClientTransportCustomizer.andThen(httpClientTransportCustomizer),
90114
this.clientConnectorCustomizerCustomizer);
91115
}
@@ -99,7 +123,8 @@ public JettyHttpClientBuilder withHttpClientTransportCustomizer(
99123
public JettyHttpClientBuilder withClientConnectorCustomizerCustomizer(
100124
Consumer<ClientConnector> clientConnectorCustomizerCustomizer) {
101125
Assert.notNull(clientConnectorCustomizerCustomizer, "'clientConnectorCustomizerCustomizer' must not be null");
102-
return new JettyHttpClientBuilder(this.customizer, this.httpClientTransportCustomizer,
126+
return new JettyHttpClientBuilder(this.customizer, this.httpClientTransportFactory,
127+
this.httpClientTransportCustomizer,
103128
this.clientConnectorCustomizerCustomizer.andThen(clientConnectorCustomizerCustomizer));
104129
}
105130

@@ -127,8 +152,9 @@ private HttpClient createHttpClient(@Nullable Duration readTimeout, HttpClientTr
127152

128153
private HttpClientTransport createTransport(HttpClientSettings settings) {
129154
ClientConnector connector = createClientConnector(settings.sslBundle());
130-
return (connector.getSslContextFactory() != null) ? new HttpClientTransportDynamic(connector)
131-
: new HttpClientTransportOverHTTP(connector);
155+
HttpClientTransport clientTransport = this.httpClientTransportFactory.apply(connector);
156+
Assert.state(clientTransport != null, "'httpClientTransportFactory' did not return a client transport");
157+
return clientTransport;
132158
}
133159

134160
private ClientConnector createClientConnector(@Nullable SslBundle sslBundle) {

module/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/reactive/JettyClientHttpConnectorBuilder.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.Collection;
2020
import java.util.List;
2121
import java.util.function.Consumer;
22+
import java.util.function.Function;
2223
import java.util.function.UnaryOperator;
2324

2425
import org.eclipse.jetty.client.HttpClient;
@@ -62,6 +63,20 @@ public JettyClientHttpConnectorBuilder withCustomizers(Collection<Consumer<Jetty
6263
return new JettyClientHttpConnectorBuilder(mergedCustomizers(customizers), this.httpClientBuilder);
6364
}
6465

66+
/**
67+
* Return a new {@link JettyClientHttpConnectorBuilder} that uses the given factory to
68+
* create the {@link HttpClientTransport}.
69+
* @param httpClientTransportFactory the {@link HttpClientTransport} factory to use
70+
* @return a new {@link JettyClientHttpConnectorBuilder} instance
71+
* @since 4.0.0
72+
*/
73+
public JettyClientHttpConnectorBuilder withHttpClientTransportFactory(
74+
Function<ClientConnector, HttpClientTransport> httpClientTransportFactory) {
75+
Assert.notNull(httpClientTransportFactory, "'httpClientTransportFactory' must not be null");
76+
return new JettyClientHttpConnectorBuilder(getCustomizers(),
77+
this.httpClientBuilder.withHttpClientTransportFactory(httpClientTransportFactory));
78+
}
79+
6580
/**
6681
* Return a new {@link JettyClientHttpConnectorBuilder} that applies additional
6782
* customization to the underlying {@link HttpClient}.

module/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/JettyClientHttpRequestFactoryBuilderTests.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@
1818

1919
import org.eclipse.jetty.client.HttpClient;
2020
import org.eclipse.jetty.client.HttpClientTransport;
21+
import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP;
2122
import org.eclipse.jetty.io.ClientConnector;
2223
import org.junit.jupiter.api.Test;
2324

2425
import org.springframework.http.client.JettyClientHttpRequestFactory;
2526
import org.springframework.test.util.ReflectionTestUtils;
2627

28+
import static org.assertj.core.api.Assertions.assertThat;
29+
2730
/**
2831
* Tests for {@link JettyClientHttpRequestFactoryBuilder} and
2932
* {@link JettyHttpClientBuilder}.
@@ -62,6 +65,16 @@ void with() {
6265
customizer.assertCalled();
6366
}
6467

68+
@Test
69+
void withHttpClientTransportFactory() {
70+
JettyClientHttpRequestFactory factory = ClientHttpRequestFactoryBuilder.jetty()
71+
.withHttpClientTransportFactory(TestHttpClientTransport::new)
72+
.build();
73+
assertThat(factory).extracting("httpClient")
74+
.extracting("transport")
75+
.isInstanceOf(TestHttpClientTransport.class);
76+
}
77+
6578
@Override
6679
protected long connectTimeout(JettyClientHttpRequestFactory requestFactory) {
6780
return ((HttpClient) ReflectionTestUtils.getField(requestFactory, "httpClient")).getConnectTimeout();
@@ -72,4 +85,12 @@ protected long readTimeout(JettyClientHttpRequestFactory requestFactory) {
7285
return (long) ReflectionTestUtils.getField(requestFactory, "readTimeout");
7386
}
7487

88+
static class TestHttpClientTransport extends HttpClientTransportOverHTTP {
89+
90+
TestHttpClientTransport(ClientConnector connector) {
91+
super(connector);
92+
}
93+
94+
}
95+
7596
}

module/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/reactive/JettyClientHttpConnectorBuilderTests.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@
2020

2121
import org.eclipse.jetty.client.HttpClient;
2222
import org.eclipse.jetty.client.HttpClientTransport;
23+
import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP;
2324
import org.eclipse.jetty.io.ClientConnector;
2425
import org.junit.jupiter.api.Test;
2526

2627
import org.springframework.boot.http.client.JettyHttpClientBuilder;
2728
import org.springframework.http.client.reactive.JettyClientHttpConnector;
2829
import org.springframework.test.util.ReflectionTestUtils;
2930

31+
import static org.assertj.core.api.Assertions.assertThat;
32+
3033
/**
3134
* Tests for {@link JettyClientHttpConnectorBuilder} and {@link JettyHttpClientBuilder}.
3235
*
@@ -63,6 +66,16 @@ void with() {
6366
customizer.assertCalled();
6467
}
6568

69+
@Test
70+
void withHttpClientTransportFactory() {
71+
JettyClientHttpConnector connector = ClientHttpConnectorBuilder.jetty()
72+
.withHttpClientTransportFactory(TestHttpClientTransport::new)
73+
.build();
74+
assertThat(connector).extracting("httpClient")
75+
.extracting("transport")
76+
.isInstanceOf(TestHttpClientTransport.class);
77+
}
78+
6679
@Override
6780
protected long connectTimeout(JettyClientHttpConnector connector) {
6881
return ((HttpClient) ReflectionTestUtils.getField(connector, "httpClient")).getConnectTimeout();
@@ -74,4 +87,12 @@ protected long readTimeout(JettyClientHttpConnector connector) {
7487
return ((Duration) ReflectionTestUtils.getField(httpClient, "readTimeout")).toMillis();
7588
}
7689

90+
static class TestHttpClientTransport extends HttpClientTransportOverHTTP {
91+
92+
TestHttpClientTransport(ClientConnector connector) {
93+
super(connector);
94+
}
95+
96+
}
97+
7798
}

0 commit comments

Comments
 (0)