Search in sources :

Example 16 with Checkpoint

use of com.linkedin.databus.core.Checkpoint 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 17 with Checkpoint

use of com.linkedin.databus.core.Checkpoint in project databus by linkedin.

the class TestResponseProcessors method testTargetSCNOtherException.

@Test
public void testTargetSCNOtherException() throws Exception {
    TestAbstractQueue queue = new TestAbstractQueue();
    TestConnectionStateMessage stateMsg = new TestConnectionStateMessage();
    DefaultHttpResponse httpResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
    httpResponse.setHeader(DatabusHttpHeaders.DATABUS_ERROR_CAUSE_CLASS_HEADER, "Other Dummy Error");
    TestRemoteExceptionHandler remoteExHandler = new TestRemoteExceptionHandler();
    remoteExHandler._exType = ExceptionType.OTHER_EXCEPTION;
    Checkpoint cp = new Checkpoint();
    cp.setConsumptionMode(DbusClientMode.BOOTSTRAP_CATCHUP);
    BootstrapTargetScnHttpResponseProcessor processor = new BootstrapTargetScnHttpResponseProcessor(null, queue, stateMsg, cp, remoteExHandler, null);
    ChannelBuffer buf = getScnResponse();
    HttpChunk httpChunk = new DefaultHttpChunk(buf);
    HttpChunkTrailer httpChunkTrailer = new DefaultHttpChunkTrailer();
    processor.startResponse(httpResponse);
    processor.addChunk(httpChunk);
    processor.addTrailer(httpChunkTrailer);
    processor.finishResponse();
    Assert.assertEquals("Error Handled", false, processor._errorHandled);
    Assert.assertEquals("Processor Response State", AbstractHttpResponseProcessorDecorator.ResponseStatus.CHUNKS_FINISHED, processor._responseStatus);
    Assert.assertEquals("Actor Queue Size", 1, queue.getMessages().size());
    Assert.assertEquals("Expected ConnectionStateMessage", "TestConnectionStateMessage", queue.getMessages().get(0).getClass().getSimpleName());
    TestConnectionStateMessage gotMsg = (TestConnectionStateMessage) (queue.getMessages().get(0));
    Assert.assertEquals("Expected ConnectionStateMessage State", TestConnectionStateMessage.State.TARGETSCN_RESPONSE_ERROR, gotMsg._state);
    Assert.assertEquals("No response", true, (null == stateMsg._cp));
}
Also used : Checkpoint(com.linkedin.databus.core.Checkpoint) DefaultHttpChunkTrailer(org.jboss.netty.handler.codec.http.DefaultHttpChunkTrailer) HttpChunkTrailer(org.jboss.netty.handler.codec.http.HttpChunkTrailer) DefaultHttpChunk(org.jboss.netty.handler.codec.http.DefaultHttpChunk) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) DefaultHttpChunkTrailer(org.jboss.netty.handler.codec.http.DefaultHttpChunkTrailer) ChannelBuffer(org.jboss.netty.buffer.ChannelBuffer) DefaultHttpChunk(org.jboss.netty.handler.codec.http.DefaultHttpChunk) HttpChunk(org.jboss.netty.handler.codec.http.HttpChunk) Test(org.testng.annotations.Test)

Example 18 with Checkpoint

use of com.linkedin.databus.core.Checkpoint in project databus by linkedin.

the class TestResponseProcessors method testStartSCNExceptionAfterStartCase1.

