package com.linkedin.databus2.test.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.ByteOrder;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.buffer.DirectChannelBufferFactory;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.local.DefaultLocalClientChannelFactory;
import org.jboss.netty.channel.local.LocalAddress;
/** Simple network client for unit tests. One has to specify the channel pipeline to use. */
public class SimpleTestClientConnection
{
private Channel _channel;
private Thread _thread;
private final ClientBootstrap _clientBootstrap;
private final Lock _lock = new ReentrantLock(true);
private boolean _connected;
private boolean _shutdownRequested;
private boolean _shutdown;
private final Condition _connectedCondition = _lock.newCondition();
private final Condition _shutdownReqCondition = _lock.newCondition();
private final Condition _shutdownCondition = _lock.newCondition();
public SimpleTestClientConnection(ByteOrder bufferByteOrder)
{
_clientBootstrap = new ClientBootstrap(new DefaultLocalClientChannelFactory());
_clientBootstrap.setOption("bufferFactory",
DirectChannelBufferFactory.getInstance(bufferByteOrder));
}
public void setPipelineFactory(ChannelPipelineFactory pipelineFactory)
{
_clientBootstrap.setPipelineFactory(pipelineFactory);
}
public void start(final int serverAddr)
{
_shutdownRequested = false;
_shutdown = false;
_connected = false;
_thread = new Thread(new Runnable()
{
@Override
public void run()
{
//System.err.println("Client running on thread: " + Thread.currentThread());
ChannelFuture connectFuture = _clientBootstrap.connect(new LocalAddress(serverAddr));
connectFuture.awaitUninterruptibly();
_channel = connectFuture.getChannel();
_lock.lock();
try
{
_connected = connectFuture.isSuccess();
_connectedCondition.signalAll();
while (!_shutdownRequested)
{
try
{
_shutdownReqCondition.await();
}
catch (InterruptedException ie) {}
}
_shutdown = true;
_shutdownCondition.signalAll();
}
finally
{
_lock.unlock();
}
}
});
_thread.setDaemon(true);
_thread.start();
}
public boolean startSynchronously(final int serverAddr, long timeoutMillis)
{
start(serverAddr);
try {awaitConnected(timeoutMillis); } catch (InterruptedException ie){};
return isConnected();
}
public void awaitConnected(long timeoutMillis) throws InterruptedException
{
_lock.lock();
try
{
if (!_connected) _connectedCondition.await(timeoutMillis, TimeUnit.MILLISECONDS);
}
finally
{
_lock.unlock();
}
}
public boolean isConnected()
{
_lock.lock();
try
{
return _connected;
}
finally
{
_lock.unlock();
}
}
public void stop()
{
_lock.lock();
try
{
_shutdownRequested = true;
_shutdownReqCondition.signalAll();
while (! _shutdown)
{
try
{
_shutdownCondition.await();
}
catch (InterruptedException ie) {}
}
}
finally
{
_lock.unlock();
}
ChannelFuture closeFuture = _channel.close();
closeFuture.awaitUninterruptibly();
_clientBootstrap.releaseExternalResources();
}
public Channel getChannel()
{
return _channel;
}
}