diff options
Diffstat (limited to 'vespa-feed-client')
-rw-r--r-- | vespa-feed-client/src/main/java/ai/vespa/feed/client/FeedClientBuilder.java | 28 | ||||
-rw-r--r-- | vespa-feed-client/src/main/java/ai/vespa/feed/client/HttpFeedClient.java | 29 |
2 files changed, 47 insertions, 10 deletions
diff --git a/vespa-feed-client/src/main/java/ai/vespa/feed/client/FeedClientBuilder.java b/vespa-feed-client/src/main/java/ai/vespa/feed/client/FeedClientBuilder.java index 95a49abcc25..3cd3f3cb4ca 100644 --- a/vespa-feed-client/src/main/java/ai/vespa/feed/client/FeedClientBuilder.java +++ b/vespa-feed-client/src/main/java/ai/vespa/feed/client/FeedClientBuilder.java @@ -3,7 +3,10 @@ package ai.vespa.feed.client; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; +import java.io.IOException; +import java.io.UncheckedIOException; import java.net.URI; +import java.nio.file.Path; import java.util.HashMap; import java.util.Map; import java.util.function.Supplier; @@ -27,6 +30,9 @@ public class FeedClientBuilder { int maxConnections = 4; int maxStreamsPerConnection = 1024; FeedClient.RetryStrategy retryStrategy = defaultRetryStrategy; + Path certificate; + Path privateKey; + Path caCertificates; public static FeedClientBuilder create(URI endpoint) { return new FeedClientBuilder(endpoint); } @@ -63,6 +69,9 @@ public class FeedClientBuilder { } public FeedClientBuilder setSslContext(SSLContext context) { + if (certificate != null || caCertificates != null || privateKey != null) { + throw new IllegalArgumentException("Cannot set both SSLContext and certificate / CA certificates"); + } this.sslContext = requireNonNull(context); return this; } @@ -86,8 +95,25 @@ public class FeedClientBuilder { return this; } + public FeedClientBuilder setCertificate(Path certificatePemFile, Path privateKeyPemFile) { + if (sslContext != null) throw new IllegalArgumentException("Cannot set both SSLContext and certificate"); + this.certificate = certificatePemFile; + this.privateKey = privateKeyPemFile; + return this; + } + + public FeedClientBuilder setCaCertificates(Path caCertificatesFile) { + if (sslContext != null) throw new IllegalArgumentException("Cannot set both SSLContext and CA certificate"); + this.caCertificates = caCertificatesFile; + return this; + } + public FeedClient build() { - return new HttpFeedClient(this); + try { + return new HttpFeedClient(this); + } catch (IOException e) { + throw new UncheckedIOException(e); + } } } diff --git a/vespa-feed-client/src/main/java/ai/vespa/feed/client/HttpFeedClient.java b/vespa-feed-client/src/main/java/ai/vespa/feed/client/HttpFeedClient.java index 64b99961e61..98edc32a107 100644 --- a/vespa-feed-client/src/main/java/ai/vespa/feed/client/HttpFeedClient.java +++ b/vespa-feed-client/src/main/java/ai/vespa/feed/client/HttpFeedClient.java @@ -19,6 +19,7 @@ import org.apache.hc.core5.reactor.IOReactorConfig; import org.apache.hc.core5.util.TimeValue; import org.apache.hc.core5.util.Timeout; +import javax.net.ssl.SSLContext; import java.io.IOException; import java.io.UncheckedIOException; import java.net.URI; @@ -48,7 +49,7 @@ class HttpFeedClient implements FeedClient { private final CloseableHttpAsyncClient httpClient; private final AtomicBoolean closed = new AtomicBoolean(); - HttpFeedClient(FeedClientBuilder builder) { + HttpFeedClient(FeedClientBuilder builder) throws IOException { this.endpoint = builder.endpoint; this.requestHeaders = new HashMap<>(builder.requestHeaders); @@ -57,7 +58,7 @@ class HttpFeedClient implements FeedClient { this.httpClient.start(); } - private static CloseableHttpAsyncClient createHttpClient(FeedClientBuilder builder, HttpRequestStrategy retryStrategy) { + private static CloseableHttpAsyncClient createHttpClient(FeedClientBuilder builder, HttpRequestStrategy retryStrategy) throws IOException { HttpAsyncClientBuilder httpClientBuilder = HttpAsyncClientBuilder.create() .setUserAgent(String.format("vespa-feed-client/%s", Vespa.VERSION)) .setDefaultHeaders(Collections.singletonList(new BasicHeader("Vespa-Client-Version", Vespa.VERSION))) @@ -86,18 +87,28 @@ class HttpFeedClient implements FeedClient { .setMaxConnTotal(builder.maxConnections) .setMaxConnPerRoute(builder.maxConnections) .setPoolConcurrencyPolicy(PoolConcurrencyPolicy.LAX); - if (builder.sslContext != null) { - ClientTlsStrategyBuilder tlsStrategyBuilder = ClientTlsStrategyBuilder.create() - .setSslContext(builder.sslContext); - if (builder.hostnameVerifier != null) { - tlsStrategyBuilder.setHostnameVerifier(builder.hostnameVerifier); - } - connectionManagerBuilder.setTlsStrategy(tlsStrategyBuilder.build()); + ClientTlsStrategyBuilder tlsStrategyBuilder = ClientTlsStrategyBuilder.create() + .setSslContext(constructSslContext(builder)); + if (builder.hostnameVerifier != null) { + tlsStrategyBuilder.setHostnameVerifier(builder.hostnameVerifier); } + connectionManagerBuilder.setTlsStrategy(tlsStrategyBuilder.build()); httpClientBuilder.setConnectionManager(connectionManagerBuilder.build()); return httpClientBuilder.build(); } + private static SSLContext constructSslContext(FeedClientBuilder builder) throws IOException { + if (builder.sslContext != null) return builder.sslContext; + SslContextBuilder sslContextBuilder = new SslContextBuilder(); + if (builder.certificate != null && builder.privateKey != null) { + sslContextBuilder.withCertificateAndKey(builder.certificate, builder.privateKey); + } + if (builder.caCertificates != null) { + sslContextBuilder.withCaCertificates(builder.caCertificates); + } + return sslContextBuilder.build(); + } + @Override public CompletableFuture<Result> put(DocumentId documentId, String documentJson, OperationParameters params) { return send("POST", documentId, requireNonNull(documentJson), params); |