@Test
public void testStartSCNExceptionAfterStartCase1() throws Exception {
    TestAbstractQueue queue = new TestAbstractQueue();
    TestConnectionStateMessage stateMsg = new TestConnectionStateMessage();
    HttpResponse httpResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
    TestRemoteExceptionHandler remoteExHandler = new TestRemoteExceptionHandler();
    Checkpoint cp = new Checkpoint();
    cp.setConsumptionMode(DbusClientMode.BOOTSTRAP_SNAPSHOT);
    BootstrapStartScnHttpResponseProcessor processor = new BootstrapStartScnHttpResponseProcessor(null, queue, stateMsg, cp, remoteExHandler, null);
    ChannelBuffer buf = getScnResponse();
    HttpChunk httpChunk = new DefaultHttpChunk(buf);
    HttpChunkTrailer httpChunkTrailer = new DefaultHttpChunkTrailer();
    processor.startResponse(httpResponse);
    processor.channelException(new Exception("dummy exception"));
    processor.addChunk(httpChunk);
    processor.addTrailer(httpChunkTrailer);
    processor.finishResponse();
    Assert.assertEquals("Error Handled", true, processor._errorHandled);
    Assert.assertEquals("Processor Response State", AbstractHttpResponseProcessorDecorator.ResponseStatus.CHUNKS_FINISHED, processor._responseStatus);
    Assert.assertEquals("Actor Queue Size", 1, queue.getMessages().size());
    Assert.assertEquals("Expected ConnectionStateMessage", "TestConnectionStateMessage", queue.getMessages().get(0).getClass().getSimpleName());
    TestConnectionStateMessage gotMsg = (TestConnectionStateMessage) (queue.getMessages().get(0));
    Assert.assertEquals("Expected ConnectionStateMessage State", TestConnectionStateMessage.State.STARTSCN_RESPONSE_ERROR, gotMsg._state);
    Assert.assertEquals("No response", true, (null == stateMsg._cp));
}
Also used : DefaultHttpChunk(org.jboss.netty.handler.codec.http.DefaultHttpChunk) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(org.jboss.netty.handler.codec.http.HttpResponse) BootstrapDatabaseTooOldException(com.linkedin.databus2.core.container.request.BootstrapDatabaseTooOldException) ChannelBuffer(org.jboss.netty.buffer.ChannelBuffer) Checkpoint(com.linkedin.databus.core.Checkpoint) DefaultHttpChunkTrailer(org.jboss.netty.handler.codec.http.DefaultHttpChunkTrailer) HttpChunkTrailer(org.jboss.netty.handler.codec.http.HttpChunkTrailer) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) DefaultHttpChunkTrailer(org.jboss.netty.handler.codec.http.DefaultHttpChunkTrailer) DefaultHttpChunk(org.jboss.netty.handler.codec.http.DefaultHttpChunk) HttpChunk(org.jboss.netty.handler.codec.http.HttpChunk) Test(org.testng.annotations.Test)

Example 19 with Checkpoint

use of com.linkedin.databus.core.Checkpoint in project databus by linkedin.

the class TestResponseProcessors method testStartSCNExceptionAfterStartCase2.

@Test
public void testStartSCNExceptionAfterStartCase2() throws Exception {
    TestAbstractQueue queue = new TestAbstractQueue();
    TestConnectionStateMessage stateMsg = new TestConnectionStateMessage();
    HttpResponse httpResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
    TestRemoteExceptionHandler remoteExHandler = new TestRemoteExceptionHandler();
    Checkpoint cp = new Checkpoint();
    cp.setConsumptionMode(DbusClientMode.BOOTSTRAP_SNAPSHOT);
    BootstrapStartScnHttpResponseProcessor processor = new BootstrapStartScnHttpResponseProcessor(null, queue, stateMsg, cp, remoteExHandler, null);
    ChannelBuffer buf = getScnResponse();
    HttpChunk httpChunk = new DefaultHttpChunk(buf);
    HttpChunkTrailer httpChunkTrailer = new DefaultHttpChunkTrailer();
    processor.startResponse(httpResponse);
    processor.addChunk(httpChunk);
    processor.channelException(new Exception("dummy exception"));
    processor.addTrailer(httpChunkTrailer);
    processor.finishResponse();
    Assert.assertEquals("Error Handled", true, processor._errorHandled);
    Assert.assertEquals("Processor Response State", AbstractHttpResponseProcessorDecorator.ResponseStatus.CHUNKS_FINISHED, processor._responseStatus);
    Assert.assertEquals("Actor Queue Size", 1, queue.getMessages().size());
    Assert.assertEquals("Expected ConnectionStateMessage", "TestConnectionStateMessage", queue.getMessages().get(0).getClass().getSimpleName());
    TestConnectionStateMessage gotMsg = (TestConnectionStateMessage) (queue.getMessages().get(0));
    Assert.assertEquals("Expected ConnectionStateMessage State", TestConnectionStateMessage.State.STARTSCN_RESPONSE_ERROR, gotMsg._state);
    Assert.assertEquals("No response", true, (null == stateMsg._cp));
}
Also used : DefaultHttpChunk(org.jboss.netty.handler.codec.http.DefaultHttpChunk) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(org.jboss.netty.handler.codec.http.HttpResponse) BootstrapDatabaseTooOldException(com.linkedin.databus2.core.container.request.BootstrapDatabaseTooOldException) ChannelBuffer(org.jboss.netty.buffer.ChannelBuffer) Checkpoint(com.linkedin.databus.core.Checkpoint) DefaultHttpChunkTrailer(org.jboss.netty.handler.codec.http.DefaultHttpChunkTrailer) HttpChunkTrailer(org.jboss.netty.handler.codec.http.HttpChunkTrailer) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) DefaultHttpChunkTrailer(org.jboss.netty.handler.codec.http.DefaultHttpChunkTrailer) DefaultHttpChunk(org.jboss.netty.handler.codec.http.DefaultHttpChunk) HttpChunk(org.jboss.netty.handler.codec.http.HttpChunk) Test(org.testng.annotations.Test)

