package org.jboss.resteasy.test;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.HttpHeaders.Values;
import org.jboss.resteasy.plugins.server.netty.NettyContainer;
import org.jboss.resteasy.util.HttpHeaderNames;
import org.junit.*;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation.Builder;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.*;
import java.util.concurrent.CountDownLatch;
import static org.jboss.resteasy.test.TestPortProvider.generateURL;
@Ignore("[RESTEASY-1490] RESTEASY1323Test intermittent failures")
public class RESTEASY1323Test
{
static String BASE_URI = generateURL("");
static final int REQUEST_TIMEOUT = 6000;
@BeforeClass
public static void setupSuite() throws Exception
{
NettyContainer.start().getRegistry().addSingletonResource(new AsyncJaxrsResource());
}
@AfterClass
public static void tearDownSuite() throws Exception
{
NettyContainer.stop();
}
@Before
public void setupTest() throws Exception
{
}
@After
public void tearDownTest() throws Exception
{
}
@Test(timeout=REQUEST_TIMEOUT*10)
public void testAsyncKeepConnection() throws Exception
{
callAsyncTwiceWithKeepAlive();
}
// use netty to better monitor channel connection.
private void callAsyncTwiceWithKeepAlive() throws InterruptedException, MalformedURLException {
final CountDownLatch responseLatch = new CountDownLatch(2);
// Configure the client.
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new HttpClientCodec());
ch.pipeline().addLast(new HttpObjectAggregator(4096));
ch.pipeline().addLast(new SimpleChannelInboundHandler<FullHttpResponse>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpResponse msg) {
System.out.println("HTTP response from resteasy: "+msg);
responseLatch.countDown();
}
});
}
});
// first request;
URL url = new URL(BASE_URI+"/jaxrs");
// Make the connection attempt.
final Channel ch = b.connect(url.getHost(), url.getPort()).sync().channel();
// Prepare the HTTP request.
HttpRequest request = new DefaultFullHttpRequest(
HttpVersion.HTTP_1_1, HttpMethod.GET, url.getFile());
request.headers().set(HttpHeaderNames.HOST, url.getHost());
request.headers().set(HttpHeaderNames.CONNECTION, "keep-alive");
// Send the HTTP request.
ch.writeAndFlush(request).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
// 2nd request
URL url = new URL(BASE_URI+"/jaxrs/empty");
HttpRequest request2 = new DefaultFullHttpRequest(
HttpVersion.HTTP_1_1, HttpMethod.GET, url.getFile());
request2.headers().set(HttpHeaderNames.HOST, url.getHost());
request2.headers().set(HttpHeaderNames.CONNECTION, "keep-alive");
ch.writeAndFlush(request2);
}
});
responseLatch.await();
} finally {
// Shut down executor threads to exit.
group.shutdownGracefully().await();
}
}
@Test(timeout=REQUEST_TIMEOUT*5)
public void testAsyncCloseConnection() throws Exception
{
callAsyncWithCloseConnection();
}
// use netty to better monitor channel connection.
private void callAsyncWithCloseConnection() throws InterruptedException, MalformedURLException {
final CountDownLatch responseLatch = new CountDownLatch(2);
// Configure the client.
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new HttpClientCodec());
ch.pipeline().addLast(new HttpObjectAggregator(4096));
ch.pipeline().addLast(new SimpleChannelInboundHandler<FullHttpResponse>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpResponse msg) {
System.out.println("HTTP response from resteasy: "+msg);
responseLatch.countDown();
}
});
}
});
// first request;
URL url = new URL(BASE_URI+"/jaxrs");
// Make the connection attempt.
final Channel ch = b.connect(url.getHost(), url.getPort()).sync().channel();
// Prepare the HTTP request.
HttpRequest request = new DefaultFullHttpRequest(
HttpVersion.HTTP_1_1, HttpMethod.GET, url.getFile());
request.headers().set(HttpHeaderNames.HOST, url.getHost());
request.headers().set(HttpHeaderNames.CONNECTION, "close");
// Send the HTTP request.
ch.writeAndFlush(request);
// waiting for server close connection after idle.
ch.closeFuture().await();
} finally {
// Shut down executor threads to exit.
group.shutdownGracefully().await();
}
}
}