Search in sources :

Example 6 with DefaultHttpChunk

use of org.jboss.netty.handler.codec.http.DefaultHttpChunk in project databus by linkedin.

the class DummySuccessfulErrorCountingConsumer method testRelayFailoverPartialWindow2.

@Test
public /**
	 * R1 EVB Boundaries ------------------------------------------------------------------------------
	 *                   ^                        ^                          ^                    ^
	 *                   0                        30                         60                   90
	 * R2 EVB Boundaries --------------------------------------------------------------------------------
	 *                   ^               ^                   ^               ^            ^
	 *                   0               20                  40              60           80
	 *
	 * R3 EVB Boundaries --------------------------------------------------------------------------------
	 *                   ^      ^        ^         ^         ^       ^       ^      ^     ^        ^
	 *                   0      10       20        30        40      50      60     70    80       90
	 *
	 *
     *  Client switches from R1 to R2 on server close and from R2 to R3 on timeout while in the middle of the windows.
	 *
	 *  Switch from R1 -> R2 happens when windowScn = 30 and WindowOffset = 8th event
	 *  Switch from R2 -> R3 happens when windowScn = 40 and windowOffset = 5th event
	 *
	 * @throws Exception
	 */
void testRelayFailoverPartialWindow2() throws Exception {
    final Logger log = Logger.getLogger("TestDatabusHttpClient.testRelayFailoverPartialWindow2");
    //log.setLevel(Level.DEBUG);
    final int eventsNum = 200;
    DbusEventInfo[] eventInfos = createSampleSchema1Events(eventsNum);
    //simulate relay buffers
    DbusEventBuffer[] relayBuffer = new DbusEventBuffer[RELAY_PORT.length];
    List<List<Integer>> eventOfs = new ArrayList<List<Integer>>(3);
    List<List<DbusEventKey>> eventKeys = new ArrayList<List<DbusEventKey>>(3);
    for (int i = 0; i < RELAY_PORT.length; ++i) {
        relayBuffer[i] = new DbusEventBuffer(_bufCfg);
        relayBuffer[i].start(0);
        WriteEventsResult wrRes = writeEventsToBuffer(relayBuffer[i], eventInfos, (RELAY_PORT.length - i) * 10);
        List<Integer> ofs = wrRes.getOffsets();
        eventOfs.add(ofs);
        eventKeys.add(wrRes.getKeys());
    }
    List<DbusEventKey> key = eventKeys.get(0);
    for (int i = 1; i < RELAY_PORT.length; ++i) {
        assertEquals(key, eventKeys.get(i));
        key = eventKeys.get(i);
    }
    //figure out an event offset inside a window
    int resp1EnfOfs = eventOfs.get(0).get(8);
    //create client
    _stdClientCfgBuilder.getContainer().setReadTimeoutMs(DEFAULT_READ_TIMEOUT_MS);
    final DatabusHttpClientImpl client = new DatabusHttpClientImpl(_stdClientCfgBuilder.build());
    final TestConsumer consumer = new TestConsumer();
    client.registerDatabusStreamListener(consumer, null, SOURCE1_NAME);
    client.start();
    try {
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return client._relayConnections.size() == 1;
            }
        }, "sources connection present", 100, log);
        final DatabusSourcesConnection clientConn = client._relayConnections.get(0);
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return null != clientConn.getRelayPullThread().getLastOpenConnection();
            }
        }, "relay connection present", 100, log);
        final NettyHttpDatabusRelayConnection relayConn = (NettyHttpDatabusRelayConnection) clientConn.getRelayPullThread().getLastOpenConnection();
        final NettyHttpDatabusRelayConnectionInspector relayConnInsp = new NettyHttpDatabusRelayConnectionInspector(relayConn);
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return null != relayConnInsp.getChannel() && relayConnInsp.getChannel().isConnected();
            }
        }, "client connected", 200, log);
        //figure out the connection to the relay
        Channel clientChannel = relayConnInsp.getChannel();
        InetSocketAddress relayAddr = (InetSocketAddress) clientChannel.getRemoteAddress();
        SocketAddress clientAddr = clientChannel.getLocalAddress();
        int relayPort = relayAddr.getPort();
        log.info("relay selected: " + relayPort);
        SimpleTestServerConnection relay = null;
        for (int i = 0; i < RELAY_PORT.length; ++i) {
            if (relayPort == RELAY_PORT[i])
                relay = _dummyServer[i];
        }
        assertTrue(null != relay);
        final SocketAddress testClientAddr = clientAddr;
        final SimpleTestServerConnection testRelay = relay;
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return null != testRelay.getChildChannel(testClientAddr);
            }
        }, "relay detects new connection", 1000, log);
        Channel serverChannel = relay.getChildChannel(clientAddr);
        assertTrue(null != serverChannel);
        ChannelPipeline serverPipeline = serverChannel.getPipeline();
        SimpleObjectCaptureHandler objCapture = (SimpleObjectCaptureHandler) serverPipeline.get("3");
        //process the /sources request
        NettyTestUtils.waitForHttpRequest(objCapture, SOURCES_REQUEST_REGEX, 1000);
        objCapture.clear();
        //send back the /sources response
        HttpResponse sourcesResp = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
        sourcesResp.setHeader(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
        sourcesResp.setHeader(HttpHeaders.Names.TRANSFER_ENCODING, HttpHeaders.Values.CHUNKED);
        HttpChunk body = new DefaultHttpChunk(ChannelBuffers.wrappedBuffer(("[{\"id\":1,\"name\":\"" + SOURCE1_NAME + "\"}]").getBytes(Charset.defaultCharset())));
        NettyTestUtils.sendServerResponses(relay, clientAddr, sourcesResp, body);
        //make sure the client processes the response correctly
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                String idListString = clientConn.getRelayPullThread()._currentState.getSourcesIdListString();
                return "1".equals(idListString);
            }
        }, "client processes /sources response", 100, log);
        //process the /register request
        NettyTestUtils.waitForHttpRequest(objCapture, "/register.*", 1000);
        objCapture.clear();
        //send back the /register response
        RegisterResponseEntry entry = new RegisterResponseEntry(1L, (short) 1, SOURCE1_SCHEMA_STR);
        String responseStr = NettyTestUtils.generateRegisterResponse(entry);
        body = new DefaultHttpChunk(ChannelBuffers.wrappedBuffer(responseStr.getBytes(Charset.defaultCharset())));
        NettyTestUtils.sendServerResponses(relay, clientAddr, sourcesResp, body);
        //make sure the client processes the response correctly
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                DispatcherState dispState = clientConn.getRelayDispatcher().getDispatcherState();
                return null != dispState.getSchemaMap() && 1 == dispState.getSchemaMap().size();
            }
        }, "client processes /register response", 100, log);
        //process /stream call and return a partial window
        NettyTestUtils.waitForHttpRequest(objCapture, "/stream.*", 1000);
        objCapture.clear();
        //send back the /stream response
        final DbusEventsStatisticsCollector stats = new DbusEventsStatisticsCollector(1, "test1", true, false, null);
        Checkpoint cp = Checkpoint.createFlexibleCheckpoint();
        ChannelBuffer streamRes = NettyTestUtils.streamToChannelBuffer(relayBuffer[0], cp, resp1EnfOfs, stats);
        HttpResponse streamResp = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
        streamResp.setHeader(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
        streamResp.setHeader(HttpHeaders.Names.TRANSFER_ENCODING, HttpHeaders.Values.CHUNKED);
        NettyTestUtils.sendServerResponses(relay, clientAddr, streamResp, new DefaultHttpChunk(streamRes));
        //make sure the client processes the response correctly
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                log.debug("LastWritten SCN:" + clientConn.getDataEventsBuffer().lastWrittenScn());
                return clientConn.getDataEventsBuffer().lastWrittenScn() == 30;
            }
        }, "client receives /stream response", 1100, log);
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                log.error("events num=" + consumer.getEventNum());
                return stats.getTotalStats().getNumDataEvents() == consumer.getEventNum();
            }
        }, "client processes /stream response", 110000, log);
        assertEquals(-1, consumer.getRollbackScn());
        int rollbackNum = 0;
        assertEquals(stats.getTotalStats().getNumSysEvents() + 1 + rollbackNum, consumer.getWinNum());
        List<DbusEventKey> expKeys = eventKeys.get(0).subList(0, (int) stats.getTotalStats().getNumDataEvents());
        List<Long> expSeqs = new ArrayList<Long>();
        for (int i = 0; i < stats.getTotalStats().getNumDataEvents(); i++) expSeqs.add(30L);
        long numEvents = stats.getTotalStats().getNumDataEvents();
        assertEquals("Keys", expKeys, consumer.getKeys());
        assertEquals("Sequences", expSeqs, consumer.getSequences());
        assertEquals("Keys", expKeys, consumer.getKeys());
        assertEquals("Sequences", expSeqs, consumer.getSequences());
        numEvents = stats.getTotalStats().getNumDataEvents();
        //now kill the relay and wait for a failover
        serverChannel.close();
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return null != relayConnInsp.getChannel() && !relayConnInsp.getChannel().isConnected();
            }
        }, "client disconnected", 200, log);
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return clientConn.getRelayPullThread().getLastOpenConnection() != relayConn;
            }
        }, "new netty connection", 200, log);
        /////////// FAKING CONNECTION TO NEW RELAY
        final NettyHttpDatabusRelayConnection newRelayConn = (NettyHttpDatabusRelayConnection) clientConn.getRelayPullThread().getLastOpenConnection();
        final NettyHttpDatabusRelayConnectionInspector newRelayConnInsp = new NettyHttpDatabusRelayConnectionInspector(newRelayConn);
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return null != newRelayConnInsp.getChannel() && newRelayConnInsp.getChannel().isConnected();
            }
        }, "client connected to new relay", 200, log);
        //figure out the connection to the relay
        clientChannel = newRelayConnInsp.getChannel();
        relayAddr = (InetSocketAddress) clientChannel.getRemoteAddress();
        clientAddr = clientChannel.getLocalAddress();
        relayPort = relayAddr.getPort();
        log.info("new relay selected: " + relayPort);
        relay = null;
        int relayIdx = 0;
        for (; relayIdx < RELAY_PORT.length; ++relayIdx) {
            if (relayPort == RELAY_PORT[relayIdx])
                relay = _dummyServer[relayIdx];
        }
        assertTrue(null != relay);
        serverChannel = relay.getChildChannel(clientAddr);
        assertTrue(null != serverChannel);
        serverPipeline = serverChannel.getPipeline();
        objCapture = (SimpleObjectCaptureHandler) serverPipeline.get("3");
        //process the /sources request
        NettyTestUtils.waitForHttpRequest(objCapture, SOURCES_REQUEST_REGEX, 1000);
        objCapture.clear();
        //send back the /sources response
        body = new DefaultHttpChunk(ChannelBuffers.wrappedBuffer(("[{\"id\":1,\"name\":\"" + SOURCE1_NAME + "\"}]").getBytes(Charset.defaultCharset())));
        NettyTestUtils.sendServerResponses(relay, clientAddr, sourcesResp, body);
        //make sure the client processes the response correctly
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                String idListString = clientConn.getRelayPullThread()._currentState.getSourcesIdListString();
                return "1".equals(idListString);
            }
        }, "client processes /sources response", 100, log);
        //process the /register request
        NettyTestUtils.waitForHttpRequest(objCapture, "/register.*", 1000);
        objCapture.clear();
        //send back the /register response
        body = new DefaultHttpChunk(ChannelBuffers.wrappedBuffer(responseStr.getBytes(Charset.defaultCharset())));
        NettyTestUtils.sendServerResponses(relay, clientAddr, sourcesResp, body);
        //make sure the client processes the response correctly
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                DispatcherState dispState = clientConn.getRelayDispatcher().getDispatcherState();
                return null != dispState.getSchemaMap() && 1 == dispState.getSchemaMap().size();
            }
        }, "client processes /register response", 100, log);
        //process /stream call and return a partial window
        Matcher streamMatcher = NettyTestUtils.waitForHttpRequest(objCapture, "/stream.*checkPoint=([^&]*)&.*", 1000);
        String cpString = streamMatcher.group(1);
        objCapture.clear();
        int respStartOfs = eventOfs.get(1).get(1);
        int respEndOfs = eventOfs.get(1).get(26);
        cp = new Checkpoint(cpString);
        //last window read was partial
        assertTrue(cp.getWindowOffset() > 0);
        streamRes = NettyTestUtils.streamToChannelBuffer(relayBuffer[1], cp, respEndOfs - respStartOfs, stats);
        NettyTestUtils.sendServerResponses(relay, clientAddr, streamResp, new DefaultHttpChunk(streamRes));
        //make sure the client processes the response correctly
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                log.debug("lastWrittenScn=" + clientConn.getDataEventsBuffer().lastWrittenScn());
                return clientConn.getDataEventsBuffer().lastWrittenScn() == 40;
            }
        }, "client receives /stream response", 1100, log);
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                log.debug("events num=" + consumer.getEventNum());
                return stats.getTotalStats().getNumDataEvents() == consumer.getEventNum();
            }
        }, "client processes /stream response", 11000, log);
        assertEquals(20, consumer.getRollbackScn());
        //add one more onStartDataEventsSequence after the rollback()
        ++rollbackNum;
        assertEquals(stats.getTotalStats().getNumSysEvents() + 1 + rollbackNum, consumer.getWinNum());
        expKeys.addAll(eventKeys.get(1).subList(0, (int) (stats.getTotalStats().getNumDataEvents() - numEvents)));
        for (int i = 0; i < (stats.getTotalStats().getNumDataEvents() - numEvents); i++) expSeqs.add((i / 20) * 20 + 20L);
        log.info("Expected NumKeys :" + expKeys.size() + ", Got NumKeys :" + consumer.getKeys().size());
        for (int i = 0; i < expKeys.size(); i++) {
            if (!consumer.getKeys().contains(expKeys.get(i)))
                log.error(i + " Key :" + expKeys.get(i) + " missing !!");
            else
                log.info(i + " Key :" + expKeys.get(i) + " present !!");
        }
        assertEquals("Keys", expKeys, consumer.getKeys());
        assertEquals("Sequences", expSeqs, consumer.getSequences());
        assertEquals("Keys", expKeys, consumer.getKeys());
        assertEquals("Sequences", expSeqs, consumer.getSequences());
        numEvents = stats.getTotalStats().getNumDataEvents();
        assertEquals(clientConn.getRelayPullThread().getConnectionState().getDataEventsBuffer().isSCNRegress(), false);
        ///////////////////////////////////
        //simulate a timeout on the server; the client would have sent a /stream call and there
        //will be no response from the server, so eventually it should time out and switch servers
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                log.debug("Channel :" + newRelayConnInsp.getChannel());
                return (null != newRelayConnInsp.getChannel()) && (!newRelayConnInsp.getChannel().isConnected());
            }
        }, "waiting for a reconnect", (long) (DEFAULT_READ_TIMEOUT_MS * 1.5), log);
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return clientConn.getRelayPullThread().getLastOpenConnection() != relayConn;
            }
        }, "new netty connection", 200, log);
        final NettyHttpDatabusRelayConnection new2RelayConn = (NettyHttpDatabusRelayConnection) clientConn.getRelayPullThread().getLastOpenConnection();
        final NettyHttpDatabusRelayConnectionInspector new2RelayConnInsp = new NettyHttpDatabusRelayConnectionInspector(new2RelayConn);
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return null != new2RelayConnInsp.getChannel() && new2RelayConnInsp.getChannel().isConnected();
            }
        }, "client connected to third relay", 200, log);
        //figure out the connection to the relay
        clientChannel = new2RelayConnInsp.getChannel();
        relayAddr = (InetSocketAddress) clientChannel.getRemoteAddress();
        clientAddr = clientChannel.getLocalAddress();
        relayPort = relayAddr.getPort();
        log.info("third relay selected: " + relayPort);
        relay = null;
        relayIdx = 0;
        for (; relayIdx < RELAY_PORT.length; ++relayIdx) {
            if (relayPort == RELAY_PORT[relayIdx])
                relay = _dummyServer[relayIdx];
        }
        assertTrue(null != relay);
        serverChannel = relay.getChildChannel(clientAddr);
        assertTrue(null != serverChannel);
        serverPipeline = serverChannel.getPipeline();
        objCapture = (SimpleObjectCaptureHandler) serverPipeline.get("3");
        //process the /sources request
        NettyTestUtils.waitForHttpRequest(objCapture, SOURCES_REQUEST_REGEX, 1000);
        objCapture.clear();
        //send back the /sources response
        body = new DefaultHttpChunk(ChannelBuffers.wrappedBuffer(("[{\"id\":1,\"name\":\"" + SOURCE1_NAME + "\"}]").getBytes(Charset.defaultCharset())));
        NettyTestUtils.sendServerResponses(relay, clientAddr, sourcesResp, body);
        //make sure the client processes the response correctly
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                String idListString = clientConn.getRelayPullThread()._currentState.getSourcesIdListString();
                return "1".equals(idListString);
            }
        }, "client processes /sources response", 100, log);
        //process the /register request
        NettyTestUtils.waitForHttpRequest(objCapture, "/register.*", 1000);
        objCapture.clear();
        //send back the /register response
        body = new DefaultHttpChunk(ChannelBuffers.wrappedBuffer(responseStr.getBytes(Charset.defaultCharset())));
        NettyTestUtils.sendServerResponses(relay, clientAddr, sourcesResp, body);
        //make sure the client processes the response correctly
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                DispatcherState dispState = clientConn.getRelayDispatcher().getDispatcherState();
                return null != dispState.getSchemaMap() && 1 == dispState.getSchemaMap().size();
            }
        }, "client processes /sources response", 100, log);
        //process /stream call and return a partial window
        streamMatcher = NettyTestUtils.waitForHttpRequest(objCapture, "/stream.*checkPoint=([^&]*)&.*", 1000);
        cpString = streamMatcher.group(1);
        objCapture.clear();
        respStartOfs = eventOfs.get(2).get(20);
        respEndOfs = eventOfs.get(2).get(89);
        log.debug("Checkpoint String is :" + cpString);
        cp = new Checkpoint(cpString);
        //last window read was partial. So the client would have reset the windowOffset
        assertTrue("Is WindowOffset Cleared", cp.getWindowOffset() == -1);
        assertEquals("WindowSCN == PrevSCN. Ckpt :" + cp, cp.getWindowScn(), cp.getPrevScn());
        streamRes = NettyTestUtils.streamToChannelBuffer(relayBuffer[2], cp, respEndOfs - respStartOfs, stats);
        NettyTestUtils.sendServerResponses(relay, clientAddr, streamResp, new DefaultHttpChunk(streamRes));
        //make sure the client processes the response correctly
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                log.debug("lastWrittenScn=" + clientConn.getDataEventsBuffer().lastWrittenScn());
                return clientConn.getDataEventsBuffer().lastWrittenScn() == 90;
            }
        }, "client receives /stream response, Sequence :" + consumer.getSequences(), 10100, log);
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                log.debug("events num=" + consumer.getEventNum());
                return stats.getTotalStats().getNumDataEvents() == consumer.getEventNum();
            }
        }, "client processes /stream response", 110000, log);
        assertEquals(30, consumer.getRollbackScn());
        //add one more onStartDataEventsSequence because of the rollback
        ++rollbackNum;
        assertEquals(stats.getTotalStats().getNumSysEvents() + 1 + rollbackNum, consumer.getWinNum());
        expKeys.addAll(eventKeys.get(2).subList(20, (int) (stats.getTotalStats().getNumDataEvents() - numEvents + 20)));
        for (int i = 0; i < (stats.getTotalStats().getNumDataEvents() - numEvents); i++) expSeqs.add((i / 10) * 10 + 30L);
        numEvents = stats.getTotalStats().getNumDataEvents();
        assertEquals("Keys", expKeys, consumer.getKeys());
        assertEquals("Sequences Size ", expSeqs.size(), consumer.getSequences().size());
        for (int i = 0; i < expSeqs.size(); i++) {
            System.out.println(i + " Exp : " + expSeqs.get(i) + ", Got :" + consumer.getSequences().get(i));
            if (expSeqs.get(i) != consumer.getSequences().get(i))
                throw new RuntimeException("Failed at " + i);
        }
        assertEquals("Sequences", expSeqs, consumer.getSequences());
        numEvents = stats.getTotalStats().getNumDataEvents();
        assertEquals(clientConn.getRelayPullThread().getConnectionState().getDataEventsBuffer().isSCNRegress(), false);
        // Expect none of the keys streamed to be missed.
        expKeys.clear();
        cp = clientConn.getRelayPullThread().getConnectionState().getCheckpoint();
        int offset = (int) ((cp.getWindowOffset() < 0) ? 0 : cp.getWindowOffset());
        LOG.info("Client ckpt is :" + cp);
        expKeys.addAll(eventKeys.get(2).subList(0, 80 + offset));
        for (int i = 0; i < expKeys.size(); i++) {
            if (!consumer.getKeys().contains(expKeys.get(i))) {
                log.error(i + " Key :" + expKeys.get(i) + " missing !!");
                throw new RuntimeException("Failed at " + i);
            } else
                log.info(i + " Key :" + expKeys.get(i) + " present !!");
        }
    } finally {
        client.shutdown();
    }
}
Also used : NettyHttpDatabusRelayConnection(com.linkedin.databus.client.netty.NettyHttpDatabusRelayConnection) NettyHttpDatabusRelayConnectionInspector(com.linkedin.databus.client.netty.NettyHttpDatabusRelayConnectionInspector) DefaultHttpChunk(org.jboss.netty.handler.codec.http.DefaultHttpChunk) Matcher(java.util.regex.Matcher) InetSocketAddress(java.net.InetSocketAddress) ArrayList(java.util.ArrayList) DbusEventsStatisticsCollector(com.linkedin.databus.core.monitoring.mbean.DbusEventsStatisticsCollector) Logger(org.apache.log4j.Logger) ChannelBuffer(org.jboss.netty.buffer.ChannelBuffer) DbusEventInfo(com.linkedin.databus.core.DbusEventInfo) List(java.util.List) ArrayList(java.util.ArrayList) SocketAddress(java.net.SocketAddress) InetSocketAddress(java.net.InetSocketAddress) ConditionCheck(com.linkedin.databus2.test.ConditionCheck) Channel(org.jboss.netty.channel.Channel) SimpleTestServerConnection(com.linkedin.databus2.test.container.SimpleTestServerConnection) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(org.jboss.netty.handler.codec.http.HttpResponse) Checkpoint(com.linkedin.databus.core.Checkpoint) ChannelPipeline(org.jboss.netty.channel.ChannelPipeline) DbusEventBuffer(com.linkedin.databus.core.DbusEventBuffer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Checkpoint(com.linkedin.databus.core.Checkpoint) SimpleObjectCaptureHandler(com.linkedin.databus2.test.container.SimpleObjectCaptureHandler) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) RegisterResponseEntry(com.linkedin.databus2.core.container.request.RegisterResponseEntry) DbusEventKey(com.linkedin.databus.core.DbusEventKey) DefaultHttpChunk(org.jboss.netty.handler.codec.http.DefaultHttpChunk) HttpChunk(org.jboss.netty.handler.codec.http.HttpChunk) Test(org.testng.annotations.Test)

