Package com.linkedin.databus2.core.container

Source Code of com.linkedin.databus2.core.container.TestExtendedWriteTimeoutHandler

package com.linkedin.databus2.core.container;
/*
*
* Copyright 2013 LinkedIn Corp. All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/


import java.nio.channels.ClosedChannelException;
import java.nio.charset.Charset;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelDownstreamHandler;
import org.jboss.netty.handler.timeout.WriteTimeoutException;
import org.testng.Assert;
import org.testng.annotations.Test;

import com.linkedin.databus.core.DbusEventFactory;
import com.linkedin.databus.core.DbusEventV1;
import com.linkedin.databus.core.DbusEventV1Factory;
import com.linkedin.databus2.test.ConditionCheck;
import com.linkedin.databus2.test.TestUtil;
import com.linkedin.databus2.test.container.ExceptionListenerTestHandler;
import com.linkedin.databus2.test.container.SimpleTestClientConnection;
import com.linkedin.databus2.test.container.SimpleTestMessageReader;
import com.linkedin.databus2.test.container.SimpleTestServerConnection;

public class TestExtendedWriteTimeoutHandler
{
  static final long CONNECT_TIMEOUT_MS = 1000;

  @Test
  public void testClientSimpleRequestResponse()
  {
    DbusEventFactory eventFactory = new DbusEventV1Factory();

    SimpleTestServerConnection srvConn = new SimpleTestServerConnection(eventFactory.getByteOrder());
    srvConn.setPipelineFactory(new SimpleServerPipelineFactory());
    boolean serverStarted = srvConn.startSynchronously(101, CONNECT_TIMEOUT_MS);
    Assert.assertTrue(serverStarted, "server started");

    final SimpleTestClientConnection clientConn = new SimpleTestClientConnection(eventFactory.getByteOrder());
    clientConn.setPipelineFactory(new SimpleClientPipelineFactoryWithSleep(200));
    boolean clientConnected = clientConn.startSynchronously(101, CONNECT_TIMEOUT_MS);
    Assert.assertTrue(clientConnected, "client connected");

    //hook in to key places in the server pipeline
    ChannelPipeline lastSrvConnPipeline = srvConn.getLastConnChannel().getPipeline();
    SimpleTestMessageReader srvMsgReader = (SimpleTestMessageReader)lastSrvConnPipeline.get(
        SimpleTestMessageReader.class.getSimpleName());
    ExceptionListenerTestHandler srvExceptionListener =
        (ExceptionListenerTestHandler)lastSrvConnPipeline.get(
            ExceptionListenerTestHandler.class.getSimpleName());

    //hook in to key places in the client pipeline
    ChannelPipeline clientPipeline = clientConn.getChannel().getPipeline();
    final ExceptionListenerTestHandler clientExceptionListener =
        (ExceptionListenerTestHandler)clientPipeline.get(
            ExceptionListenerTestHandler.class.getSimpleName());

    //System.err.println("Current thread: " + Thread.currentThread());

    //send a request in a separate thread because the client will intentionally block to simulate
    //a timeout
    final ChannelBuffer msg = ChannelBuffers.wrappedBuffer("hello".getBytes(Charset.defaultCharset()));
    Thread sendThread1 = new Thread(new Runnable()
        {
          @Override
          public void run()
          {
            //System.err.println(Thread.currentThread().toString() + ": sending message");
            clientConn.getChannel().write(msg);
          }
        }, "send msg thread");
    sendThread1.start();

    //wait for the request to propagate
    //System.err.println(Thread.currentThread().toString() + ": waiting for 10");
    try {Thread.sleep(50);} catch (InterruptedException ie){};
    //System.err.println(Thread.currentThread().toString() + ": done Waiting for 10");

    //make sure the server has not received the message
    Assert.assertNull(srvExceptionListener.getLastException(), "no server errors");
    Assert.assertNull(clientExceptionListener.getLastException(), "no errors yet");
    Assert.assertTrue(!"hello".equals(srvMsgReader.getMsg()), "message not read yet");

    //System.err.println("Waiting for 300");
    //wait for the write timeout
    try {Thread.sleep(300);} catch (InterruptedException ie){};
    //System.err.println("Done Waiting for 300");

    //the client should have timed out and closed the connection

    TestUtil.assertWithBackoff(new ConditionCheck()
        {
          @Override
          public boolean check()
          {
            return null != clientExceptionListener.getLastException();
          }
        }, "client error", 1000, null);

    Assert.assertTrue(null != clientExceptionListener.getLastException(),
                      "client error");
    Assert.assertTrue(clientExceptionListener.getLastException() instanceof ClosedChannelException
                      || clientExceptionListener.getLastException() instanceof WriteTimeoutException,
                      "client error test");
    Assert.assertTrue(! lastSrvConnPipeline.getChannel().isConnected(), "client has disconnected");
    Assert.assertTrue(! clientPipeline.getChannel().isConnected(), "closed connection to server");

  }

}

class SleepingDownstreamHandler extends SimpleChannelDownstreamHandler
{
  private volatile int _sleepDuration;

  public SleepingDownstreamHandler(int sleepDuration)
  {
    _sleepDuration = sleepDuration;
  }

  public void setSleepDuration(int sleepDuration)
  {
    _sleepDuration = sleepDuration;
  }

  @Override
  public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) throws Exception
  {
    int curSleep = _sleepDuration;
    if (curSleep > 0)
    {
      long startTs = System.currentTimeMillis();
      long now;
      while ((now = System.currentTimeMillis()) - startTs < curSleep)
      {
        long t = curSleep - (now - startTs);
        //System.err.println(Thread.currentThread().toString() + ": sleeping for " + t);
        try
        {
          Thread.sleep(t);
        }
        catch (InterruptedException ie){}
      }
      //System.err.println(Thread.currentThread().toString() + ": done sleeping");
    }
    super.writeRequested(ctx, e);
  }

}

class SimpleClientPipelineFactoryWithSleep extends SimpleClientPipelineFactory
{
  private final int _defaultSleep;

  public SimpleClientPipelineFactoryWithSleep(int defaultSleep)
  {
    _defaultSleep = defaultSleep;
  }

  @Override
  public ChannelPipeline getPipeline() throws Exception
  {
    ChannelPipeline result = super.getPipeline();;

    result.addBefore(ExceptionListenerTestHandler.class.getSimpleName(),
                     ExtendedWriteTimeoutHandler.class.getSimpleName(),
                    new ExtendedWriteTimeoutHandler("client write timeout", null, 100, true));
    result.addFirst(SleepingDownstreamHandler.class.getName(),
                    new SleepingDownstreamHandler(_defaultSleep));

    return result;
  }

}
TOP

Related Classes of com.linkedin.databus2.core.container.TestExtendedWriteTimeoutHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.