From e7fe15a311e143a2154bfc62ed21cdf591b9a27f Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Fri, 10 Jul 2015 13:14:02 +0200 Subject: [PATCH] Add ListPeers command --- .../fcp/quelaton/DefaultFcpClient.java | 5 ++ .../net/pterodactylus/fcp/quelaton/FcpClient.java | 2 + .../fcp/quelaton/ListPeersCommand.java | 17 ++++++ .../fcp/quelaton/ListPeersCommandImpl.java | 70 ++++++++++++++++++++++ .../fcp/quelaton/DefaultFcpClientTest.java | 39 ++++++++++++ 5 files changed, 133 insertions(+) create mode 100644 src/main/java/net/pterodactylus/fcp/quelaton/ListPeersCommand.java create mode 100644 src/main/java/net/pterodactylus/fcp/quelaton/ListPeersCommandImpl.java diff --git a/src/main/java/net/pterodactylus/fcp/quelaton/DefaultFcpClient.java b/src/main/java/net/pterodactylus/fcp/quelaton/DefaultFcpClient.java index 1f31d91..1d7c02c 100644 --- a/src/main/java/net/pterodactylus/fcp/quelaton/DefaultFcpClient.java +++ b/src/main/java/net/pterodactylus/fcp/quelaton/DefaultFcpClient.java @@ -74,6 +74,11 @@ public class DefaultFcpClient implements FcpClient { return new ClientPutCommandImpl(threadPool, this::connect); } + @Override + public ListPeersCommand listPeers() { + return new ListPeersCommandImpl(threadPool, this::connect); + } + private class ClientHelloReplySequence extends FcpReplySequence { private final AtomicReference receivedNodeHello; diff --git a/src/main/java/net/pterodactylus/fcp/quelaton/FcpClient.java b/src/main/java/net/pterodactylus/fcp/quelaton/FcpClient.java index 6e5ab0a..ad4501d 100644 --- a/src/main/java/net/pterodactylus/fcp/quelaton/FcpClient.java +++ b/src/main/java/net/pterodactylus/fcp/quelaton/FcpClient.java @@ -11,4 +11,6 @@ public interface FcpClient { ClientGetCommand clientGet(); ClientPutCommand clientPut(); + ListPeersCommand listPeers(); + } diff --git a/src/main/java/net/pterodactylus/fcp/quelaton/ListPeersCommand.java b/src/main/java/net/pterodactylus/fcp/quelaton/ListPeersCommand.java new file mode 100644 index 0000000..56a28c2 --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/quelaton/ListPeersCommand.java @@ -0,0 +1,17 @@ +package net.pterodactylus.fcp.quelaton; + +import java.util.Collection; +import java.util.concurrent.Future; + +import net.pterodactylus.fcp.Peer; + +/** + * Retrieves the list of all peers from the FCP server. + * + * @author David ‘Bombe’ Roden + */ +public interface ListPeersCommand { + + Future> execute(); + +} diff --git a/src/main/java/net/pterodactylus/fcp/quelaton/ListPeersCommandImpl.java b/src/main/java/net/pterodactylus/fcp/quelaton/ListPeersCommandImpl.java new file mode 100644 index 0000000..5638b98 --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/quelaton/ListPeersCommandImpl.java @@ -0,0 +1,70 @@ +package net.pterodactylus.fcp.quelaton; + +import java.io.IOException; +import java.util.Collection; +import java.util.HashSet; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicBoolean; + +import net.pterodactylus.fcp.EndListPeers; +import net.pterodactylus.fcp.ListPeers; +import net.pterodactylus.fcp.Peer; + +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; + +/** + * Default {@link ListPeersCommand} implementation based on {@link FcpReplySequence}. + * + * @author David ‘Bombe’ Roden + */ +public class ListPeersCommandImpl implements ListPeersCommand { + + private final ListeningExecutorService threadPool; + private final ConnectionSupplier connectionSupplier; + + public ListPeersCommandImpl(ExecutorService threadPool, ConnectionSupplier connectionSupplier) { + this.threadPool = MoreExecutors.listeningDecorator(threadPool); + this.connectionSupplier = connectionSupplier; + } + + @Override + public Future> execute() { + String identifier = new RandomIdentifierGenerator().generate(); + ListPeers listPeers = new ListPeers(identifier); + return threadPool.submit(() -> new ListPeersReplySequence().send(listPeers).get()); + } + + private class ListPeersReplySequence extends FcpReplySequence> { + + private final Collection peers = new HashSet<>(); + private final AtomicBoolean finished = new AtomicBoolean(false); + + public ListPeersReplySequence() throws IOException { + super(threadPool, connectionSupplier.get()); + } + + @Override + protected boolean isFinished() { + return finished.get(); + } + + @Override + protected Collection getResult() { + return peers; + } + + @Override + protected void consumePeer(Peer peer) { + peers.add(peer); + } + + @Override + protected void consumeEndListPeers(EndListPeers endListPeers) { + finished.set(true); + } + + } + +} diff --git a/src/test/java/net/pterodactylus/fcp/quelaton/DefaultFcpClientTest.java b/src/test/java/net/pterodactylus/fcp/quelaton/DefaultFcpClientTest.java index 7a43771..4c49f9f 100644 --- a/src/test/java/net/pterodactylus/fcp/quelaton/DefaultFcpClientTest.java +++ b/src/test/java/net/pterodactylus/fcp/quelaton/DefaultFcpClientTest.java @@ -1,21 +1,26 @@ package net.pterodactylus.fcp.quelaton; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import java.util.stream.Collectors; import net.pterodactylus.fcp.FcpKeyPair; import net.pterodactylus.fcp.Key; +import net.pterodactylus.fcp.Peer; import net.pterodactylus.fcp.Priority; import net.pterodactylus.fcp.fake.FakeTcpServer; import net.pterodactylus.fcp.quelaton.ClientGetCommand.Data; @@ -583,4 +588,38 @@ public class DefaultFcpClientTest { )); } + @Test + public void clientCanListPeers() throws IOException, ExecutionException, InterruptedException { + Future> peers = fcpClient.listPeers().execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + assertThat(lines, matchesFcpMessage( + "ListPeers", + "WithVolatile=false", + "WithMetadata=false", + "EndMessage" + )); + String identifier = extractIdentifier(lines); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "identity=id1", + "EndMessage" + ); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "identity=id2", + "EndMessage" + ); + fcpServer.writeLine( + "EndListPeers", + "Identifier=" + identifier, + "EndMessage" + ); + assertThat(peers.get(), hasSize(2)); + assertThat(peers.get().stream().map(Peer::getIdentity).collect(Collectors.toList()), + containsInAnyOrder("id1", "id2")); + } + } -- 2.7.4