use of io.netty.handler.codec.http2.Http2StreamChannel in project ambry by linkedin.
the class Http2MultiplexedChannelPoolTest method streamChannelAcquireReleaseTest.
/**
* Channel acquire and release test.
*/
@Test
public void streamChannelAcquireReleaseTest() throws Exception {
Channel channel = newHttp2Channel();
try {
ChannelPool connectionPool = Mockito.mock(ChannelPool.class);
loopGroup.register(channel).awaitUninterruptibly();
Promise<Channel> channelPromise = new DefaultPromise<>(loopGroup.next());
channelPromise.setSuccess(channel);
Mockito.when(connectionPool.acquire()).thenReturn(channelPromise);
Http2MultiplexedChannelPool h2Pool = new Http2MultiplexedChannelPool(connectionPool, loopGroup, new HashSet<>(), null, http2ClientConfigForOneConnection, new Http2ClientMetrics(new MetricRegistry()), streamChannelInitializer);
Channel streamChannel1 = h2Pool.acquire().awaitUninterruptibly().getNow();
assertTrue(streamChannel1 instanceof Http2StreamChannel);
Mockito.verify(connectionPool, Mockito.times(1)).acquire();
Channel streamChannel2 = h2Pool.acquire().awaitUninterruptibly().getNow();
assertTrue(streamChannel2 instanceof Http2StreamChannel);
Mockito.verify(connectionPool, Mockito.times(1)).acquire();
// Verify number of numOfAvailableStreams
MultiplexedChannelRecord multiplexedChannelRecord = streamChannel2.parent().attr(Http2MultiplexedChannelPool.MULTIPLEXED_CHANNEL).get();
assertEquals(maxConcurrentStreamsPerConnection - 2, multiplexedChannelRecord.getNumOfAvailableStreams().get());
h2Pool.release(streamChannel1).getNow();
h2Pool.release(streamChannel2).getNow();
assertEquals(maxConcurrentStreamsPerConnection, multiplexedChannelRecord.getNumOfAvailableStreams().get());
} finally {
channel.close();
}
}
use of io.netty.handler.codec.http2.Http2StreamChannel in project ambry by linkedin.
the class Http2MultiplexedChannelPoolTest method minConnectionTest.
/**
* Minimum Connection is required.
*/
@Test
public void minConnectionTest() throws Exception {
int minConnections = 2;
int totalStreamToAcquire = 4;
List<Channel> channels = new ArrayList<>();
try {
ChannelPool connectionPool = Mockito.mock(ChannelPool.class);
OngoingStubbing<Future<Channel>> mockito = Mockito.when(connectionPool.acquire());
for (int i = 0; i < minConnections; i++) {
Channel channel = newHttp2Channel();
channels.add(channel);
loopGroup.register(channel).awaitUninterruptibly();
Promise<Channel> channelPromise = new DefaultPromise<>(loopGroup.next());
channelPromise.setSuccess(channel);
mockito = mockito.thenReturn(channelPromise);
}
Http2MultiplexedChannelPool h2Pool = new Http2MultiplexedChannelPool(connectionPool, loopGroup, new HashSet<>(), null, http2ClientConfigForTwoConnection, new Http2ClientMetrics(new MetricRegistry()), streamChannelInitializer);
List<Channel> toRelease = new ArrayList<>();
for (int i = 0; i < minConnections; i++) {
Channel streamChannel = h2Pool.acquire().awaitUninterruptibly().getNow();
toRelease.add(streamChannel);
assertTrue(streamChannel instanceof Http2StreamChannel);
Mockito.verify(connectionPool, Mockito.times(i + 1)).acquire();
}
for (int i = minConnections; i < totalStreamToAcquire; i++) {
Channel streamChannel = h2Pool.acquire().awaitUninterruptibly().getNow();
toRelease.add(streamChannel);
assertTrue(streamChannel instanceof Http2StreamChannel);
// No more parent channel acquisition
Mockito.verify(connectionPool, Mockito.times(minConnections)).acquire();
}
for (Channel streamChannel : toRelease) {
h2Pool.release(streamChannel).getNow();
}
} finally {
for (Channel channel : channels) {
channel.close();
}
}
}
use of io.netty.handler.codec.http2.Http2StreamChannel in project ambry by linkedin.
the class MultiplexedChannelRecord method acquireClaimedStream.
void acquireClaimedStream(Promise<Channel> promise) {
NettyUtils.doInEventLoop(parentChannel.eventLoop(), () -> {
if (state != RecordState.OPEN) {
String message;
// GOAWAY
if (state == RecordState.CLOSED_TO_NEW) {
message = String.format("Connection %s received GOAWAY with Last Stream ID %d. Unable to open new " + "streams on this connection.", parentChannel, lastStreamId);
} else {
message = String.format("Connection %s was closed while acquiring new stream.", parentChannel);
}
log.warn(message);
promise.setFailure(new IOException(message));
return;
}
Future<Http2StreamChannel> streamFuture = new Http2StreamChannelBootstrap(parentChannel).handler(streamChannelInitializer).open();
streamFuture.addListener((GenericFutureListener<Future<Http2StreamChannel>>) future -> {
NettyUtils.warnIfNotInEventLoop(parentChannel.eventLoop());
if (!future.isSuccess()) {
promise.setFailure(future.cause());
return;
}
Http2StreamChannel channel = future.getNow();
streamChannels.put(channel.id(), channel);
promise.setSuccess(channel);
if (closeIfIdleTask == null && allowedIdleTimeInMs != null && allowedIdleTimeInMs > 0) {
enableCloseIfIdleTask();
}
});
}, promise);
}
use of io.netty.handler.codec.http2.Http2StreamChannel in project ambry by linkedin.
the class MultiplexedChannelRecord method closeAndExecuteOnChildChannels.
private void closeAndExecuteOnChildChannels(Consumer<Channel> childChannelConsumer) {
NettyUtils.doInEventLoop(parentChannel.eventLoop(), () -> {
if (state == RecordState.CLOSED) {
return;
}
state = RecordState.CLOSED;
// Create a copy of the children, because they may be modified by the consumer.
List<Http2StreamChannel> childrenToClose = new ArrayList<>(streamChannels.values());
for (Channel childChannel : childrenToClose) {
childChannelConsumer.accept(childChannel);
log.debug("fire exception to stream {} {} pipeline: {}. Active: {}", childChannel.hashCode(), childChannel, childChannel.pipeline(), childChannel.isOpen());
}
});
}
use of io.netty.handler.codec.http2.Http2StreamChannel in project netty by netty.
the class Http2FrameClient method main.
public static void main(String[] args) throws Exception {
final EventLoopGroup clientWorkerGroup = new NioEventLoopGroup();
// Configure SSL.
final SslContext sslCtx;
if (SSL) {
final SslProvider provider = SslProvider.isAlpnSupported(SslProvider.OPENSSL) ? SslProvider.OPENSSL : SslProvider.JDK;
sslCtx = SslContextBuilder.forClient().sslProvider(provider).ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE).trustManager(InsecureTrustManagerFactory.INSTANCE).applicationProtocolConfig(new ApplicationProtocolConfig(Protocol.ALPN, SelectorFailureBehavior.NO_ADVERTISE, SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1)).build();
} else {
sslCtx = null;
}
try {
final Bootstrap b = new Bootstrap();
b.group(clientWorkerGroup);
b.channel(NioSocketChannel.class);
b.option(ChannelOption.SO_KEEPALIVE, true);
b.remoteAddress(HOST, PORT);
b.handler(new Http2ClientFrameInitializer(sslCtx));
// Start the client.
final Channel channel = b.connect().syncUninterruptibly().channel();
System.out.println("Connected to [" + HOST + ':' + PORT + ']');
final Http2ClientStreamFrameResponseHandler streamFrameResponseHandler = new Http2ClientStreamFrameResponseHandler();
final Http2StreamChannelBootstrap streamChannelBootstrap = new Http2StreamChannelBootstrap(channel);
final Http2StreamChannel streamChannel = streamChannelBootstrap.open().syncUninterruptibly().getNow();
streamChannel.pipeline().addLast(streamFrameResponseHandler);
// Send request (a HTTP/2 HEADERS frame - with ':method = GET' in this case)
final DefaultHttp2Headers headers = new DefaultHttp2Headers();
headers.method("GET");
headers.path(PATH);
headers.scheme(SSL ? "https" : "http");
final Http2HeadersFrame headersFrame = new DefaultHttp2HeadersFrame(headers, true);
streamChannel.writeAndFlush(headersFrame);
System.out.println("Sent HTTP/2 GET request to " + PATH);
// Wait for the responses (or for the latch to expire), then clean up the connections
if (!streamFrameResponseHandler.responseSuccessfullyCompleted()) {
System.err.println("Did not get HTTP/2 response in expected time.");
}
System.out.println("Finished HTTP/2 request, will close the connection.");
// Wait until the connection is closed.
channel.close().syncUninterruptibly();
} finally {
clientWorkerGroup.shutdownGracefully();
}
}
Aggregations