Skip to content

Commit e82d240

Browse files
committed
Add keepAlive configuration in NettyNioAsyncHttpClient
1 parent ac6a1c0 commit e82d240

File tree

5 files changed

+58
-6
lines changed

5 files changed

+58
-6
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"category": "Netty NIO Async HTTP Client",
3+
"contributor": "",
4+
"type": "feature",
5+
"description": "Add `tcpKeepAlive` configuration."
6+
}

http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import io.netty.channel.EventLoopGroup;
2727
import io.netty.handler.ssl.SslContext;
2828
import io.netty.handler.ssl.SslProvider;
29+
import java.net.SocketOptions;
2930
import java.net.URI;
3031
import java.time.Duration;
3132
import java.util.concurrent.CompletableFuture;
@@ -359,6 +360,14 @@ public interface Builder extends SdkAsyncHttpClient.Builder<NettyNioAsyncHttpCli
359360
*/
360361
Builder protocol(Protocol protocol);
361362

363+
/**
364+
* Configure whether to enable support for TCP KeepAlive {@link SocketOptions#SO_KEEPALIVE}
365+
*
366+
* <p>
367+
* By default, this is disabled.
368+
*/
369+
Builder tcpKeepAlive(Boolean keepConnectionAlive);
370+
362371
/**
363372
* Configures additional {@link ChannelOption} which will be used to create Netty Http client. This allows custom
364373
* configuration for Netty.
@@ -599,6 +608,16 @@ public void setProtocol(Protocol protocol) {
599608
protocol(protocol);
600609
}
601610

611+
@Override
612+
public Builder tcpKeepAlive(Boolean keepConnectionAlive) {
613+
standardOptions.put(SdkHttpConfigurationOption.TCP_KEEPALIVE, keepConnectionAlive);
614+
return this;
615+
}
616+
617+
public void setTcpKeepAlive(Boolean keepConnectionAlive) {
618+
tcpKeepAlive(keepConnectionAlive);
619+
}
620+
602621
@Override
603622
public Builder putChannelOption(ChannelOption channelOption, Object value) {
604623
this.sdkChannelOptions.putOption(channelOption, value);

http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/internal/BootstrapProvider.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public Bootstrap createBootstrap(String host, int port) {
5454
.group(sdkEventLoopGroup.eventLoopGroup())
5555
.channelFactory(sdkEventLoopGroup.channelFactory())
5656
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, nettyConfiguration.connectTimeoutMillis())
57+
.option(ChannelOption.SO_KEEPALIVE, nettyConfiguration.tcpKeepAlive())
5758
.remoteAddress(InetSocketAddress.createUnresolved(host, port));
5859
sdkChannelOptions.channelOptions().forEach(bootstrap::option);
5960

http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/internal/NettyConfiguration.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static software.amazon.awssdk.http.SdkHttpConfigurationOption.CONNECTION_TIMEOUT;
2020
import static software.amazon.awssdk.http.SdkHttpConfigurationOption.MAX_CONNECTIONS;
2121
import static software.amazon.awssdk.http.SdkHttpConfigurationOption.MAX_PENDING_CONNECTION_ACQUIRES;
22+
import static software.amazon.awssdk.http.SdkHttpConfigurationOption.TCP_KEEPALIVE;
2223
import static software.amazon.awssdk.http.SdkHttpConfigurationOption.TRUST_ALL_CERTIFICATES;
2324
import static software.amazon.awssdk.utils.NumericUtils.saturatedCast;
2425

@@ -97,4 +98,8 @@ public TlsTrustManagersProvider tlsTrustManagersProvider() {
9798
public boolean trustAllCertificates() {
9899
return configuration.get(TRUST_ALL_CERTIFICATES);
99100
}
101+
102+
public boolean tcpKeepAlive() {
103+
return configuration.get(TCP_KEEPALIVE);
104+
}
100105
}

http-clients/netty-nio-client/src/test/java/software/amazon/awssdk/http/nio/netty/internal/BootstrapProviderTest.java

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,17 @@
1717

1818
import static org.assertj.core.api.Assertions.assertThat;
1919
import static software.amazon.awssdk.http.SdkHttpConfigurationOption.GLOBAL_HTTP_DEFAULTS;
20+
import static software.amazon.awssdk.http.SdkHttpConfigurationOption.TCP_KEEPALIVE;
2021

22+
import io.netty.bootstrap.Bootstrap;
23+
import io.netty.channel.ChannelOption;
2124
import java.net.InetSocketAddress;
2225
import java.net.SocketAddress;
23-
2426
import org.junit.Test;
2527
import org.junit.runner.RunWith;
26-
import org.mockito.Mock;
2728
import org.mockito.runners.MockitoJUnitRunner;
28-
29-
import io.netty.bootstrap.Bootstrap;
30-
import io.netty.resolver.AddressResolver;
31-
import io.netty.resolver.AddressResolverGroup;
3229
import software.amazon.awssdk.http.nio.netty.SdkEventLoopGroup;
30+
import software.amazon.awssdk.utils.AttributeMap;
3331

3432
@RunWith(MockitoJUnitRunner.class)
3533
public class BootstrapProviderTest {
@@ -53,4 +51,27 @@ public void createBootstrap_usesUnresolvedInetSocketAddress() {
5351

5452
assertThat(inetSocketAddress.isUnresolved()).isTrue();
5553
}
54+
55+
@Test
56+
public void createBootstrap_defaultConfiguration_tcpKeepAliveShouldBeFalse() {
57+
Bootstrap bootstrap = bootstrapProvider.createBootstrap("some-awesome-service-1234.amazonaws.com", 443);
58+
59+
Boolean keepAlive = (Boolean) bootstrap.config().options().get(ChannelOption.SO_KEEPALIVE);
60+
assertThat(keepAlive).isFalse();
61+
}
62+
63+
@Test
64+
public void createBootstrap_tcpKeepAliveTrue_shouldApply() {
65+
NettyConfiguration nettyConfiguration =
66+
new NettyConfiguration(AttributeMap.builder().put(TCP_KEEPALIVE, true)
67+
.build().merge(GLOBAL_HTTP_DEFAULTS));
68+
BootstrapProvider provider =
69+
new BootstrapProvider(SdkEventLoopGroup.builder().build(),
70+
nettyConfiguration,
71+
new SdkChannelOptions());
72+
73+
Bootstrap bootstrap = provider.createBootstrap("some-awesome-service-1234.amazonaws.com", 443);
74+
Boolean keepAlive = (Boolean) bootstrap.config().options().get(ChannelOption.SO_KEEPALIVE);
75+
assertThat(keepAlive).isTrue();
76+
}
5677
}

0 commit comments

Comments
 (0)