Search in sources :

Example 16 with Channel

use of org.jboss.netty.channel.Channel in project databus by linkedin.

the class TestHttpResponseProcessor method testReadTimeoutChunking.

@Test
public void testReadTimeoutChunking() throws DatabusException {
    final Logger log = Logger.getLogger("GenericHttpResponseHandler.testReadTimeoutChunking");
    log.info("start");
    final GenericHttpResponseHandler responseHandler = new GenericHttpResponseHandler(KeepAliveType.KEEP_ALIVE);
    responseHandler.getLog().setLevel(_logLevel);
    TestHttpResponseProcessor respProcessor = new TestHttpResponseProcessor(log);
    TestConnectListener connectListener = new TestConnectListener(log);
    TestSendRequestListener requestListener = new TestSendRequestListener(log);
    TestCloseListener closeListener = new TestCloseListener(log);
    responseHandler.setConnectionListener(connectListener);
    Channel channel = createClientBootstrap(responseHandler);
    SocketAddress clientAddr = channel.getLocalAddress();
    try {
        setListeners(responseHandler, respProcessor, requestListener, closeListener);
        channel.write(new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/test"));
        //It seems that there is a race condition between the writeFuture succeeding
        //and the writeComplete message getting to the handler. Make sure that the
        //writeComplete has got to the handler before we do anything else with
        //the channel.
        final GenericHttpResponseHandler handler = getResponseHandler(channel);
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return handler._messageState.hasSentRequest();
            }
        }, "request sent", 1000, log);
        HttpResponse resp = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
        resp.setHeader(HttpHeaders.Names.TRANSFER_ENCODING, HttpHeaders.Values.CHUNKED);
        sendServerResponse(clientAddr, resp, 1000);
        HttpChunk chunk1 = new DefaultHttpChunk(ChannelBuffers.wrappedBuffer("chunk1".getBytes(Charset.defaultCharset())));
        sendServerResponse(clientAddr, chunk1, 1000);
        final List<String> callbacks = respProcessor.getCallbacks();
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return 2 == callbacks.size();
            }
        }, "waiting for response processed", 1000, null);
        Assert.assertEquals(callbacks.get(0), "startResponse");
        Assert.assertEquals(callbacks.get(1), "addChunk");
        Channels.fireExceptionCaught(channel, new ReadTimeoutException());
        channel.close();
        final List<String> closeCallbacks = closeListener.getCallbacks();
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return 3 == callbacks.size() && 1 == closeCallbacks.size();
            }
        }, "waiting for response processed", 1000, null);
        final List<String> connectCallbacks = connectListener.getCallbacks();
        final List<String> requestCallbacks = requestListener.getCallbacks();
        Assert.assertEquals(callbacks.get(0), "startResponse");
        Assert.assertEquals(callbacks.get(1), "addChunk");
        Assert.assertTrue(callbacks.get(2).startsWith("channelException"));
        //Assert.assertEquals(callbacks.get(3), "channelClosed"); // no more channelClosed after channel Exception
        //make sure that no new callbacks have showed up
        stateSanityCheck(connectCallbacks, requestCallbacks, callbacks, closeCallbacks);
        Assert.assertEquals(callbacks.size(), 3);
    } finally {
        channel.close();
        log.info("end");
    }
}
Also used : ConditionCheck(com.linkedin.databus2.test.ConditionCheck) DefaultHttpChunk(org.jboss.netty.handler.codec.http.DefaultHttpChunk) ReadTimeoutException(org.jboss.netty.handler.timeout.ReadTimeoutException) Channel(org.jboss.netty.channel.Channel) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(org.jboss.netty.handler.codec.http.HttpResponse) Logger(org.apache.log4j.Logger) DefaultHttpRequest(org.jboss.netty.handler.codec.http.DefaultHttpRequest) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) SocketAddress(java.net.SocketAddress) InetSocketAddress(java.net.InetSocketAddress) DefaultHttpChunk(org.jboss.netty.handler.codec.http.DefaultHttpChunk) HttpChunk(org.jboss.netty.handler.codec.http.HttpChunk) Test(org.testng.annotations.Test)

Example 17 with Channel

use of org.jboss.netty.channel.Channel in project databus by linkedin.

the class TestHttpResponseProcessor method testReadTimeoutNoChunking.

