package net.tomp2p.rpc;
import java.util.concurrent.atomic.AtomicInteger;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.tomp2p.connection2.ChannelCreator;
import net.tomp2p.connection2.ChannelServerConficuration;
import net.tomp2p.connection2.PeerConnection;
import net.tomp2p.futures.BaseFutureAdapter;
import net.tomp2p.futures.FutureChannelCreator;
import net.tomp2p.futures.FuturePeerConnection;
import net.tomp2p.futures.FutureResponse;
import net.tomp2p.futures.ProgressListener;
import net.tomp2p.message.Buffer;
import net.tomp2p.message.Message2;
import net.tomp2p.p2p.Peer;
import net.tomp2p.p2p.PeerMaker;
import net.tomp2p.p2p.builder.SendDirectBuilder;
import net.tomp2p.peers.Number160;
import net.tomp2p.peers.PeerAddress;
import net.tomp2p.utils.Timings;
import net.tomp2p.utils.Utils;
import org.junit.Assert;
import org.junit.Test;
public class TestDirect {
@Test
public void testDirectMessage() throws Exception {
testDirectMessage(true);
testDirectMessage(false);
}
private void testDirectMessage(boolean wait) throws Exception {
Peer sender = null;
Peer recv1 = null;
ChannelCreator cc = null;
final AtomicInteger replyComplete = new AtomicInteger(0);
final AtomicInteger replyNotComplete = new AtomicInteger(0);
final AtomicInteger progressComplete = new AtomicInteger(0);
final AtomicInteger progressNotComplete = new AtomicInteger(0);
try {
PeerMaker pm1 = new PeerMaker(new Number160("0x50")).p2pId(55).ports(2424);
ChannelServerConficuration css = pm1.createDefaultChannelServerConfiguration();
css.idleTCPSeconds(Integer.MAX_VALUE);
pm1.channelServerConfiguration(css);
sender = pm1.makeAndListen();
PeerMaker pm2 = new PeerMaker(new Number160("0x20")).p2pId(55).ports(8088);
pm2.channelServerConfiguration(css);
recv1 = pm2.makeAndListen();
recv1.setRawDataReply(new RawDataReply() {
@Override
public Buffer reply(PeerAddress sender, Buffer requestBuffer, boolean complete)
throws Exception {
System.err.println("reply 2 ? " + complete);
ByteBuf replyBuffer = Unpooled.buffer(50);
replyBuffer.writerIndex(50);
if (complete) {
replyComplete.incrementAndGet();
return new Buffer(replyBuffer, 100);
} else {
replyNotComplete.incrementAndGet();
return new Buffer(replyBuffer, 100);
}
}
});
FutureChannelCreator fcc = sender.getConnectionBean().reservation().create(0, 1);
fcc.awaitUninterruptibly();
cc = fcc.getChannelCreator();
SendDirectBuilder sendDirectBuilder = new SendDirectBuilder(sender, (PeerAddress) null);
sendDirectBuilder.setStreaming();
sendDirectBuilder.idleTCPSeconds(Integer.MAX_VALUE);
byte[] me = new byte[50];
Buffer b = new Buffer(Unpooled.compositeBuffer(), 100);
b.addComponent(Unpooled.wrappedBuffer(me));
if (!wait) {
ByteBuf replyBuffer = Unpooled.buffer(50);
replyBuffer.writerIndex(50);
b.addComponent(replyBuffer);
}
sendDirectBuilder.setBuffer(b);
sendDirectBuilder.progressListener(new ProgressListener() {
@Override
public void progress(final Message2 interMediateMessage) {
if (interMediateMessage.isDone()) {
progressComplete.incrementAndGet();
System.err.println("progress 1 ? done");
} else {
progressNotComplete.incrementAndGet();
System.err.println("progress 1 ? not done");
}
}
});
FutureResponse fr = sender.getDirectDataRPC().send(recv1.getPeerAddress(), sendDirectBuilder, cc);
if (wait) {
Thread.sleep(500);
ByteBuf replyBuffer = Unpooled.buffer(50);
replyBuffer.writerIndex(50);
b.addComponent(replyBuffer);
}
fr.progress();
System.err.println("progres");
// we are not done yet!
// now we are done
fr.awaitUninterruptibly();
if (wait) {
Assert.assertEquals(1, progressComplete.get());
Assert.assertEquals(1, progressNotComplete.get());
Assert.assertEquals(1, replyComplete.get());
Assert.assertEquals(1, replyNotComplete.get());
} else {
Assert.assertEquals(1, progressComplete.get());
Assert.assertEquals(1, progressNotComplete.get());
Assert.assertEquals(2, replyComplete.get());
Assert.assertEquals(0, replyNotComplete.get());
}
Assert.assertEquals(true, fr.isSuccess());
} finally {
if (cc != null) {
cc.shutdown().awaitListenersUninterruptibly();
}
if (sender != null) {
sender.shutdown().await();
}
if (recv1 != null) {
recv1.shutdown().await();
}
}
}
@Test
public void testDirectMessage1() throws Exception {
Peer sender = null;
Peer recv1 = null;
ChannelCreator cc = null;
try {
sender = new PeerMaker(new Number160("0x50")).p2pId(55).ports(2424).makeAndListen();
recv1 = new PeerMaker(new Number160("0x20")).p2pId(55).ports(8088).makeAndListen();
recv1.setObjectDataReply(new ObjectDataReply() {
@Override
public Object reply(PeerAddress sender, Object request) throws Exception {
return "yes";
}
});
FutureChannelCreator fcc = sender.getConnectionBean().reservation().create(0, 2);
fcc.awaitUninterruptibly();
cc = fcc.getChannelCreator();
SendDirectBuilder sendDirectBuilder = new SendDirectBuilder(sender, (PeerAddress) null);
sendDirectBuilder.setObject("test");
FutureResponse fd1 = sender.getDirectDataRPC()
.send(recv1.getPeerAddress(), sendDirectBuilder, cc);
FutureResponse fd2 = sender.getDirectDataRPC()
.send(recv1.getPeerAddress(), sendDirectBuilder, cc);
fd1.awaitUninterruptibly();
fd2.awaitUninterruptibly();
System.err.println(fd1.getFailedReason());
Assert.assertEquals(true, fd1.isSuccess());
Assert.assertEquals(true, fd2.isSuccess());
Object ret = fd1.getResponse().getBuffer(0).object();
Assert.assertEquals("yes", ret);
} finally {
if (cc != null) {
cc.shutdown().awaitListenersUninterruptibly();
}
if (sender != null) {
sender.shutdown().await();
}
if (recv1 != null) {
recv1.shutdown().await();
}
}
}
@Test
public void testOrder() throws Exception {
Peer sender = null;
Peer recv1 = null;
ChannelCreator cc = null;
try {
sender = new PeerMaker(new Number160("0x9876")).p2pId(55).ports(2424).makeAndListen();
recv1 = new PeerMaker(new Number160("0x1234")).p2pId(55).ports(8088).makeAndListen();
recv1.setObjectDataReply(new ObjectDataReply() {
@Override
public Object reply(PeerAddress sender, Object request) throws Exception {
Integer i = (Integer) request;
System.err.println("got " + i);
return i + 1;
}
});
for (int i = 0; i < 500; i++) {
FutureChannelCreator fcc = sender.getConnectionBean().reservation().create(0, 1);
fcc.awaitUninterruptibly();
cc = fcc.getChannelCreator();
SendDirectBuilder sendDirectBuilder = new SendDirectBuilder(sender, (PeerAddress) null);
sendDirectBuilder.setObject((Object) Integer.valueOf(i));
FutureResponse futureData = sender.getDirectDataRPC().send(recv1.getPeerAddress(),
sendDirectBuilder, cc);
Utils.addReleaseListener(cc, futureData);
futureData.addListener(new BaseFutureAdapter<FutureResponse>() {
@Override
public void operationComplete(FutureResponse future) throws Exception {
// the future object might be null if the future failed,
// e.g due to shutdown
System.err.println(future.getResponse().getBuffer(0).object());
}
});
}
System.err.println("done");
Timings.sleep(2000);
} finally {
if (cc != null) {
cc.shutdown().awaitListenersUninterruptibly();
}
if (sender != null) {
sender.shutdown().await();
}
if (recv1 != null) {
recv1.shutdown().await();
}
}
}
@Test
public void testDirectReconnect() throws Exception {
Peer sender = null;
Peer recv1 = null;
try {
sender = new PeerMaker(new Number160("0x50")).p2pId(55).ports(2424).makeAndListen();
recv1 = new PeerMaker(new Number160("0x20")).p2pId(55).ports(8088).makeAndListen();
recv1.setObjectDataReply(new ObjectDataReply() {
@Override
public Object reply(PeerAddress sender, Object request) throws Exception {
return "yes";
}
});
FuturePeerConnection peerConnection = sender.createPeerConnection(recv1.getPeerAddress());
ChannelCreator.resetConnectionCounts();
FutureResponse fd1 = sender.sendDirect(peerConnection).setObject("test")
.connectionTimeoutTCPMillis(2000).idleTCPSeconds(10 * 1000).start();
Assert.assertEquals(1, ChannelCreator.tcpConnectionCount());
Assert.assertEquals(0, ChannelCreator.udpConnectionCount());
fd1.awaitListenersUninterruptibly();
Assert.assertEquals(true, fd1.isSuccess());
Assert.assertEquals(1, ChannelCreator.tcpConnectionCount());
Assert.assertEquals(0, ChannelCreator.udpConnectionCount());
Timings.sleep(2000);
System.err.println("send second with the same connection");
FutureResponse fd2 = sender.sendDirect(peerConnection).setObject("test").start();
fd2.awaitUninterruptibly();
Assert.assertEquals(1, ChannelCreator.tcpConnectionCount());
Assert.assertEquals(0, ChannelCreator.udpConnectionCount());
Assert.assertEquals(true, fd2.isSuccess());
peerConnection.close().await();
System.err.println("done");
} finally {
if (sender != null) {
sender.shutdown().await();
}
if (recv1 != null) {
recv1.shutdown().await();
}
}
}
@Test
public void testDirect2() throws Exception {
Peer sender = null;
Peer recv1 = null;
try {
sender = new PeerMaker(new Number160("0x50")).p2pId(55).ports(2424).setEnableMaintenance(false)
.makeAndListen();
recv1 = new PeerMaker(new Number160("0x20")).p2pId(55).ports(8088).setEnableMaintenance(false)
.makeAndListen();
recv1.setObjectDataReply(new ObjectDataReply() {
@Override
public Object reply(PeerAddress sender, Object request) throws Exception {
return "yes";
}
});
FuturePeerConnection peerConnection = sender.createPeerConnection(recv1.getPeerAddress());
ChannelCreator.resetConnectionCounts();
FutureResponse fd1 = sender.sendDirect(peerConnection).setObject("test")
.connectionTimeoutTCPMillis(2000).idleTCPSeconds(5).start();
fd1.awaitUninterruptibly();
Assert.assertEquals(1, ChannelCreator.tcpConnectionCount());
Timings.sleep(7000);
FutureResponse fd2 = sender.sendDirect(peerConnection).setObject("test").start();
fd2.awaitUninterruptibly();
peerConnection.close().await();
Assert.assertEquals(2, ChannelCreator.tcpConnectionCount());
System.out.println("done");
} finally {
if (sender != null) {
sender.shutdown().await();
}
if (recv1 != null) {
recv1.shutdown().await();
}
}
}
}