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 ListeningExecutorService threadPool;
22 private final String hostname;
23 private final int port;
24 private final AtomicReference<FcpConnection> fcpConnection = new AtomicReference<>();
25 private final Supplier<String> clientName;
26 private final ActiveSubscriptions activeSubscriptions = new ActiveSubscriptions(this::unsubscribeUsk);
28 public DefaultFcpClient(ExecutorService threadPool, String hostname, int port, Supplier<String> clientName) {
29 this.threadPool = MoreExecutors.listeningDecorator(threadPool);
30 this.hostname = hostname;
32 this.clientName = clientName;
35 private FcpConnection connect() throws IOException {
36 FcpConnection fcpConnection = this.fcpConnection.get();
37 if ((fcpConnection != null) && !fcpConnection.isClosed()) {
40 fcpConnection = createConnection();
41 this.fcpConnection.set(fcpConnection);
43 activeSubscriptions.renew(fcpConnection::addFcpListener, this::subscribeUsk);
44 } catch (InterruptedException | ExecutionException e) {
45 throw new IOException(e);
50 private FcpConnection createConnection() throws IOException {
52 return new ClientHelloImpl(threadPool, hostname, port).withName(clientName.get()).execute().get();
53 } catch (InterruptedException | ExecutionException e) {
54 throw new IOException(e);
59 public GetNodeCommand getNode() {
60 return new GetNodeCommandImpl(threadPool, this::connect);
64 public GetConfigCommand getConfig() {
65 return new GetConfigCommandImpl(threadPool, this::connect);
69 public ModifyConfigCommand modifyConfig() {
70 return new ModifyConfigCommandImpl(threadPool, this::connect);
74 public GenerateKeypairCommand generateKeypair() {
75 return new GenerateKeypairCommandImpl(threadPool, this::connect);
79 public ClientGetCommand clientGet() {
80 return new ClientGetCommandImpl(threadPool, this::connect);
84 public ClientPutCommand clientPut() {
85 return new ClientPutCommandImpl(threadPool, this::connect);
89 public ListPeerCommand listPeer() {
90 return new ListPeerCommandImpl(threadPool, this::connect);
94 public ListPeersCommand listPeers() {
95 return new ListPeersCommandImpl(threadPool, this::connect);
99 public AddPeerCommand addPeer() {
100 return new AddPeerCommandImpl(threadPool, this::connect);
104 public ModifyPeerCommand modifyPeer() {
105 return new ModifyPeerCommandImpl(threadPool, this::connect);
109 public RemovePeerCommand removePeer() {
110 return new RemovePeerCommandImpl(threadPool, this::connect);
114 public ListPeerNotesCommand listPeerNotes() {
115 return new ListPeerNotesCommandImpl(threadPool, this::connect);
119 public ModifyPeerNoteCommand modifyPeerNote() {
120 return new ModifyPeerNoteCommandImpl(threadPool, this::connect);
124 public LoadPluginCommand loadPlugin() {
125 return new LoadPluginCommandImpl(threadPool, this::connect);
129 public ReloadPluginCommand reloadPlugin() {
130 return new ReloadPluginCommandImpl(threadPool, this::connect);
134 public RemovePluginCommand removePlugin() {
135 return new RemovePluginCommandImpl(threadPool, this::connect);
139 public GetPluginInfoCommand getPluginInfo() {
140 return new GetPluginInfoCommandImpl(threadPool, this::connect);
144 public SubscribeUskCommand subscribeUsk() {
145 return new SubscribeUskCommandImpl(threadPool, this::connect, activeSubscriptions);
148 private UnsubscribeUskCommand unsubscribeUsk() {
149 return new UnsubscribeUskCommandImpl(threadPool, this::connect);