@Test
public void testReadTimeoutNoChunking() throws InterruptedException, DatabusException {
    final Logger log = Logger.getLogger("GenericHttpResponseHandler.testReadTimeoutNoChunking");
    final GenericHttpResponseHandler responseHandler = new GenericHttpResponseHandler(KeepAliveType.KEEP_ALIVE);
    responseHandler.getLog().setLevel(_logLevel);
    log.info("start");
    log.setLevel(_logLevel);
    TestHttpResponseProcessor respProcessor = new TestHttpResponseProcessor(log);
    TestConnectListener connectListener = new TestConnectListener(log);
    TestSendRequestListener requestListener = new TestSendRequestListener(log);
    TestCloseListener closeListener = new TestCloseListener(log);
    responseHandler.setConnectionListener(connectListener);
    Channel channel = createClientBootstrap(responseHandler);
    try {
        setListeners(responseHandler, respProcessor, requestListener, closeListener);
        ChannelFuture writeFuture = channel.write(new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/test"));
        Assert.assertTrue(writeFuture.await(1000));
        //It seems that there is a race condition between the writeFuture succeeding
        //and the writeComplete message getting to the handler. Make sure that the
        //writeComplete has got to the handler before we do anything else with
        //the channel.
        final GenericHttpResponseHandler handler = getResponseHandler(channel);
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return handler._messageState.hasSentRequest();
            }
        }, "request sent", 1000, log);
        Channels.fireExceptionCaught(channel, new ReadTimeoutException());
        channel.close();
        final List<String> callbacks = respProcessor.getCallbacks();
        final List<String> closeCallbacks = closeListener.getCallbacks();
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                log.debug("# callbacks:" + callbacks + ";expecting 1");
                return 1 == callbacks.size() && 1 == closeCallbacks.size();
            }
        }, "waiting for response processed", 5000, null);
        final List<String> connectCallbacks = connectListener.getCallbacks();
        final List<String> requestCallbacks = requestListener.getCallbacks();
        stateSanityCheck(connectCallbacks, requestCallbacks, callbacks, closeCallbacks);
        Assert.assertTrue(callbacks.get(0).startsWith("channelException"));
        //Assert.assertEquals(callbacks.get(1), "channelClosed");  // we don't get channelClosed after exception anymore
        //make sure that no new callbacks have showed up
        Assert.assertEquals(callbacks.size(), 1);
    } finally {
        channel.close();
        log.info("end");
    }
}
Also used : ChannelFuture(org.jboss.netty.channel.ChannelFuture) ConditionCheck(com.linkedin.databus2.test.ConditionCheck) ReadTimeoutException(org.jboss.netty.handler.timeout.ReadTimeoutException) Channel(org.jboss.netty.channel.Channel) Logger(org.apache.log4j.Logger) DefaultHttpRequest(org.jboss.netty.handler.codec.http.DefaultHttpRequest) Test(org.testng.annotations.Test)

Example 18 with Channel

use of org.jboss.netty.channel.Channel in project databus by linkedin.

the class TestNettyHttpDatabusBootstrapConnection method getServerChannelForClientConn.

private Channel getServerChannelForClientConn(final AbstractNettyHttpConnection conn) {
    Channel channel = conn._channel;
    SocketAddress clientAddr = channel.getLocalAddress();
    return _dummyServer.getChildChannel(clientAddr);
}
Also used : ChunkedBodyReadableByteChannel(com.linkedin.databus.client.ChunkedBodyReadableByteChannel) Channel(org.jboss.netty.channel.Channel) SocketAddress(java.net.SocketAddress) InetSocketAddress(java.net.InetSocketAddress)

Example 19 with Channel

use of org.jboss.netty.channel.Channel in project databus by linkedin.

the class TestNettyHttpDatabusBootstrapConnection method testServerBootstrapDisconnect.

@Test
public /**
   * This is a unit test for DDSDBUS-3537. There is a lag between a network channel disconnect and the
   * state change in AbstractNettyHttpConnection. This can cause a race condition in various requestXXX objects which
   * check the state of the connection using the network channel. As a result, they may attempt to reconnect while
   * AbstractNettyHttpConnection is still in CONNECTED state which causes an error for an incorrect transition
   * CONNECTED -> CONNECTING.
   *
   *  The test simulates the above condition by injecting a handler in the client pipeline which artificially holds up
   *  the channelClosed message. As a result we can inject a request while the netty channel is disconnected but the
   *  AbstractNettyHttpConnection object has not detected this yet.
   */
