dc6d9502a9c71734d1f135be9b5583fc3293f3e0
[jFCPlib.git] / src / main / java / net / pterodactylus / fcp / quelaton / DefaultFcpClient.java
1 package net.pterodactylus.fcp.quelaton;
2
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;
8
9 import net.pterodactylus.fcp.FcpConnection;
10
11 import com.google.common.util.concurrent.ListeningExecutorService;
12 import com.google.common.util.concurrent.MoreExecutors;
13
14 /**
15  * Default {@link FcpClient} implementation.
16  *
17  * @author <a href="bombe@freenetproject.org">David ‘Bombe’ Roden</a>
18  */
19 public class DefaultFcpClient implements FcpClient {
20
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);
28
29         public DefaultFcpClient(ExecutorService threadPool, String hostname, int port, Supplier<String> clientName) {
30                 this.threadPool = MoreExecutors.listeningDecorator(threadPool);
31                 this.hostname = hostname;
32                 this.port = port;
33                 this.clientName = clientName;
34         }
35
36         private FcpConnection connect() throws IOException {
37                 FcpConnection fcpConnection = this.fcpConnection.get();
38                 if ((fcpConnection != null) && !fcpConnection.isClosed()) {
39                         return fcpConnection;
40                 }
41                 fcpConnection = createConnection();
42                 this.fcpConnection.set(fcpConnection);
43                 try {
44                         activeSubscriptions.renew(fcpConnection::addFcpListener, this::subscribeUsk);
45                 } catch (InterruptedException | ExecutionException e) {
46                         throw new IOException(e);
47                 }
48                 return fcpConnection;
49         }
50
51         private FcpConnection createConnection() throws IOException {
52                 try {
53                         return new ClientHelloImpl(threadPool, hostname, port).withName(clientName.get()).execute().get();
54                 } catch (InterruptedException | ExecutionException e) {
55                         throw new IOException(e);
56                 }
57         }
58
59         @Override
60         public GetNodeCommand getNode() {
61                 return new GetNodeCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
62         }
63
64         @Override
65         public GetConfigCommand getConfig() {
66                 return new GetConfigCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
67         }
68
69         @Override
70         public ModifyConfigCommand modifyConfig() {
71                 return new ModifyConfigCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
72         }
73
74         @Override
75         public GenerateKeypairCommand generateKeypair() {
76                 return new GenerateKeypairCommandImpl(threadPool, this::connect);
77         }
78
79         @Override
80         public ClientGetCommand clientGet() {
81                 return new ClientGetCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
82         }
83
84         @Override
85         public ClientPutCommand clientPut() {
86                 return new ClientPutCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
87         }
88
89         @Override
90         public ListPeerCommand listPeer() {
91                 return new ListPeerCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
92         }
93
94         @Override
95         public ListPeersCommand listPeers() {
96                 return new ListPeersCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
97         }
98
99         @Override
100         public AddPeerCommand addPeer() {
101                 return new AddPeerCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
102         }
103
104         @Override
105         public ModifyPeerCommand modifyPeer() {
106                 return new ModifyPeerCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
107         }
108
109         @Override
110         public RemovePeerCommand removePeer() {
111                 return new RemovePeerCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
112         }
113
114         @Override
115         public ListPeerNotesCommand listPeerNotes() {
116                 return new ListPeerNotesCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
117         }
118
119         @Override
120         public ModifyPeerNoteCommand modifyPeerNote() {
121                 return new ModifyPeerNoteCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
122         }
123
124         @Override
125         public LoadPluginCommand loadPlugin() {
126                 return new LoadPluginCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
127         }
128
129         @Override
130         public ReloadPluginCommand reloadPlugin() {
131                 return new ReloadPluginCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
132         }
133
134         @Override
135         public RemovePluginCommand removePlugin() {
136                 return new RemovePluginCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
137         }
138
139         @Override
140         public GetPluginInfoCommand getPluginInfo() {
141                 return new GetPluginInfoCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
142         }
143
144         @Override
145         public SubscribeUskCommand subscribeUsk() {
146                 return new SubscribeUskCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate, activeSubscriptions);
147         }
148
149         private UnsubscribeUskCommand unsubscribeUsk() {
150                 return new UnsubscribeUskCommandImpl(threadPool, this::connect, randomIdentifierGenerator::generate);
151         }
152
153 }
154