Skip to content

Commit a72f494

Browse files
committed
Upgrade Netty version to 4.1.46.Final and applied fix to solve failure problem
1 parent 8c7874c commit a72f494

5 files changed

Lines changed: 117 additions & 2 deletions

File tree

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ protected SimpleChannelPoolAwareChannelPool newPool(URI key) {
131131

132132
ChannelPipelineInitializer pipelineInitializer = new ChannelPipelineInitializer(protocol,
133133
sslContext,
134+
sslProvider,
134135
maxStreams,
135136
initialWindowSize,
136137
healthCheckPingPeriod,

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
import static software.amazon.awssdk.utils.NumericUtils.saturatedCast;
2323
import static software.amazon.awssdk.utils.StringUtils.lowerCase;
2424

25+
import io.netty.buffer.UnpooledByteBufAllocator;
2526
import io.netty.channel.Channel;
2627
import io.netty.channel.ChannelInitializer;
28+
import io.netty.channel.ChannelOption;
2729
import io.netty.channel.ChannelPipeline;
2830
import io.netty.channel.pool.AbstractChannelPoolHandler;
2931
import io.netty.channel.pool.ChannelPool;
@@ -37,6 +39,7 @@
3739
import io.netty.handler.logging.LoggingHandler;
3840
import io.netty.handler.ssl.SslContext;
3941
import io.netty.handler.ssl.SslHandler;
42+
import io.netty.handler.ssl.SslProvider;
4043
import java.net.URI;
4144
import java.time.Duration;
4245
import java.util.concurrent.CompletableFuture;
@@ -56,6 +59,7 @@
5659
public final class ChannelPipelineInitializer extends AbstractChannelPoolHandler {
5760
private final Protocol protocol;
5861
private final SslContext sslCtx;
62+
private final SslProvider sslProvider;
5963
private final long clientMaxStreams;
6064
private final int clientInitialWindowSize;
6165
private final Duration healthCheckPingPeriod;
@@ -65,6 +69,7 @@ public final class ChannelPipelineInitializer extends AbstractChannelPoolHandler
6569

6670
public ChannelPipelineInitializer(Protocol protocol,
6771
SslContext sslCtx,
72+
SslProvider sslProvider,
6873
long clientMaxStreams,
6974
int clientInitialWindowSize,
7075
Duration healthCheckPingPeriod,
@@ -73,6 +78,7 @@ public ChannelPipelineInitializer(Protocol protocol,
7378
URI poolKey) {
7479
this.protocol = protocol;
7580
this.sslCtx = sslCtx;
81+
this.sslProvider = sslProvider;
7682
this.clientMaxStreams = clientMaxStreams;
7783
this.clientInitialWindowSize = clientInitialWindowSize;
7884
this.healthCheckPingPeriod = healthCheckPingPeriod;
@@ -94,6 +100,12 @@ public void channelCreated(Channel ch) {
94100

95101
pipeline.addLast(sslHandler);
96102
pipeline.addLast(SslCloseCompletionEventHandler.getInstance());
103+
104+
// Use unpooled allocator to avoid increased heap memory usage from Netty 4.1.43.
105+
// See https://github.com/netty/netty/issues/9768
106+
if (sslProvider == SslProvider.JDK) {
107+
ch.config().setOption(ChannelOption.ALLOCATOR, UnpooledByteBufAllocator.DEFAULT);
108+
}
97109
}
98110

99111
if (protocol == Protocol.HTTP2) {

http-clients/netty-nio-client/src/test/java/software/amazon/awssdk/http/nio/netty/fault/GoAwayTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,17 @@ public void goAwayCanCloseAllStreams() throws InterruptedException {
9797

9898
CountDownLatch allRequestsReceived = new CountDownLatch(2);
9999
Supplier<Http2FrameListener> frameListenerSupplier = () -> new TestFrameListener() {
100+
@Override
101+
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int padding, boolean endStream) {
102+
onHeadersReadDelegator(ctx, streamId);
103+
}
104+
100105
@Override
101106
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int streamDependency, short weight, boolean exclusive, int padding, boolean endStream) {
107+
onHeadersReadDelegator(ctx, streamId);
108+
}
109+
110+
private void onHeadersReadDelegator(ChannelHandlerContext ctx, int streamId) {
102111
serverChannels.add(ctx.channel().id().asShortText());
103112

104113
Http2Headers outboundHeaders = new DefaultHttp2Headers()
@@ -146,8 +155,17 @@ public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers
146155
public void execute_goAwayReceived_existingChannelsNotReused() throws InterruptedException {
147156
// Frame listener supplier for each connection
148157
Supplier<Http2FrameListener> frameListenerSupplier = () -> new TestFrameListener() {
158+
@Override
159+
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int padding, boolean endStream) {
160+
onHeadersReadDelegator(ctx, streamId);
161+
}
162+
149163
@Override
150164
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int streamDependency, short weight, boolean exclusive, int padding, boolean endStream) {
165+
onHeadersReadDelegator(ctx, streamId);
166+
}
167+
168+
private void onHeadersReadDelegator(ChannelHandlerContext ctx, int streamId) {
151169
frameWriter().writeHeaders(ctx, streamId, new DefaultHttp2Headers().add("content-length", "0").status("204"), 0, true, ctx.newPromise());
152170
ctx.flush();
153171
}
@@ -188,8 +206,17 @@ public void execute_goAwayReceived_lastStreamId_lowerStreamsNotClosed() throws I
188206
CountDownLatch allRequestsReceived = new CountDownLatch(2);
189207
byte[] getPayload = "go away!".getBytes(StandardCharsets.UTF_8);
190208
Supplier<Http2FrameListener> frameListenerSupplier = () -> new TestFrameListener() {
209+
@Override
210+
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int padding, boolean endStream) {
211+
onHeadersReadDelegator(ctx, streamId);
212+
}
213+
191214
@Override
192215
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int streamDependency, short weight, boolean exclusive, int padding, boolean endStream) {
216+
onHeadersReadDelegator(ctx, streamId);
217+
}
218+
219+
private void onHeadersReadDelegator(ChannelHandlerContext ctx, int streamId) {
193220
channelToStreams.computeIfAbsent(ctx.channel().id().asShortText(), (k) -> Collections.newSetFromMap(new ConcurrentHashMap<>())).add(streamId);
194221

195222
if (streamId == 3) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
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+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.http.nio.netty.internal;
17+
18+
import static org.hamcrest.CoreMatchers.is;
19+
import static org.junit.Assert.assertThat;
20+
import static software.amazon.awssdk.http.SdkHttpConfigurationOption.GLOBAL_HTTP_DEFAULTS;
21+
22+
import io.netty.buffer.UnpooledByteBufAllocator;
23+
import io.netty.channel.Channel;
24+
import io.netty.channel.ChannelOption;
25+
import io.netty.channel.embedded.EmbeddedChannel;
26+
import io.netty.channel.pool.ChannelPool;
27+
import io.netty.handler.codec.http2.Http2SecurityUtil;
28+
import io.netty.handler.ssl.SslContext;
29+
import io.netty.handler.ssl.SslContextBuilder;
30+
import io.netty.handler.ssl.SslProvider;
31+
import io.netty.handler.ssl.SupportedCipherSuiteFilter;
32+
import java.net.URI;
33+
import java.time.Duration;
34+
import java.util.concurrent.atomic.AtomicReference;
35+
import javax.net.ssl.SSLException;
36+
import org.junit.Test;
37+
import software.amazon.awssdk.http.Protocol;
38+
39+
public class ChannelPipelineInitializerTest {
40+
41+
private ChannelPipelineInitializer pipelineInitializer;
42+
43+
private URI targetUri;
44+
45+
@Test
46+
public void channelConfigOptionCheck() throws SSLException {
47+
targetUri = URI.create("https://some-awesome-service-1234.amazonaws.com:8080");
48+
49+
SslContext sslContext = SslContextBuilder.forClient()
50+
.sslProvider(SslProvider.JDK)
51+
.ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE)
52+
.build();
53+
54+
AtomicReference<ChannelPool> channelPoolRef = new AtomicReference<>();
55+
56+
NettyConfiguration nettyConfiguration = new NettyConfiguration(GLOBAL_HTTP_DEFAULTS);
57+
58+
pipelineInitializer = new ChannelPipelineInitializer(Protocol.HTTP1_1,
59+
sslContext,
60+
SslProvider.JDK,
61+
100,
62+
1024,
63+
Duration.ZERO,
64+
channelPoolRef,
65+
nettyConfiguration,
66+
targetUri);
67+
68+
Channel channel = new EmbeddedChannel();
69+
70+
pipelineInitializer.channelCreated(channel);
71+
72+
assertThat(channel.config().getOption(ChannelOption.ALLOCATOR), is(UnpooledByteBufAllocator.DEFAULT));
73+
74+
}
75+
}

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
<equalsverifier.version>2.3.3</equalsverifier.version>
9595
<!-- Update netty-open-ssl-version accordingly whenever we update netty version-->
9696
<!-- https://github.com/netty/netty/blob/4.1/pom.xml#L286 -->
97-
<netty.version>4.1.42.Final</netty.version>
97+
<netty.version>4.1.46.Final</netty.version>
9898
<unitils.version>3.3</unitils.version>
9999
<xmlunit.version>1.3</xmlunit.version>
100100
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -119,7 +119,7 @@
119119
<jimfs.version>1.1</jimfs.version>
120120
<testng.version>7.1.0</testng.version> <!-- TCK Tests -->
121121
<commons-lang.verson>2.3</commons-lang.verson>
122-
<netty-open-ssl-version>2.0.25.Final</netty-open-ssl-version>
122+
<netty-open-ssl-version>2.0.29.Final</netty-open-ssl-version>
123123
<dynamodb-local.version>1.11.477</dynamodb-local.version>
124124
<sqllite.version>1.0.392</sqllite.version>
125125

0 commit comments

Comments
 (0)