void testServerBootstrapDisconnect() throws Exception {
    final Logger log = Logger.getLogger("TestNettyHttpDatabusBootstrapConnection.testServerBootstrapDisconnect");
    log.info("starting");
    log.info("setup the client");
    TestingConnectionCallback callback = TestingConnectionCallback.createAndStart("testServerSourcesDisconnect");
    DummyRemoteExceptionHandler remoteExceptionHandler = new DummyRemoteExceptionHandler();
    final NettyHttpDatabusBootstrapConnection conn = (NettyHttpDatabusBootstrapConnection) CONN_FACTORY.createConnection(BOOTSTRAP_SERVER_INFO, callback, remoteExceptionHandler);
    try {
        log.info("initial setup");
        final List<String> sourceNamesList = Arrays.asList(SOURCE1_NAME);
        final Checkpoint cp = Checkpoint.createOnlineConsumptionCheckpoint(0);
        BootstrapCheckpointHandler cpHandler = new BootstrapCheckpointHandler(sourceNamesList);
        cpHandler.createInitialBootstrapCheckpoint(cp, 0L);
        final DummyDatabusBootstrapConnectionStateMessage bstCallback = new DummyDatabusBootstrapConnectionStateMessage(log);
        log.info("process a normal startSCN which should establish the connection");
        sendStartScnHappyPath(conn, cp, bstCallback, SOURCE1_NAME, 100L, log);
        Assert.assertTrue(conn.isConnected());
        //wait for the response
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return null != bstCallback.getCheckpoint();
            }
        }, "wait for /startSCN response", 100, log);
        log.info("verify /startSCN response");
        final Checkpoint startScnCp = bstCallback.getCheckpoint();
        Assert.assertNotNull(startScnCp);
        Assert.assertEquals(100L, startScnCp.getBootstrapStartScn().longValue());
        log.info("instrument the client pipeline so that we can intercept and delay the channelClosed message");
        final Semaphore passMessage = new Semaphore(1);
        final CountDownLatch closeSent = new CountDownLatch(1);
        passMessage.acquire();
        conn._channel.getPipeline().addBefore("handler", "closeChannelDelay", new SimpleChannelHandler() {

            @Override
            public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
                closeSent.countDown();
                passMessage.acquire();
                try {
                    super.channelClosed(ctx, e);
                } finally {
                    passMessage.release();
                }
            }
        });
        final Channel serverChannel = getServerChannelForClientConn(conn);
        Thread asyncChannelClose = new Thread(new Runnable() {

            @Override
            public void run() {
                log.info("closing server channel");
                serverChannel.close();
                log.info("server channel: closed");
                closeSent.countDown();
            }
        }, "asyncChannelCloseThread");
        asyncChannelClose.setDaemon(true);
        Thread asyncBootstrapReq = new Thread(new Runnable() {

            @Override
            public void run() {
                conn.requestStream("1", null, 10000, startScnCp, bstCallback);
            }
        }, "asyncBootstrapReqThread");
        asyncBootstrapReq.setDaemon(true);
        log.info("simultaneously closing connection and sending /bootstrap request");
        bstCallback.reset();
        asyncChannelClose.start();
        Assert.assertTrue(closeSent.await(1000, TimeUnit.MILLISECONDS));
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return !conn._channel.isConnected();
            }
        }, "waiting for disconnect on the client side", 1000, log);
        Assert.assertEquals(AbstractNettyHttpConnection.State.CONNECTED, conn.getNetworkState());
        log.info("asynchronously sending /bootstrap");
        asyncBootstrapReq.start();
        log.info("letting channelClose get through");
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return bstCallback.isStreamRequestError();
            }
        }, "wait for streamRequestError callback", 1000, log);
        passMessage.release();
        log.info("finished");
    } finally {
        conn.close();
        callback.shutdown();
        log.info("cleaned");
    }
}
Also used : ConditionCheck(com.linkedin.databus2.test.ConditionCheck) ChunkedBodyReadableByteChannel(com.linkedin.databus.client.ChunkedBodyReadableByteChannel) Channel(org.jboss.netty.channel.Channel) ChannelHandlerContext(org.jboss.netty.channel.ChannelHandlerContext) Semaphore(java.util.concurrent.Semaphore) Logger(org.apache.log4j.Logger) CountDownLatch(java.util.concurrent.CountDownLatch) BootstrapCheckpointHandler(com.linkedin.databus.core.BootstrapCheckpointHandler) InvalidConfigException(com.linkedin.databus.core.util.InvalidConfigException) JsonGenerationException(org.codehaus.jackson.JsonGenerationException) JsonMappingException(org.codehaus.jackson.map.JsonMappingException) IOException(java.io.IOException) Checkpoint(com.linkedin.databus.core.Checkpoint) ChannelStateEvent(org.jboss.netty.channel.ChannelStateEvent) SimpleChannelHandler(org.jboss.netty.channel.SimpleChannelHandler) Test(org.testng.annotations.Test)