Example 7 with DefaultHttpChunk

use of org.jboss.netty.handler.codec.http.DefaultHttpChunk in project databus by linkedin.

the class TestHttpResponseProcessor method testHappyPathWithCloseChunking.

@Test
public void testHappyPathWithCloseChunking() throws DatabusException {
    Logger log = Logger.getLogger("GenericHttpResponseHandler.testHappyPathWithCloseChunking");
    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);
        HttpChunk chunk2 = new DefaultHttpChunk(ChannelBuffers.wrappedBuffer("chunk2".getBytes(Charset.defaultCharset())));
        sendServerResponse(clientAddr, chunk2, 1000);
        sendServerResponse(clientAddr, new DefaultHttpChunkTrailer(), 1000);
        TestUtil.sleep(200);
        sendServerClose(clientAddr, -1);
        final List<String> callbacks = respProcessor.getCallbacks();
        TestUtil.assertWithBackoff(new ConditionCheck() {

            @Override
            public boolean check() {
                return 5 == callbacks.size();
            }
        }, "waiting for response processed", 1000, null);
        final List<String> connectCallbacks = connectListener.getCallbacks();
        final List<String> requestCallbacks = requestListener.getCallbacks();
        final List<String> closeCallbacks = closeListener.getCallbacks();
        stateSanityCheck(connectCallbacks, requestCallbacks, callbacks, closeCallbacks);
        Assert.assertEquals(callbacks.get(0), "startResponse");
        Assert.assertEquals(callbacks.get(1), "addChunk");
        Assert.assertEquals(callbacks.get(2), "addChunk");
        Assert.assertEquals(callbacks.get(3), "addTrailer");
        Assert.assertEquals(callbacks.get(4), "finishResponse");
        //make sure that no new callbacks have showed up
        Assert.assertEquals(callbacks.size(), 5);
    } finally {
        channel.close();
    }
}
Also used : ConditionCheck(com.linkedin.databus2.test.ConditionCheck) DefaultHttpChunk(org.jboss.netty.handler.codec.http.DefaultHttpChunk) 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) DefaultHttpChunkTrailer(org.jboss.netty.handler.codec.http.DefaultHttpChunkTrailer) 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 8 with DefaultHttpChunk

