Skip to content

Commit 795e4ac

Browse files
committed
Configure the default connector by its config
Signed-off-by: jansupol <[email protected]>
1 parent 9dd4ac3 commit 795e4ac

File tree

14 files changed

+1652
-312
lines changed

14 files changed

+1652
-312
lines changed

connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/JerseyClientHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ protected void notifyResponse(ChannelHandlerContext ctx) {
143143
ctx.close();
144144
if (redirectController.prepareRedirect(newReq, cr)) {
145145
final NettyConnector newConnector =
146-
new NettyConnector(newReq.getClient(), connector.connectorConfiguration);
146+
new NettyConnector(newReq.getClient(), connector.clientConfiguration);
147147
newConnector.execute(newReq, redirectUriHistory, new CompletableFuture<ClientResponse>() {
148148
@Override
149149
public boolean complete(ClientResponse value) {

connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ public class NettyClientProperties {
7272
*/
7373
public static final String IDLE_CONNECTION_PRUNE_TIMEOUT = "jersey.config.client.idleConnectionPruneTimeout";
7474

75+
/**
76+
* Enable or disable the Netty logging by {@code LoggingHandler(Level.DEBUG)}. Disabled by default.
77+
*/
78+
public static final String LOGGING_ENABLED = "jersey.config.client.netty.loggingEnabled";
79+
7580
/**
7681
* <p>
7782
* This property determines the maximum number of idle connections that will be simultaneously kept alive, per destination.

connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@
6161
import io.netty.handler.codec.http.HttpUtil;
6262
import io.netty.handler.codec.http.HttpVersion;
6363
import io.netty.handler.codec.http.LastHttpContent;
64+
import io.netty.handler.logging.LogLevel;
65+
import io.netty.handler.logging.LoggingHandler;
6466
import io.netty.handler.ssl.ApplicationProtocolConfig;
6567
import io.netty.handler.ssl.ClientAuth;
6668
import io.netty.handler.ssl.IdentityCipherSuiteFilter;
@@ -96,7 +98,7 @@ class NettyConnector implements Connector {
9698
final EventLoopGroup group;
9799
final Client client;
98100
final HashMap<String, ArrayList<Channel>> connections = new HashMap<>();
99-
final NettyConnectorProvider.Config.RW connectorConfiguration;
101+
final NettyConnectorProvider.Config.RW clientConfiguration;
100102

101103
private static final LazyValue<String> NETTY_VERSION = Values.lazy(
102104
(Value<String>) () -> {
@@ -117,18 +119,18 @@ class NettyConnector implements Connector {
117119

118120
NettyConnector(Client client, NettyConnectorProvider.Config.RW connectorConfiguration) {
119121
this.client = client;
120-
this.connectorConfiguration = connectorConfiguration.fromClient(client);
122+
this.clientConfiguration = connectorConfiguration.fromClient(client);
121123

122124
final Configuration configuration = client.getConfiguration();
123-
final Integer threadPoolSize = this.connectorConfiguration.asyncThreadPoolSize();
125+
final Integer threadPoolSize = this.clientConfiguration.asyncThreadPoolSize();
124126
if (threadPoolSize != null && threadPoolSize > 0) {
125127
executorService = VirtualThreadUtil
126-
.withConfig(connectorConfiguration.prefixedConfiguration(configuration))
128+
.withConfig(clientConfiguration.prefixedConfiguration(configuration))
127129
.newFixedThreadPool(threadPoolSize);
128130
this.group = new NioEventLoopGroup(threadPoolSize);
129131
} else {
130132
executorService = VirtualThreadUtil
131-
.withConfig(connectorConfiguration.prefixedConfiguration(configuration))
133+
.withConfig(clientConfiguration.prefixedConfiguration(configuration))
132134
.newCachedThreadPool();
133135
this.group = new NioEventLoopGroup();
134136
}
@@ -165,7 +167,7 @@ public Future<?> apply(final ClientRequest jerseyRequest, final AsyncConnectorCa
165167
protected void execute(final ClientRequest jerseyRequest, final Set<URI> redirectUriHistory,
166168
final CompletableFuture<ClientResponse> responseAvailable) {
167169
final NettyConnectorProvider.Config.RW requestConfiguration =
168-
connectorConfiguration
170+
clientConfiguration
169171
.fromRequest(jerseyRequest)
170172
.readTimeout(jerseyRequest)
171173
.expect100ContinueTimeout(jerseyRequest);
@@ -183,7 +185,7 @@ protected void execute(final ClientRequest jerseyRequest, final Set<URI> redirec
183185
: "https".equalsIgnoreCase(requestUri.getScheme()) ? 443 : 80;
184186

185187
try {
186-
final SSLParamConfigurator sslConfig = SSLParamConfigurator.builder()
188+
final SSLParamConfigurator sslConfig = SSLParamConfigurator.builder(requestConfiguration)
187189
.request(jerseyRequest).setSNIAlways(true).setSNIHostName(jerseyRequest).build();
188190

189191
final String key = requestConfiguration
@@ -272,6 +274,9 @@ protected void initChannel(SocketChannel ch) throws Exception {
272274
p.addLast(sslHandler);
273275
}
274276

277+
if (requestConfiguration.loggingEnabled.get()) {
278+
p.addLast(new LoggingHandler(LogLevel.INFO));
279+
}
275280
p.addLast(requestConfiguration.createHttpClientCodec(config.getProperties()));
276281
p.addLast(EXPECT_100_CONTINUE_HANDLER, expect100ContinueHandler);
277282
p.addLast(new ChunkedWriteHandler());

connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnectorConfiguration.java

Lines changed: 88 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,21 @@
3636
class NettyConnectorConfiguration<N extends NettyConnectorConfiguration<N>> extends ConnectorConfiguration<N> {
3737

3838
/* package */ final NullableRef<NettyConnectionController> connectionController = NullableRef.empty();
39-
/* package */ final NullableRef<Boolean> enableHostnameVerification = NullableRef.of(Boolean.TRUE);
40-
/* package */ final Ref<Integer> expect100ContTimeout = NullableRef.of(
41-
NettyClientProperties.DEFAULT_EXPECT_100_CONTINUE_TIMEOUT_VALUE);
42-
/* package */ final NullableRef<Boolean> filterHeadersForProxy = NullableRef.of(Boolean.TRUE);
43-
/* package */ final NullableRef<Integer> firstHttpHeaderLineLength = NullableRef.of(
44-
NettyClientProperties.DEFAULT_INITIAL_LINE_LENGTH);
45-
/* package */ final NullableRef<Integer> maxChunkSize = NullableRef.of(NettyClientProperties.DEFAULT_CHUNK_SIZE);
46-
/* package */ final NullableRef<Integer> maxHeaderSize = NullableRef.of(NettyClientProperties.DEFAULT_HEADER_SIZE);
39+
/* package */ final NullableRef<Boolean> enableHostnameVerification = NullableRef.empty();
40+
/* package */ final Ref<Integer> expect100ContTimeout = NullableRef.empty();
41+
/* package */ final NullableRef<Boolean> filterHeadersForProxy = NullableRef.empty();
42+
/* package */ final NullableRef<Integer> firstHttpHeaderLineLength = NullableRef.empty();
43+
/* package */ final Ref<Boolean> loggingEnabled = NullableRef.empty();
44+
/* package */ final NullableRef<Integer> maxChunkSize = NullableRef.empty();
45+
/* package */ final NullableRef<Integer> maxHeaderSize = NullableRef.empty();
4746
// either from Jersey config, or default
48-
/* package */ final Ref<Integer> maxPoolSizeTotal = NullableRef.of(DEFAULT_MAX_POOL_SIZE_TOTAL);
47+
/* package */ final Ref<Integer> maxPoolSizeTotal = NullableRef.empty();
4948
// either from Jersey config, or default
50-
/* package */ final Ref<Integer> maxPoolIdle = NullableRef.of(DEFAULT_MAX_POOL_IDLE);
49+
/* package */ final Ref<Integer> maxPoolIdle = NullableRef.empty();
5150
// either from system property, or from Jersey config, or default
52-
/* package */ final Ref<Integer> maxPoolSize = NullableRef.of(HTTP_KEEPALIVE ? MAX_POOL_SIZE : DEFAULT_MAX_POOL_SIZE);
53-
/* package */ final Ref<Integer> maxRedirects = NullableRef.of(DEFAULT_MAX_REDIRECTS);
54-
/* package */ final NullableRef<Boolean> preserveMethodOnRedirect = NullableRef.of(Boolean.TRUE);
51+
/* package */ final Ref<Integer> maxPoolSize = NullableRef.empty();
52+
/* package */ final Ref<Integer> maxRedirects = NullableRef.empty();
53+
/* package */ final NullableRef<Boolean> preserveMethodOnRedirect = NullableRef.empty();
5554
/* package */ final NullableRef<NettyHttpRedirectController> redirectController = NullableRef.empty();
5655

5756
// If HTTP keepalive is enabled the value of "http.maxConnections" determines the maximum number
@@ -69,27 +68,6 @@ class NettyConnectorConfiguration<N extends NettyConnectorConfiguration<N>> exte
6968

7069
private static final int DEFAULT_MAX_REDIRECTS = 5;
7170

72-
@Override
73-
protected <X extends ConnectorConfiguration<?>> void setNonEmpty(X otherCC) {
74-
NettyConnectorConfiguration<?> other = (NettyConnectorConfiguration<?>) otherCC;
75-
super.setNonEmpty(other);
76-
this.connectionController.setNonEmpty(other.connectionController);
77-
this.redirectController.setNonEmpty(other.redirectController);
78-
this.connectionController.setNonEmpty(other.connectionController);
79-
this.enableHostnameVerification.setNonEmpty(other.enableHostnameVerification);
80-
((NullableRef<Integer>) this.expect100ContTimeout).setNonEmpty((NullableRef<Integer>) other.expect100ContTimeout);
81-
this.filterHeadersForProxy.setNonEmpty(other.filterHeadersForProxy);
82-
this.firstHttpHeaderLineLength.setNonEmpty(other.firstHttpHeaderLineLength);
83-
this.maxChunkSize.setNonEmpty(other.maxChunkSize);
84-
this.maxHeaderSize.setNonEmpty(other.maxHeaderSize);
85-
((NullableRef<Integer>) this.maxPoolIdle).setNonEmpty((NullableRef<Integer>) other.maxPoolIdle);
86-
((NullableRef<Integer>) this.maxPoolSize).setNonEmpty((NullableRef<Integer>) other.maxPoolSize);
87-
((NullableRef<Integer>) this.maxPoolSizeTotal).setNonEmpty((NullableRef<Integer>) other.maxPoolSizeTotal);
88-
((NullableRef<Integer>) this.maxRedirects).setNonEmpty((NullableRef<Integer>) other.maxRedirects);
89-
this.preserveMethodOnRedirect.setNonEmpty(other.preserveMethodOnRedirect);
90-
this.redirectController.setNonEmpty(other.redirectController);
91-
}
92-
9371
/**
9472
* Set the connection pooling controller for the Netty Connector.
9573
*
@@ -115,7 +93,7 @@ public N expect100ContinueTimeout(int millis) {
11593

11694
/**
11795
* Enable or disable the endpoint identification algorithm to HTTPS. The property
118-
* {@link NettyClientProperties#ENABLE_SSL_HOSTNAME_VERIFICATION} has over this setting.
96+
* {@link NettyClientProperties#ENABLE_SSL_HOSTNAME_VERIFICATION} takes precedence over this setting.
11997
*
12098
* @param enable enable or disable the hostname verification.
12199
* @return updated configuration.
@@ -125,6 +103,18 @@ public N enableSslHostnameVerification(boolean enable) {
125103
return self();
126104
}
127105

106+
/**
107+
* Enable or disable the Netty logging by {@code LoggingHandler(Level.DEBUG)}. Disabled by default.
108+
* The property {@link NettyClientProperties#LOGGING_ENABLED} takes precedence over this setting.
109+
*
110+
* @param enable to enable or disable.
111+
* @return updated configuration.
112+
*/
113+
public N enableLoggingHandler(boolean enable) {
114+
loggingEnabled.set(enable);
115+
return self();
116+
}
117+
128118
/**
129119
* Filter the HTTP headers for requests (CONNECT) towards the proxy except for PROXY-prefixed
130120
* and HOST headers when {@code true}.
@@ -257,6 +247,49 @@ abstract static class ReadWrite<N extends ReadWrite<N>>
257247
extends NettyConnectorConfiguration<N>
258248
implements ConnectorConfiguration.Read<N> {
259249

250+
@Override
251+
public <X extends ConnectorConfiguration<?>> void setNonEmpty(X otherCC) {
252+
NettyConnectorConfiguration<?> other = (NettyConnectorConfiguration<?>) otherCC;
253+
ConnectorConfiguration.Read.super.setNonEmpty(other);
254+
this.connectionController.setNonEmpty(other.connectionController);
255+
this.redirectController.setNonEmpty(other.redirectController);
256+
this.connectionController.setNonEmpty(other.connectionController);
257+
this.enableHostnameVerification.setNonEmpty(other.enableHostnameVerification);
258+
((NullableRef<Integer>) this.expect100ContTimeout).setNonEmpty((NullableRef<Integer>) other.expect100ContTimeout);
259+
this.filterHeadersForProxy.setNonEmpty(other.filterHeadersForProxy);
260+
this.firstHttpHeaderLineLength.setNonEmpty(other.firstHttpHeaderLineLength);
261+
((NullableRef<Boolean>) this.loggingEnabled).setNonEmpty((NullableRef<Boolean>) other.loggingEnabled);
262+
this.maxChunkSize.setNonEmpty(other.maxChunkSize);
263+
this.maxHeaderSize.setNonEmpty(other.maxHeaderSize);
264+
((NullableRef<Integer>) this.maxPoolIdle).setNonEmpty((NullableRef<Integer>) other.maxPoolIdle);
265+
((NullableRef<Integer>) this.maxPoolSize).setNonEmpty((NullableRef<Integer>) other.maxPoolSize);
266+
((NullableRef<Integer>) this.maxPoolSizeTotal).setNonEmpty((NullableRef<Integer>) other.maxPoolSizeTotal);
267+
((NullableRef<Integer>) this.maxRedirects).setNonEmpty((NullableRef<Integer>) other.maxRedirects);
268+
this.preserveMethodOnRedirect.setNonEmpty(other.preserveMethodOnRedirect);
269+
this.redirectController.setNonEmpty(other.redirectController);
270+
}
271+
272+
@Override
273+
public N init() {
274+
Read.super.init();
275+
enableSslHostnameVerification(Boolean.TRUE);
276+
expect100ContinueTimeout(NettyClientProperties.DEFAULT_EXPECT_100_CONTINUE_TIMEOUT_VALUE);
277+
filterHeadersForProxy(Boolean.TRUE);
278+
initialHttpHeaderLineLength(NettyClientProperties.DEFAULT_INITIAL_LINE_LENGTH);
279+
enableLoggingHandler(Boolean.FALSE);
280+
maxChunkSize(NettyClientProperties.DEFAULT_CHUNK_SIZE);
281+
maxHeaderSize(NettyClientProperties.DEFAULT_HEADER_SIZE);
282+
// either from Jersey config, or default
283+
maxTotalConnections(DEFAULT_MAX_POOL_SIZE_TOTAL);
284+
// either from Jersey config, or default
285+
maxPoolIdle.set(DEFAULT_MAX_POOL_IDLE);
286+
// either from system property, or from Jersey config, or default
287+
maxPoolSize.set(HTTP_KEEPALIVE ? MAX_POOL_SIZE : DEFAULT_MAX_POOL_SIZE);
288+
maxRedirects(DEFAULT_MAX_REDIRECTS);
289+
preserveMethodOnRedirect(Boolean.TRUE);
290+
return self();
291+
}
292+
260293
/**
261294
* Get the preset {@link NettyConnectionController} or create an instance of the default one, if not preset.
262295
* @return the {@link NettyConnectionController} instance.
@@ -350,29 +383,19 @@ abstract static class ReadWrite<N extends ReadWrite<N>>
350383
*/
351384
/* package */ N fromClient(Client client) {
352385
final Map<String, Object> properties = client.getConfiguration().getProperties();
353-
final N clientConfiguration = copy();
354-
Object configProp = properties.get(prefixed(ClientProperties.CONNECTOR_CONFIGURATION));
355-
if (configProp != null) {
356-
NettyConnectorConfiguration<?> nettyCfg = (NettyConnectorConfiguration<?>) configProp;
357-
if (prefix.equals(nettyCfg.prefix) || "".equals(nettyCfg.prefix.get())) {
358-
clientConfiguration.setNonEmpty(nettyCfg);
359-
clientConfiguration.prefix(prefix.get());
360-
}
361-
} else {
362-
configProp = properties.get(ClientProperties.CONNECTOR_CONFIGURATION);
363-
if (configProp != null && prefix.equals(((NettyConnectorConfiguration<?>) configProp).prefix)) {
364-
clientConfiguration.setNonEmpty((NettyConnectorConfiguration<?>) configProp);
365-
}
366-
}
386+
final N clientConfiguration = copyFromClient(client.getConfiguration());
367387

368-
final Object threadPoolSize = properties.get(prefixed(ClientProperties.ASYNC_THREADPOOL_SIZE));
388+
final Object threadPoolSize = properties.get(clientConfiguration.prefixed(ClientProperties.ASYNC_THREADPOOL_SIZE));
369389
if (threadPoolSize instanceof Integer && (Integer) threadPoolSize > 0) {
370390
clientConfiguration.asyncThreadPoolSize((Integer) threadPoolSize);
371391
}
372392

373-
final Object maxPoolSizeTotalProperty = properties.get(prefixed(NettyClientProperties.MAX_CONNECTIONS_TOTAL));
374-
final Object maxPoolIdleProperty = properties.get(prefixed(NettyClientProperties.IDLE_CONNECTION_PRUNE_TIMEOUT));
375-
final Object maxPoolSizeProperty = properties.get(prefixed(NettyClientProperties.MAX_CONNECTIONS));
393+
final Object maxPoolSizeTotalProperty = properties.get(
394+
clientConfiguration.prefixed(NettyClientProperties.MAX_CONNECTIONS_TOTAL));
395+
final Object maxPoolIdleProperty = properties.get(
396+
clientConfiguration.prefixed(NettyClientProperties.IDLE_CONNECTION_PRUNE_TIMEOUT));
397+
final Object maxPoolSizeProperty = properties.get(
398+
clientConfiguration.prefixed(NettyClientProperties.MAX_CONNECTIONS));
376399

377400
if (maxPoolSizeTotalProperty != null) {
378401
clientConfiguration.maxPoolSizeTotal.set((Integer) maxPoolSizeTotalProperty);
@@ -394,6 +417,13 @@ abstract static class ReadWrite<N extends ReadWrite<N>>
394417
throw new ProcessingException(LocalizationMessages.WRONG_MAX_POOL_SIZE(maxPoolSize.get()));
395418
}
396419

420+
final Object logging = properties.get(clientConfiguration.prefixed(NettyClientProperties.LOGGING_ENABLED));
421+
if (logging instanceof Boolean) {
422+
clientConfiguration.loggingEnabled.set((Boolean) logging);
423+
} else if (logging instanceof String) {
424+
clientConfiguration.loggingEnabled.set(Boolean.valueOf((String) logging));
425+
}
426+
397427
return clientConfiguration;
398428
}
399429

@@ -410,19 +440,11 @@ abstract static class ReadWrite<N extends ReadWrite<N>>
410440
* @return a new instance of configuration.
411441
*/
412442
/* package */ N fromRequest(ClientRequest request) {
413-
final N requestConfiguration = copy();
414-
Object configProp = request.getProperty(prefixed(ClientProperties.CONNECTOR_CONFIGURATION));
415-
if (configProp != null) {
416-
NettyConnectorConfiguration<?> nettyCfg = (NettyConnectorConfiguration<?>) configProp;
417-
if (prefix.equals(nettyCfg.prefix) || "".equals(nettyCfg.prefix.get())) {
418-
requestConfiguration.setNonEmpty(nettyCfg);
419-
requestConfiguration.prefix(prefix.get());
420-
}
421-
} else {
422-
configProp = request.getProperty(ClientProperties.CONNECTOR_CONFIGURATION);
423-
if (configProp != null && prefix.equals(((NettyConnectorConfiguration<?>) configProp).prefix)) {
424-
requestConfiguration.setNonEmpty((NettyConnectorConfiguration<?>) configProp);
425-
}
443+
final N requestConfiguration = copyFromRequest(request);
444+
445+
final Boolean logging = request.resolveProperty(prefixed(NettyClientProperties.LOGGING_ENABLED), Boolean.class);
446+
if (logging != null) {
447+
requestConfiguration.loggingEnabled.set(logging);
426448
}
427449

428450
return requestConfiguration;
@@ -476,9 +498,6 @@ abstract static class ReadWrite<N extends ReadWrite<N>>
476498

477499
return proxy;
478500
}
479-
480-
@Override
481-
public abstract N self();
482501
}
483502

484503
}

connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnectorProvider.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,6 @@ public static final class Config extends NettyConnectorConfiguration<Config> {
7979
private Config() {
8080
}
8181

82-
@Override
83-
protected Config self() {
84-
return this;
85-
}
86-
8782
/* package */ RW rw() {
8883
RW rw = new RW();
8984
rw.setNonEmpty(this);
@@ -100,8 +95,7 @@ public RW instance() {
10095
return new RW();
10196
}
10297

103-
@Override
104-
public RW self() {
98+
public RW me() {
10599
return this;
106100
}
107101
}

0 commit comments

Comments
 (0)