001package com.quorum.tessera.config.builder;
002
003import com.quorum.tessera.config.*;
004
005import java.io.IOException;
006import java.nio.file.Files;
007import java.nio.file.Path;
008import java.nio.file.Paths;
009import java.util.*;
010import java.util.stream.Collectors;
011
012import static com.quorum.tessera.config.AppType.P2P;
013import static com.quorum.tessera.config.AppType.Q2T;
014import static com.quorum.tessera.config.CommunicationType.REST;
015import static java.util.Collections.emptyList;
016
017public class ConfigBuilder {
018
019    private ConfigBuilder() {}
020
021    public static ConfigBuilder create() {
022        return new ConfigBuilder();
023    }
024
025    private String serverHostname;
026
027    private Integer serverPort = 0;
028
029    private JdbcConfig jdbcConfig;
030
031    private String unixSocketFile;
032
033    private List<String> peers;
034
035    private List<String> alwaysSendTo;
036
037    private KeyConfiguration keyData;
038
039    private SslAuthenticationMode sslAuthenticationMode;
040
041    private SslTrustMode sslServerTrustMode;
042
043    private String sslServerKeyStorePath;
044
045    private char[] sslServerTrustStorePassword;
046
047    private char[] sslServerKeyStorePassword;
048
049    private String sslServerTrustStorePath;
050
051    private List<String> sslServerTrustCertificates = emptyList();
052
053    private String sslClientKeyStorePath;
054
055    private char[] sslClientKeyStorePassword;
056
057    private char[] sslClientTrustStorePassword;
058
059    private String sslClientTrustStorePath;
060
061    private List<String> sslClientTrustCertificates = emptyList();
062
063    private SslTrustMode sslClientTrustMode;
064
065    private String sslKnownClientsFile;
066
067    private String sslKnownServersFile;
068
069    private String sslServerTlsKeyPath;
070
071    private String sslServerTlsCertificatePath;
072
073    private String sslClientTlsKeyPath;
074
075    private String sslClientTlsCertificatePath;
076
077    private boolean useWhiteList;
078
079    private String workDir;
080
081    public ConfigBuilder sslServerTrustMode(SslTrustMode sslServerTrustMode) {
082        this.sslServerTrustMode = sslServerTrustMode;
083        return this;
084    }
085
086    public ConfigBuilder sslClientTrustMode(SslTrustMode sslClientTrustMode) {
087        this.sslClientTrustMode = sslClientTrustMode;
088        return this;
089    }
090
091    public ConfigBuilder sslServerKeyStorePath(String sslServerKeyStorePath) {
092        this.sslServerKeyStorePath = sslServerKeyStorePath;
093        return this;
094    }
095
096    public ConfigBuilder sslServerTrustStorePath(String sslServerTrustStorePath) {
097        this.sslServerTrustStorePath = sslServerTrustStorePath;
098        return this;
099    }
100
101    public ConfigBuilder sslServerTrustCertificates(List<String> sslServerTrustCertificates) {
102        this.sslServerTrustCertificates = sslServerTrustCertificates;
103        return this;
104    }
105
106    public ConfigBuilder sslClientTrustStorePassword(char[] sslClientTrustStorePassword) {
107        this.sslClientTrustStorePassword = sslClientTrustStorePassword;
108        return this;
109    }
110
111    public ConfigBuilder unixSocketFile(String unixSocketFile) {
112        this.unixSocketFile = unixSocketFile;
113        return this;
114    }
115
116    public ConfigBuilder serverHostname(String serverHostname) {
117        this.serverHostname = serverHostname;
118        return this;
119    }
120
121    public ConfigBuilder serverPort(Integer serverPort) {
122        this.serverPort = serverPort;
123        return this;
124    }
125
126    public ConfigBuilder jdbcConfig(JdbcConfig jdbcConfig) {
127        this.jdbcConfig = jdbcConfig;
128        return this;
129    }
130
131    public ConfigBuilder peers(List<String> peers) {
132        this.peers = peers;
133        return this;
134    }
135
136    public ConfigBuilder alwaysSendTo(List<String> alwaysSendTo) {
137        this.alwaysSendTo = alwaysSendTo;
138        return this;
139    }
140
141    public ConfigBuilder sslKnownClientsFile(String knownClientsFile) {
142        this.sslKnownClientsFile = knownClientsFile;
143        return this;
144    }
145
146    public ConfigBuilder sslKnownServersFile(String knownServersFile) {
147        this.sslKnownServersFile = knownServersFile;
148        return this;
149    }
150
151    public ConfigBuilder sslAuthenticationMode(SslAuthenticationMode sslAuthenticationMode) {
152        this.sslAuthenticationMode = sslAuthenticationMode;
153        return this;
154    }
155
156    public ConfigBuilder sslClientKeyStorePath(String sslClientKeyStorePath) {
157        this.sslClientKeyStorePath = sslClientKeyStorePath;
158        return this;
159    }
160
161    public ConfigBuilder sslClientTrustCertificates(List<String> sslClientTrustCertificates) {
162        this.sslClientTrustCertificates = sslClientTrustCertificates;
163        return this;
164    }
165
166    public ConfigBuilder sslClientTrustStorePath(String sslClientTrustStorePath) {
167        this.sslClientTrustStorePath = sslClientTrustStorePath;
168        return this;
169    }
170
171    public ConfigBuilder sslClientKeyStorePassword(char[] sslClientKeyStorePassword) {
172        this.sslClientKeyStorePassword = sslClientKeyStorePassword;
173        return this;
174    }
175
176    public ConfigBuilder sslServerTlsKeyPath(String sslServerTlsKeyPath) {
177        this.sslServerTlsKeyPath = sslServerTlsKeyPath;
178        return this;
179    }
180
181    public ConfigBuilder sslServerTlsCertificatePath(String sslServerTlsCertificatePath) {
182        this.sslServerTlsCertificatePath = sslServerTlsCertificatePath;
183        return this;
184    }
185
186    public ConfigBuilder sslClientTlsKeyPath(String sslClientTlsKeyPath) {
187        this.sslClientTlsKeyPath = sslClientTlsKeyPath;
188        return this;
189    }
190
191    public ConfigBuilder sslClientTlsCertificatePath(String sslClientTlsCertificatePath) {
192        this.sslClientTlsCertificatePath = sslClientTlsCertificatePath;
193        return this;
194    }
195
196    public ConfigBuilder keyData(KeyConfiguration keyData) {
197        this.keyData = keyData;
198        return this;
199    }
200
201    public ConfigBuilder useWhiteList(boolean useWhiteList) {
202        this.useWhiteList = useWhiteList;
203        return this;
204    }
205
206    public ConfigBuilder workdir(String workDir) {
207        this.workDir = workDir;
208        return this;
209    }
210
211    static Path toPath(final String workDir, final String value) {
212        if (workDir != null && value != null) {
213            return Paths.get(workDir, value);
214        } else if (value != null) {
215            return Paths.get(value);
216        }
217        return null;
218    }
219
220    public Config build() {
221
222        boolean generateKeyStoreIfNotExisted = false;
223
224        SslConfig sslConfig =
225                new SslConfig(
226                        sslAuthenticationMode,
227                        generateKeyStoreIfNotExisted,
228                        toPath(workDir, sslServerKeyStorePath),
229                        sslServerKeyStorePassword,
230                        toPath(workDir, sslServerTrustStorePath),
231                        sslServerTrustStorePassword,
232                        sslServerTrustMode,
233                        toPath(workDir, sslClientKeyStorePath),
234                        sslClientKeyStorePassword,
235                        toPath(workDir, sslClientTrustStorePath),
236                        sslClientTrustStorePassword,
237                        sslClientTrustMode,
238                        toPath(workDir, sslKnownClientsFile),
239                        toPath(workDir, sslKnownServersFile),
240                        sslServerTrustCertificates.stream()
241                                .filter(Objects::nonNull)
242                                .map(v -> toPath(workDir, v))
243                                .collect(Collectors.toList()),
244                        sslClientTrustCertificates.stream()
245                                .filter(Objects::nonNull)
246                                .map(v -> toPath(workDir, v))
247                                .collect(Collectors.toList()),
248                        toPath(workDir, sslServerTlsKeyPath),
249                        toPath(workDir, sslServerTlsCertificatePath),
250                        toPath(workDir, sslClientTlsKeyPath),
251                        toPath(workDir, sslClientTlsCertificatePath),
252                        null);
253
254        final String unixPath =
255                Optional.ofNullable(toPath(workDir, unixSocketFile))
256                        .map(Path::toAbsolutePath)
257                        .map(Path::toString)
258                        .map("unix:"::concat)
259                        .orElse(null);
260        final ServerConfig q2tConfig = new ServerConfig(Q2T, unixPath, REST, null, null, null);
261
262        final String address = (serverHostname == null) ? null : serverHostname + ":" + serverPort;
263        final ServerConfig p2pConfig = new ServerConfig(P2P, address, REST, sslConfig, null, address);
264
265        final List<Peer> peerList;
266        if (peers != null) {
267            peerList = peers.stream().map(Peer::new).collect(Collectors.toList());
268        } else {
269            peerList = null;
270        }
271
272        final List<String> forwardingKeys = new ArrayList<>();
273        if (alwaysSendTo != null) {
274            for (String keyPath : alwaysSendTo) {
275                try {
276                    List<String> keysFromFile = Files.readAllLines(toPath(workDir, keyPath));
277                    forwardingKeys.addAll(keysFromFile);
278                } catch (IOException e) {
279                    System.err.println("Error reading alwayssendto file: " + e.getMessage());
280                }
281            }
282        }
283
284        final Config config = new Config();
285        config.setServerConfigs(Arrays.asList(q2tConfig, p2pConfig));
286        config.setEncryptor(
287                new EncryptorConfig() {
288                    {
289                        setType(EncryptorType.NACL);
290                    }
291                });
292
293        config.setJdbcConfig(jdbcConfig);
294        config.setPeers(peerList);
295        config.setAlwaysSendTo(forwardingKeys);
296        config.setUseWhiteList(useWhiteList);
297        config.setKeys(keyData);
298        config.setDisablePeerDiscovery(false);
299        return config;
300    }
301}