use of org.jboss.netty.handler.codec.http.DefaultHttpChunk in project databus by linkedin.

the class TestHttpResponseProcessor method testRepeatedReadSuccess.

@Test
public void testRepeatedReadSuccess() throws DatabusException {
    Logger log = Logger.getLogger("GenericHttpResponseHandler.testRestRepeatedReadSuccess");
    //global responseHandler;
    final GenericHttpResponseHandler responseHandler = new GenericHttpResponseHandler(KeepAliveType.KEEP_ALIVE);
    responseHandler.getLog().setLevel(_logLevel);
    TestConnectListener connectListener = new TestConnectListener(log);
    responseHandler.setConnectionListener(connectListener);
    Channel channel = createClientBootstrap(responseHandler);
    SocketAddress clientAddr = channel.getLocalAddress();
    try {
        for (int i = 0; i < 2; ++i) {
            TestHttpResponseProcessor respProcessor = new TestHttpResponseProcessor(log);
            TestSendRequestListener requestListener = new TestSendRequestListener(log);
            TestCloseListener closeListener = new TestCloseListener(log);
            setListeners(responseHandler, respProcessor, requestListener, closeListener);
            channel.write(new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/test"));
            TestUtil.sleep(1000);
            HttpResponse resp = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
            resp.setHeader(HttpHeaders.Names.TRANSFER_ENCODING, HttpHeaders.Values.CHUNKED);
            sendServerResponse(clientAddr, resp, 2000);
            HttpChunk chunk1 = new DefaultHttpChunk(ChannelBuffers.wrappedBuffer("chunk1".getBytes(Charset.defaultCharset())));
            sendServerResponse(clientAddr, chunk1, 1000);
            sendServerResponse(clientAddr, new DefaultHttpChunkTrailer(), 1000);
            final List<String> callbacks = respProcessor.getCallbacks();
            final List<String> connectCallbacks = connectListener.getCallbacks();
            final List<String> requestCallbacks = requestListener.getCallbacks();
            final List<String> closeCallbacks = closeListener.getCallbacks();
            TestUtil.sleep(500);
            stateSanityCheck(connectCallbacks, requestCallbacks, callbacks, closeCallbacks);
            Assert.assertEquals(1, connectCallbacks.size());
            Assert.assertEquals(connectCallbacks.get(0), "onConnectSuccess");
            Assert.assertEquals(requestCallbacks.size(), 1);
            Assert.assertEquals(requestCallbacks.get(0), "onSendRequestSuccess");
            TestUtil.assertWithBackoff(new ConditionCheck() {

                @Override
                public boolean check() {
                    return callbacks.size() == 4;
                }
            }, "waiting for response processed", 2000, null);
            Assert.assertEquals(callbacks.get(0), "startResponse");
            Assert.assertEquals(callbacks.get(1), "addChunk");
            Assert.assertEquals(callbacks.get(2), "addTrailer");
            Assert.assertEquals(callbacks.get(3), "finishResponse");
        }
    } finally {
        channel.close();
    }
}
Also used : ConditionCheck(com.linkedin.databus2.test.ConditionCheck) DefaultHttpChunk(org.jboss.netty.handler.codec.http.DefaultHttpChunk) 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) DefaultHttpChunkTrailer(org.jboss.netty.handler.codec.http.DefaultHttpChunkTrailer) 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 9 with DefaultHttpChunk

