From 5d5612c9bfcc8c30abca5556f94cbd01c8a1f4be Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 11 Jul 2015 11:43:09 +0200 Subject: [PATCH] Add AddPeer command that adds a noderef from a file --- .../pterodactylus/fcp/quelaton/AddPeerCommand.java | 14 ++++ .../fcp/quelaton/AddPeerCommandImpl.java | 87 ++++++++++++++++++++++ .../fcp/quelaton/DefaultFcpClient.java | 5 ++ .../net/pterodactylus/fcp/quelaton/FcpClient.java | 1 + .../net/pterodactylus/fcp/quelaton/WithFile.java | 16 ++++ .../fcp/quelaton/DefaultFcpClientTest.java | 27 +++++++ 6 files changed, 150 insertions(+) create mode 100644 src/main/java/net/pterodactylus/fcp/quelaton/AddPeerCommand.java create mode 100644 src/main/java/net/pterodactylus/fcp/quelaton/AddPeerCommandImpl.java create mode 100644 src/main/java/net/pterodactylus/fcp/quelaton/WithFile.java diff --git a/src/main/java/net/pterodactylus/fcp/quelaton/AddPeerCommand.java b/src/main/java/net/pterodactylus/fcp/quelaton/AddPeerCommand.java new file mode 100644 index 0000000..2434106 --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/quelaton/AddPeerCommand.java @@ -0,0 +1,14 @@ +package net.pterodactylus.fcp.quelaton; + +import java.util.Optional; + +import net.pterodactylus.fcp.Peer; + +/** + * Command that adds a peer to the node. + * + * @author David ‘Bombe’ Roden + */ +public interface AddPeerCommand extends WithFile>> { + +} diff --git a/src/main/java/net/pterodactylus/fcp/quelaton/AddPeerCommandImpl.java b/src/main/java/net/pterodactylus/fcp/quelaton/AddPeerCommandImpl.java new file mode 100644 index 0000000..67aa563 --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/quelaton/AddPeerCommandImpl.java @@ -0,0 +1,87 @@ +package net.pterodactylus.fcp.quelaton; + +import java.io.File; +import java.io.IOException; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +import net.pterodactylus.fcp.AddPeer; +import net.pterodactylus.fcp.Peer; +import net.pterodactylus.fcp.ProtocolError; + +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; + +/** + * Default {@link AddPeerCommand} implementation based on {@link FcpReplySequence}. + * + * @author David ‘Bombe’ Roden + */ +public class AddPeerCommandImpl implements AddPeerCommand { + + private final ListeningExecutorService threadPool; + private final ConnectionSupplier connectionSupplier; + private final AtomicReference file = new AtomicReference<>(); + + public AddPeerCommandImpl(ExecutorService threadPool, ConnectionSupplier connectionSupplier) { + this.threadPool = MoreExecutors.listeningDecorator(threadPool); + this.connectionSupplier = connectionSupplier; + } + + @Override + public Executable> withFile(File file) { + this.file.set(file); + return this::execute; + } + + private ListenableFuture> execute() { + return threadPool.submit(this::executeSequence); + } + + private Optional executeSequence() throws IOException, ExecutionException, InterruptedException { + AddPeer addPeer = null; + if (file.get() != null) { + addPeer = new AddPeer(new RandomIdentifierGenerator().generate(), file.get().getPath()); + } + try (AddPeerSequence addPeerSequence = new AddPeerSequence()) { + return addPeerSequence.send(addPeer).get(); + } + } + + private class AddPeerSequence extends FcpReplySequence> { + + private final AtomicBoolean finished = new AtomicBoolean(); + private final AtomicReference peer = new AtomicReference<>(); + + public AddPeerSequence() throws IOException { + super(threadPool, connectionSupplier.get()); + } + + @Override + protected boolean isFinished() { + return finished.get(); + } + + @Override + protected Optional getResult() { + return Optional.ofNullable(peer.get()); + } + + @Override + protected void consumePeer(Peer peer) { + this.peer.set(peer); + finished.set(true); + } + + @Override + protected void consumeProtocolError(ProtocolError protocolError) { + finished.set(true); + } + + } + +} diff --git a/src/main/java/net/pterodactylus/fcp/quelaton/DefaultFcpClient.java b/src/main/java/net/pterodactylus/fcp/quelaton/DefaultFcpClient.java index 6cefb46..574afc6 100644 --- a/src/main/java/net/pterodactylus/fcp/quelaton/DefaultFcpClient.java +++ b/src/main/java/net/pterodactylus/fcp/quelaton/DefaultFcpClient.java @@ -79,5 +79,10 @@ public class DefaultFcpClient implements FcpClient { return new ListPeersCommandImpl(threadPool, this::connect); } + @Override + public AddPeerCommand addPeer() { + return new AddPeerCommandImpl(threadPool, this::connect); + } + } diff --git a/src/main/java/net/pterodactylus/fcp/quelaton/FcpClient.java b/src/main/java/net/pterodactylus/fcp/quelaton/FcpClient.java index c4c6d51..5b61979 100644 --- a/src/main/java/net/pterodactylus/fcp/quelaton/FcpClient.java +++ b/src/main/java/net/pterodactylus/fcp/quelaton/FcpClient.java @@ -14,5 +14,6 @@ public interface FcpClient { ListPeerCommand listPeer(); ListPeersCommand listPeers(); + AddPeerCommand addPeer(); } diff --git a/src/main/java/net/pterodactylus/fcp/quelaton/WithFile.java b/src/main/java/net/pterodactylus/fcp/quelaton/WithFile.java new file mode 100644 index 0000000..85af12a --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/quelaton/WithFile.java @@ -0,0 +1,16 @@ +package net.pterodactylus.fcp.quelaton; + +import java.io.File; + +/** + * An intermediary interface for FCP commands that require a file parameter. + * + * @param + * The type of the next command part + * @author David ‘Bombe’ Roden + */ +public interface WithFile { + + R withFile(File file); + +} diff --git a/src/test/java/net/pterodactylus/fcp/quelaton/DefaultFcpClientTest.java b/src/test/java/net/pterodactylus/fcp/quelaton/DefaultFcpClientTest.java index 9108c17..06a8de0 100644 --- a/src/test/java/net/pterodactylus/fcp/quelaton/DefaultFcpClientTest.java +++ b/src/test/java/net/pterodactylus/fcp/quelaton/DefaultFcpClientTest.java @@ -998,4 +998,31 @@ public class DefaultFcpClientTest { assertThat(peer.get().isPresent(), is(false)); } + @Test + public void defaultFcpClientCanAddPeerFromFile() throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.addPeer().withFile(new File("/tmp/ref.txt")).execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "AddPeer", + "Identifier=" + identifier, + "File=/tmp/ref.txt", + "EndMessage" + )); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "identity=id1", + "opennet=false", + "ark.pubURI=SSK@3YEf.../ark", + "ark.number=78", + "auth.negTypes=2", + "version=Fred,0.7,1.0,1466", + "lastGoodVersion=Fred,0.7,1.0,1466", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity().toString(), is("id1")); + } + } -- 2.7.4