Example 20 with Checkpoint

use of com.linkedin.databus.core.Checkpoint in project databus by linkedin.

the class TestResponseProcessors method testStartSCNHappyPathNonChunked.

@Test
public void testStartSCNHappyPathNonChunked() throws Exception {
    TestAbstractQueue queue = new TestAbstractQueue();
    TestConnectionStateMessage stateMsg = new TestConnectionStateMessage();
    DefaultHttpResponse httpResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
    TestRemoteExceptionHandler remoteExHandler = new TestRemoteExceptionHandler();
    Checkpoint cp = new Checkpoint();
    cp.setConsumptionMode(DbusClientMode.BOOTSTRAP_SNAPSHOT);
    BootstrapStartScnHttpResponseProcessor processor = new BootstrapStartScnHttpResponseProcessor(null, queue, stateMsg, cp, remoteExHandler, null);
    ChannelBuffer buf = getScnResponse();
    httpResponse.setContent(buf);
    httpResponse.setHeader(HttpHeaders.Names.CONTENT_LENGTH, "1000");
    processor.startResponse(httpResponse);
    processor.finishResponse();
    Assert.assertEquals("Error Handled", false, processor._errorHandled);
    Assert.assertEquals("Processor Response State", AbstractHttpResponseProcessorDecorator.ResponseStatus.CHUNKS_FINISHED, processor._responseStatus);
    Assert.assertEquals("Actor Queue Size", 1, queue.getMessages().size());
    Assert.assertEquals("Expected ConnectionStateMessage", "TestConnectionStateMessage", queue.getMessages().get(0).getClass().getSimpleName());
    TestConnectionStateMessage gotMsg = (TestConnectionStateMessage) (queue.getMessages().get(0));
    System.out.println("Long Max is :" + Long.MAX_VALUE);
    Assert.assertEquals("Expected ConnectionStateMessage State", TestConnectionStateMessage.State.STARTSCN_RESPONSE_SUCCESS, gotMsg._state);
    Assert.assertEquals("StartSCN Response Id Check", new Long(5678912), cp.getBootstrapStartScn());
}
Also used : Checkpoint(com.linkedin.databus.core.Checkpoint) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) ChannelBuffer(org.jboss.netty.buffer.ChannelBuffer) Test(org.testng.annotations.Test)

Aggregations

Checkpoint (com.linkedin.databus.core.Checkpoint)139 Test (org.testng.annotations.Test)88 ArrayList (java.util.ArrayList)46 RegisterResponseEntry (com.linkedin.databus2.core.container.request.RegisterResponseEntry)42 HashMap (java.util.HashMap)42 List (java.util.List)42 IdNamePair (com.linkedin.databus.core.util.IdNamePair)34 DefaultHttpResponse (org.jboss.netty.handler.codec.http.DefaultHttpResponse)29 ChannelBuffer (org.jboss.netty.buffer.ChannelBuffer)27 DefaultHttpChunk (org.jboss.netty.handler.codec.http.DefaultHttpChunk)25 HttpResponse (org.jboss.netty.handler.codec.http.HttpResponse)23 HttpChunk (org.jboss.netty.handler.codec.http.HttpChunk)22 BootstrapDatabaseTooOldException (com.linkedin.databus2.core.container.request.BootstrapDatabaseTooOldException)20 DefaultHttpChunkTrailer (org.jboss.netty.handler.codec.http.DefaultHttpChunkTrailer)16 HttpChunkTrailer (org.jboss.netty.handler.codec.http.HttpChunkTrailer)16 ServerInfo (com.linkedin.databus.client.pub.ServerInfo)15 DatabusSubscription (com.linkedin.databus.core.data_model.DatabusSubscription)15 IOException (java.io.IOException)15 Logger (org.apache.log4j.Logger)14 InetSocketAddress (java.net.InetSocketAddress)13