summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Marius Venstad <jonmv@users.noreply.github.com>2021-05-11 14:19:01 +0200
committerGitHub <noreply@github.com>2021-05-11 14:19:01 +0200
commit016ed26d34ea0582e0e11ffc9ada76ff79a5d889 (patch)
tree33e4f4a39717e8deebc170a42656c2b18b662f4b
parent4ae244bc86782b3dc36257edcfabc2e38f510cf7 (diff)
parent7ac7e6e3c39fd80b24c38561949466e4fc00921a (diff)
Merge pull request #17818 from vespa-engine/bjorncs/vespa-feed-client
Bjorncs/vespa feed client
-rw-r--r--vespa-feed-client/pom.xml21
-rw-r--r--vespa-feed-client/src/main/java/com/yahoo/vespa/feed/client/FeedClient.java4
-rw-r--r--vespa-feed-client/src/main/java/com/yahoo/vespa/feed/client/FeedClientBuilder.java30
-rw-r--r--vespa-feed-client/src/main/java/com/yahoo/vespa/feed/client/HttpFeedClient.java73
-rwxr-xr-xvespa-feed-client/src/main/sh/vespa-version-generator.sh24
5 files changed, 151 insertions, 1 deletions
diff --git a/vespa-feed-client/pom.xml b/vespa-feed-client/pom.xml
index 32b44012107..d0b0066f07e 100644
--- a/vespa-feed-client/pom.xml
+++ b/vespa-feed-client/pom.xml
@@ -70,6 +70,27 @@
</compilerArgs>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>generate-simplified-vtag</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>exec</goal>
+ </goals>
+ <configuration>
+ <executable>src/main/sh/vespa-version-generator.sh</executable>
+ <arguments>
+ <argument>${project.basedir}/../dist/vtag.map</argument>
+ <argument>${project.build.directory}/generated-sources/vespa-version/com/yahoo/vespa/feed/client/Vespa.java</argument>
+ </arguments>
+ <sourceRoot>${project.build.directory}/generated-sources/vespa-version</sourceRoot>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
</project>
diff --git a/vespa-feed-client/src/main/java/com/yahoo/vespa/feed/client/FeedClient.java b/vespa-feed-client/src/main/java/com/yahoo/vespa/feed/client/FeedClient.java
index af652401044..2233b0a1a39 100644
--- a/vespa-feed-client/src/main/java/com/yahoo/vespa/feed/client/FeedClient.java
+++ b/vespa-feed-client/src/main/java/com/yahoo/vespa/feed/client/FeedClient.java
@@ -1,12 +1,13 @@
// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.feed.client;
+import java.io.Closeable;
import java.util.concurrent.Future;
/**
* @author bjorncs
*/
-public interface FeedClient {
+public interface FeedClient extends Closeable {
Future<Result> put(String documentId, String documentJson, OperationParameters params, ResultCallback callback);
Future<Result> remove(String documentId, OperationParameters params, ResultCallback callback);
Future<Result> update(String documentId, String documentJson, OperationParameters params, ResultCallback callback);
@@ -15,4 +16,5 @@ public interface FeedClient {
void completed(Result result);
void failed(FeedException e);
}
+
}
diff --git a/vespa-feed-client/src/main/java/com/yahoo/vespa/feed/client/FeedClientBuilder.java b/vespa-feed-client/src/main/java/com/yahoo/vespa/feed/client/FeedClientBuilder.java
index e49d253a321..9e5f2a53a8d 100644
--- a/vespa-feed-client/src/main/java/com/yahoo/vespa/feed/client/FeedClientBuilder.java
+++ b/vespa-feed-client/src/main/java/com/yahoo/vespa/feed/client/FeedClientBuilder.java
@@ -1,14 +1,44 @@
// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.feed.client;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Supplier;
+
/**
+ * Builder for creating a {@link FeedClient} instance.
+ *
* @author bjorncs
*/
public class FeedClientBuilder {
+ SSLContext sslContext;
+ HostnameVerifier hostnameVerifier;
+ final Map<String, Supplier<String>> requestHeaders = new HashMap<>();
+ URI endpoint;
+ Integer maxConnections;
+
public static FeedClientBuilder create() { return new FeedClientBuilder(); }
private FeedClientBuilder() {}
+ public FeedClientBuilder setMaxConnection(int max) { this.maxConnections = max; return this; }
+
+ public FeedClientBuilder setEndpoint(URI endpoint) { this.endpoint = endpoint; return this; }
+
+ public FeedClientBuilder setSslContext(SSLContext context) { this.sslContext = context; return this; }
+
+ public FeedClientBuilder setHostnameVerifier(HostnameVerifier verifier) { this.hostnameVerifier = verifier; return this; }
+
+ public FeedClientBuilder addRequestHeader(String name, String value) { return addRequestHeader(name, () -> value); }
+
+ public FeedClientBuilder addRequestHeader(String name, Supplier<String> valueSupplier) {
+ this.requestHeaders.put(name, valueSupplier);
+ return this;
+ }
+
public FeedClient build() { return new HttpFeedClient(this); }
}
diff --git a/vespa-feed-client/src/main/java/com/yahoo/vespa/feed/client/HttpFeedClient.java b/vespa-feed-client/src/main/java/com/yahoo/vespa/feed/client/HttpFeedClient.java
index 6cf56ac9cdd..a7e39001117 100644
--- a/vespa-feed-client/src/main/java/com/yahoo/vespa/feed/client/HttpFeedClient.java
+++ b/vespa-feed-client/src/main/java/com/yahoo/vespa/feed/client/HttpFeedClient.java
@@ -1,15 +1,85 @@
// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.feed.client;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
+import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
+import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
+import org.apache.hc.client5.http.ssl.ClientTlsStrategyBuilder;
+import org.apache.hc.core5.http.message.BasicHeader;
+import org.apache.hc.core5.http2.config.H2Config;
+import org.apache.hc.core5.pool.PoolConcurrencyPolicy;
+import org.apache.hc.core5.reactor.IOReactorConfig;
+import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import java.util.concurrent.Future;
+import java.util.function.Supplier;
/**
+ * HTTP implementation of {@link FeedClient}
+ *
* @author bjorncs
*/
class HttpFeedClient implements FeedClient {
+ private final CloseableHttpAsyncClient httpClient;
+ private final URI endpoint;
+ private final Map<String, Supplier<String>> requestHeaders;
+
HttpFeedClient(FeedClientBuilder builder) {
+ this.httpClient = createHttpClient(builder);
+ this.endpoint = getEndpoint(builder);
+ this.requestHeaders = new HashMap<>(builder.requestHeaders);
+ }
+
+ private static CloseableHttpAsyncClient createHttpClient(FeedClientBuilder builder) {
+ HttpAsyncClientBuilder httpClientBuilder = HttpAsyncClientBuilder.create()
+ .setUserAgent(String.format("vespa-feed-client/%s", Vespa.VERSION))
+ .setDefaultHeaders(Collections.singletonList(new BasicHeader("Vespa-Client-Version", Vespa.VERSION)))
+ .disableCookieManagement()
+ .disableRedirectHandling()
+ .disableConnectionState()
+ .setIOReactorConfig(IOReactorConfig.custom()
+ .setSoTimeout(Timeout.ofSeconds(10))
+ .build())
+ .setDefaultRequestConfig(
+ RequestConfig.custom()
+ .setConnectTimeout(Timeout.ofSeconds(10))
+ .setConnectionRequestTimeout(Timeout.DISABLED)
+ .setResponseTimeout(Timeout.ofMinutes(5))
+ .build())
+ .setH2Config(H2Config.custom()
+ .setMaxConcurrentStreams(128)
+ .setPushEnabled(false)
+ .build());
+ int maxConnections = builder.maxConnections != null ? builder.maxConnections : 4;
+ PoolingAsyncClientConnectionManagerBuilder connectionManagerBuilder = PoolingAsyncClientConnectionManagerBuilder.create()
+ .setConnectionTimeToLive(TimeValue.ofMinutes(10))
+ .setMaxConnTotal(maxConnections)
+ .setMaxConnPerRoute(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());
+ }
+ httpClientBuilder.setConnectionManager(connectionManagerBuilder.build());
+ return httpClientBuilder.build();
+ }
+
+ private static URI getEndpoint(FeedClientBuilder builder) {
+ if (builder.endpoint == null) throw new IllegalArgumentException("Endpoint must be specified");
+ return builder.endpoint;
}
@Override
@@ -26,4 +96,7 @@ class HttpFeedClient implements FeedClient {
public Future<Result> update(String documentId, String documentJson, OperationParameters params, ResultCallback callback) {
return null;
}
+
+ @Override public void close() throws IOException { this.httpClient.close(); }
+
}
diff --git a/vespa-feed-client/src/main/sh/vespa-version-generator.sh b/vespa-feed-client/src/main/sh/vespa-version-generator.sh
new file mode 100755
index 00000000000..d8f5878e2c5
--- /dev/null
+++ b/vespa-feed-client/src/main/sh/vespa-version-generator.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+# Extracts the current version number (V_TAG_COMPONENT) from vtag.map and outputs this into a Java class.
+# This replaces vespajlib/../VersionTagger.java as this module cannot depend on that, nor the dependencies
+# of the resulting class.
+#
+# Author: bjorncs
+
+source=$1
+destination=$2
+destinationDir=$(dirname $destination)
+
+mkdir -p $destinationDir
+
+versionNumber=$(cat $source | grep V_TAG_COMPONENT | awk '{print $2}' )
+
+cat > $destination <<- END
+package com.yahoo.vespa.feed.client;
+
+class Vespa {
+ static final String VERSION = "$versionNumber";
+}
+END