use of org.jboss.netty.handler.codec.http.DefaultHttpChunk 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 10 with DefaultHttpChunk

use of org.jboss.netty.handler.codec.http.DefaultHttpChunk in project databus by linkedin.

the class TestResponseProcessors method testTargetSCNExceptionAfterStartCase2.

@Test
public void testTargetSCNExceptionAfterStartCase2() 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_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.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.TARGETSCN_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)

Aggregations

DefaultHttpChunk (org.jboss.netty.handler.codec.http.DefaultHttpChunk)57 DefaultHttpResponse (org.jboss.netty.handler.codec.http.DefaultHttpResponse)53 HttpChunk (org.jboss.netty.handler.codec.http.HttpChunk)52 Test (org.testng.annotations.Test)46 HttpResponse (org.jboss.netty.handler.codec.http.HttpResponse)45 ChannelBuffer (org.jboss.netty.buffer.ChannelBuffer)43 DefaultHttpChunkTrailer (org.jboss.netty.handler.codec.http.DefaultHttpChunkTrailer)38 HttpChunkTrailer (org.jboss.netty.handler.codec.http.HttpChunkTrailer)34 Checkpoint (com.linkedin.databus.core.Checkpoint)26 BootstrapDatabaseTooOldException (com.linkedin.databus2.core.container.request.BootstrapDatabaseTooOldException)25 ConditionCheck (com.linkedin.databus2.test.ConditionCheck)15 InetSocketAddress (java.net.InetSocketAddress)15 SocketAddress (java.net.SocketAddress)15 Channel (org.jboss.netty.channel.Channel)15 Logger (org.apache.log4j.Logger)12 SimpleObjectCaptureHandler (com.linkedin.databus2.test.container.SimpleObjectCaptureHandler)9 ChannelPipeline (org.jboss.netty.channel.ChannelPipeline)9 RegisterResponseEntry (com.linkedin.databus2.core.container.request.RegisterResponseEntry)8 HttpRequest (org.jboss.netty.handler.codec.http.HttpRequest)7 DatabusRelayConnectionStateMessage (com.linkedin.databus.client.DatabusRelayConnectionStateMessage)6