package se.chalmers.gdcn.network; import net.tomp2p.futures.BaseFutureAdapter; import net.tomp2p.futures.FutureDHT; import net.tomp2p.p2p.Peer; import net.tomp2p.p2p.RequestP2PConfiguration; import net.tomp2p.p2p.builder.SendBuilder; import net.tomp2p.peers.PeerAddress; import net.tomp2p.rpc.ObjectDataReply; import java.io.Serializable; /** * Created by Leif on 2014-03-19. * * There must only be ONE Passer for each Peer! */ abstract class Passer { private final Peer peer; private final static RequestP2PConfiguration requestConfiguration = new RequestP2PConfiguration(1, 10, 0, false, true); protected Passer(final Peer peer) { this.peer = peer; peer.setObjectDataReply(new ObjectDataReply() { @Override public Object reply(PeerAddress sender, Object request) throws Exception { if(peer.getPeerAddress().equals(sender)){ //Disabled for demo //System.out.println("in Passer: ERROR! sender is myself!!!"); } NetworkMessage message = NetworkMessage.decrypt( request); if(message == null){ //Error has occurred in decrypt System.out.println("Decrypt returned NULL!"); return "Decrypt was NULL"; } //Disabled for demo //System.out.println("ObjectDataReply received: " + message.toString()); switch (message.getType()){ case REQUEST: return handleRequest(sender, message.getObject()); case NO_REPLY: handleNoReply(sender, message.getObject()); return "Message was Handled in some way..."; } return "Message was read but not Handled! Type: "+message.getType().name(); } }); } /** * Handle a Request call from sender * @param sender Peer sending * @param messageContent Message * @return Serializable answer message */ protected abstract Serializable handleRequest(PeerAddress sender, Object messageContent); /** * Handle a NoReply call from sender * @param sender Peer sending * @param messageContent Message */ protected abstract void handleNoReply(PeerAddress sender, Object messageContent); /** * Send a message to this Peer and expect an answer * * @param receiver peer * @param message message * @param onReturn what you will do when it answers */ protected void sendRequest(final PeerAddress receiver, Serializable message, final OnReplyCommand onReturn){ SendBuilder sendBuilder = peer.send(receiver.getID()); final NetworkMessage networkMessage = new NetworkMessage(message, NetworkMessage.Type.REQUEST); FutureDHT futureDHT = sendBuilder.setObject( networkMessage.encrypt() ).setRequestP2PConfiguration(requestConfiguration).start(); futureDHT.addListener(new BaseFutureAdapter<FutureDHT>() { @Override public void operationComplete(FutureDHT future) throws Exception { if(!future.isSuccess()){ System.out.println("Error sending " + networkMessage.toString()); System.out.println("WHY: "+future.getFailedReason()); return; } System.out.println("Success sending " + networkMessage.toString() + " to " + print(receiver)); for(PeerAddress address : future.getRawDirectData2().keySet()){ Object answer = future.getRawDirectData2().get(address); onReturn.execute(answer); System.out.println(print(address)+" answered with "+answer); } } }); } /** * Send message to a peer without expecting something in reply * @param receiver peer * @param message message */ protected void sendNoReplyMessage(PeerAddress receiver, Serializable message){ SendBuilder sendBuilder = peer.send(receiver.getID()); final NetworkMessage networkMessage = new NetworkMessage(message, NetworkMessage.Type.NO_REPLY); FutureDHT futureDHT = sendBuilder.setObject( networkMessage.encrypt() ).setRequestP2PConfiguration(requestConfiguration).start(); futureDHT.addListener(new BaseFutureAdapter<FutureDHT>() { @Override public void operationComplete(FutureDHT future) throws Exception { if(!future.isSuccess()){ System.out.println("Error sending " + networkMessage.toString()); System.out.println("WHY: "+future.getFailedReason()); return; } //Disabled for demo System.out.println("Success sending " + networkMessage.toString()); } }); } /** * * @param peerAddress address to some peer * @return Readable string */ public static String print(PeerAddress peerAddress){ return peerAddress.getInetAddress().toString()+":"+peerAddress.portTCP(); } }