1 package net.pterodactylus.fcp.quelaton;
3 import java.io.IOException;
4 import java.util.concurrent.ExecutionException;
5 import java.util.concurrent.ExecutorService;
6 import java.util.concurrent.atomic.AtomicReference;
7 import java.util.function.Supplier;
9 import net.pterodactylus.fcp.FcpConnection;
11 import com.google.common.util.concurrent.ListeningExecutorService;
12 import com.google.common.util.concurrent.MoreExecutors;
15 * Default {@link FcpClient} implementation.
17 * @author <a href="bombe@freenetproject.org">David ‘Bombe’ Roden</a>
19 public class DefaultFcpClient implements FcpClient {
21 private final RandomIdentifierGenerator randomIdentifierGenerator = new RandomIdentifierGenerator();
22 private final ListeningExecutorService threadPool;
23 private final String hostname;
24 private final int port;
25 private final AtomicReference<FcpConnection> fcpConnection = new AtomicReference<>();
26 private final Supplier<String> clientName;
27 private final ActiveSubscriptions activeSubscriptions = new ActiveSubscriptions(this::unsubscribeUsk);
29 public DefaultFcpClient(ExecutorService threadPool, String hostname, int port, Supplier<String> clientName) {
30 this.threadPool = MoreExecutors.listeningDecorator(threadPool);
31 this.hostname = hostname;
33 this.clientName = clientName;
36 private FcpConnection connect() throws IOException {
37 FcpConnection fcpConnection = this.fcpConnection.get();
38 if ((fcpConnection != null) && !fcpConnection.isClosed()) {
41 fcpConnection = createConnection();
42 this.fcpConnection.set(fcpConnection);
44 activeSubscriptions.renew(fcpConnection::addFcpListener, this::subscribeUsk);
45 } catch (InterruptedException | ExecutionException e) {
46 throw new IOException(e);
51 private FcpConnection createConnection() throws IOException {
53 return new ClientHelloImpl(threadPool, hostname, port).withName(clientName.get()).execute().get();
54 } catch (InterruptedException | ExecutionException e) {
55 throw new IOException(e);
60 public GetNodeCommand getNode() {
61 return new GetNodeCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
65 public GetConfigCommand getConfig() {
66 return new GetConfigCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
70 public ModifyConfigCommand modifyConfig() {
71 return new ModifyConfigCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
75 public GenerateKeypairCommand generateKeypair() {
76 return new GenerateKeypairCommandImpl(threadPool, this::connect);
80 public ClientGetCommand clientGet() {
81 return new ClientGetCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
85 public ClientPutCommand clientPut() {
86 return new ClientPutCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
90 public ClientPutDiskDirCommand clientPutDiskDir() {
91 return new ClientPutDiskDirCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
95 public ListPeerCommand listPeer() {
96 return new ListPeerCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
100 public ListPeersCommand listPeers() {
101 return new ListPeersCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
105 public AddPeerCommand addPeer() {
106 return new AddPeerCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
110 public ModifyPeerCommand modifyPeer() {
111 return new ModifyPeerCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
115 public RemovePeerCommand removePeer() {
116 return new RemovePeerCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
120 public ListPeerNotesCommand listPeerNotes() {
121 return new ListPeerNotesCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
125 public ModifyPeerNoteCommand modifyPeerNote() {
126 return new ModifyPeerNoteCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
130 public LoadPluginCommand loadPlugin() {
131 return new LoadPluginCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
135 public ReloadPluginCommand reloadPlugin() {
136 return new ReloadPluginCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
140 public RemovePluginCommand removePlugin() {
141 return new RemovePluginCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
145 public GetPluginInfoCommand getPluginInfo() {
146 return new GetPluginInfoCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
150 public SubscribeUskCommand subscribeUsk() {
151 return new SubscribeUskCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate, activeSubscriptions);
154 private UnsubscribeUskCommand unsubscribeUsk() {
155 return new UnsubscribeUskCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);