package org.webpieces.nio.api;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.junit.Assert;
import org.junit.Test;
import org.webpieces.asyncserver.api.AsyncConfig;
import org.webpieces.asyncserver.api.AsyncServer;
import org.webpieces.asyncserver.api.AsyncServerManager;
import org.webpieces.asyncserver.api.AsyncServerMgrFactory;
import org.webpieces.data.api.BufferCreationPool;
import org.webpieces.nio.api.channels.Channel;
import org.webpieces.nio.api.channels.TCPChannel;
import org.webpieces.nio.api.handlers.AsyncDataListener;
import org.webpieces.nio.api.handlers.DataListener;
import org.webpieces.util.logging.Logger;
import org.webpieces.util.logging.LoggerFactory;
public class TestBasicSslClientServer {
private static final Logger log = LoggerFactory.getLogger(TestBasicSslClientServer.class);
private BufferCreationPool pool;
private List<Integer> values = new ArrayList<>();
@Test
public void testBasic() throws InterruptedException {
pool = new BufferCreationPool();
ChannelManagerFactory factory = ChannelManagerFactory.createFactory();
ChannelManager mgr = factory.createSingleThreadedChanMgr("sslChanMgr", pool);
AsyncServerManager svrFactory = AsyncServerMgrFactory.createAsyncServer(mgr);
SSLEngineFactoryForTest f = new SSLEngineFactoryForTest();
InetSocketAddress addr = new InetSocketAddress("localhost", 0);
AsyncServer svr = svrFactory.createTcpServer(new AsyncConfig("sslTcpSvr"), new SvrDataListener(), f);
svr.start(addr);
InetSocketAddress bound = svr.getUnderlyingChannel().getLocalAddress();
System.out.println("port="+bound.getPort());
TCPChannel channel = mgr.createTCPChannel("client", f.createEngineForSocket());
CompletableFuture<Channel> connect = channel.connect(bound, new ClientListener());
connect.thenAccept(c -> writeData(c));
synchronized (pool) {
while(values.size() < 10)
pool.wait();
}
for(int i = 0; i < values.size(); i++) {
Assert.assertEquals(new Integer(i), values.get(i));
}
}
private void writeData(Channel c) {
for(int i = 0; i < 10; i++) {
ByteBuffer buffer = pool.nextBuffer(2);
buffer.put((byte) i);
buffer.flip();
c.write(buffer);
}
}
private class ClientListener implements DataListener {
@Override
public void incomingData(Channel channel, ByteBuffer b) {
int value = b.get();
log.info("incoming client data="+value);
pool.releaseBuffer(b);
values.add(value);
if(values.size() >= 10) {
synchronized (pool) {
pool.notifyAll();
}
}
}
@Override
public void farEndClosed(Channel channel) {
log.info("server closed");
}
@Override
public void failure(Channel channel, ByteBuffer data, Exception e) {
log.error("client failed", e);
}
@Override
public void applyBackPressure(Channel channel) {
log.info("apply backpressure");
}
@Override
public void releaseBackPressure(Channel channel) {
log.info("releasebackpressure");
}
}
private class SvrDataListener implements AsyncDataListener {
@Override
public void incomingData(Channel channel, ByteBuffer b) {
log.info("server received data");
channel.write(b);
}
@Override
public void connectionOpened(TCPChannel channel, boolean isReadyForWrites) {
log.info("opened channel="+channel);
}
@Override
public void farEndClosed(Channel channel) {
log.info("svr side....client must have closed the channel="+channel);
}
@Override
public void failure(Channel channel, ByteBuffer data, Exception e) {
log.info("failed", e);
}
@Override
public void applyBackPressure(Channel channel) {
log.info("svr apply backpressure");
}
@Override
public void releaseBackPressure(Channel channel) {
log.info("svr releasebackpressure");
}
}
}