Example 20 with Channel

use of org.jboss.netty.channel.Channel in project databus by linkedin.

the class DummyRemoteExceptionHandler method runServerStreamReadTimeoutIteration.

private void runServerStreamReadTimeoutIteration(final Logger log, TestingConnectionCallback callback, DummyRemoteExceptionHandler remoteExceptionHandler, final NettyHttpDatabusRelayConnection conn) throws JsonGenerationException, JsonMappingException, IOException, ScnNotFoundException, OffsetNotFoundException {
    //connect to server and send /sources
    TestResponseProcessors.TestConnectionStateMessage msg = new TestResponseProcessors.TestConnectionStateMessage();
    conn.requestSources(msg);
    waitForServerConnection(conn, log);
    //introspect connection to server
    Channel channel = conn._channel;
    SocketAddress clientAddr = channel.getLocalAddress();
    Channel serverChannel = _dummyServer.getChildChannel(clientAddr);
    ChannelPipeline serverPipeline = serverChannel.getPipeline();
    SimpleObjectCaptureHandler objCapture = (SimpleObjectCaptureHandler) serverPipeline.get("3");
    //verify server gets the /source request
    HttpResponse sourcesResp = runHappyPathSources(log, callback, remoteExceptionHandler, clientAddr, objCapture);
    //send /register
    runHappyPathRegister(log, callback, remoteExceptionHandler, conn, msg, clientAddr, objCapture, sourcesResp);
    //send partial /stream
    callback.clearLastMsg();
    objCapture.clear();
    Checkpoint cp = new Checkpoint();
    cp.setFlexible();
    CheckpointMult cpm = new CheckpointMult();
    cpm.addCheckpoint(PhysicalPartition.ANY_PHYSICAL_PARTITION, cp);
    conn.requestStream("1", null, 1000, cpm, null, msg);
    //////// verify server gets the /stream request
    HttpRequest msgReq = captureRequest(objCapture);
    Assert.assertTrue(msgReq.getUri().startsWith("/stream"));
    //Trigger a read timeout
    TestUtil.sleep(DEFAULT_READ_TIMEOUT_MS + 100);
    waitForCallback(callback, TestResponseProcessors.TestConnectionStateMessage.State.STREAM_RESPONSE_ERROR, log);
    Assert.assertNull(remoteExceptionHandler.getLastException());
    Assert.assertEquals(1, callback.getAllMsgs().size());
    callback.clearLastMsg();
    objCapture.clear();
}
Also used : HttpRequest(org.jboss.netty.handler.codec.http.HttpRequest) Checkpoint(com.linkedin.databus.core.Checkpoint) SimpleObjectCaptureHandler(com.linkedin.databus2.test.container.SimpleObjectCaptureHandler) CheckpointMult(com.linkedin.databus.core.CheckpointMult) Channel(org.jboss.netty.channel.Channel) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(org.jboss.netty.handler.codec.http.HttpResponse) SocketAddress(java.net.SocketAddress) InetSocketAddress(java.net.InetSocketAddress) ChannelPipeline(org.jboss.netty.channel.ChannelPipeline)

Aggregations

Channel (org.jboss.netty.channel.Channel)187 InetSocketAddress (java.net.InetSocketAddress)57 Test (org.junit.Test)52 HttpRequest (org.jboss.netty.handler.codec.http.HttpRequest)40 DefaultHttpRequest (org.jboss.netty.handler.codec.http.DefaultHttpRequest)37 DefaultHttpResponse (org.jboss.netty.handler.codec.http.DefaultHttpResponse)34 HttpResponse (org.jboss.netty.handler.codec.http.HttpResponse)34 SocketAddress (java.net.SocketAddress)33 ChannelFuture (org.jboss.netty.channel.ChannelFuture)33 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)30 ChannelPipeline (org.jboss.netty.channel.ChannelPipeline)27 Test (org.testng.annotations.Test)23 ConditionCheck (com.linkedin.databus2.test.ConditionCheck)22 IOException (java.io.IOException)21 SimpleObjectCaptureHandler (com.linkedin.databus2.test.container.SimpleObjectCaptureHandler)19 Logger (org.apache.log4j.Logger)19 ChannelBuffer (org.jboss.netty.buffer.ChannelBuffer)17 DefaultHttpChunk (org.jboss.netty.handler.codec.http.DefaultHttpChunk)16 HttpChunk (org.jboss.netty.handler.codec.http.HttpChunk)16 ArrayList (java.util.ArrayList)14