aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Marius Venstad <jonmv@users.noreply.github.com>2021-05-25 18:56:36 +0200
committerGitHub <noreply@github.com>2021-05-25 18:56:36 +0200
commitb419ca923a7a3dd05087d2d28c7481cf144024a5 (patch)
treee8c54d18f522a017b066de57cfb07db6fb9fb79d
parent8e3d515ff5c5c58ce6e7ae16ac386f9e4655494c (diff)
parent6115afc38ac577eea18c63d33ebc9d5b0193dcb3 (diff)
Merge pull request #17971 from vespa-engine/bjorncs/vespa-feed-client-cli
Bjorncs/vespa feed client cli
-rw-r--r--CMakeLists.txt1
-rw-r--r--dist/vespa.spec2
-rw-r--r--pom.xml1
-rw-r--r--vespa-feed-client-cli/CMakeLists.txt4
-rw-r--r--vespa-feed-client-cli/OWNERS2
-rw-r--r--vespa-feed-client-cli/pom.xml87
-rw-r--r--vespa-feed-client-cli/src/main/java/ai/vespa/feed/client/CliArguments.java (renamed from vespa-feed-client/src/main/java/ai/vespa/feed/client/CliArguments.java)0
-rw-r--r--vespa-feed-client-cli/src/main/java/ai/vespa/feed/client/CliClient.java (renamed from vespa-feed-client/src/main/java/ai/vespa/feed/client/CliClient.java)6
-rwxr-xr-xvespa-feed-client-cli/src/main/sh/vespa-feed-client.sh (renamed from vespa-feed-client/src/main/sh/vespa-feed-client.sh)2
-rw-r--r--vespa-feed-client-cli/src/test/java/ai/vespa/feed/client/CliArgumentsTest.java (renamed from vespa-feed-client/src/test/java/ai/vespa/feed/client/CliArgumentsTest.java)0
-rw-r--r--vespa-feed-client-cli/src/test/resources/help.txt (renamed from vespa-feed-client/src/test/resources/help.txt)0
-rw-r--r--vespa-feed-client/CMakeLists.txt3
-rw-r--r--vespa-feed-client/pom.xml28
-rw-r--r--vespa-feed-client/src/main/java/ai/vespa/feed/client/FeedClientBuilder.java28
-rw-r--r--vespa-feed-client/src/main/java/ai/vespa/feed/client/HttpFeedClient.java29
15 files changed, 147 insertions, 46 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1045f6270c8..7bf698b7a98 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -136,6 +136,7 @@ add_subdirectory(vdslib)
add_subdirectory(vdstestlib)
add_subdirectory(vespa-athenz)
add_subdirectory(vespa-feed-client)
+add_subdirectory(vespa-feed-client-cli)
add_subdirectory(vespa-http-client)
add_subdirectory(vespa-osgi-testrunner)
add_subdirectory(vespa-testrunner-components)
diff --git a/dist/vespa.spec b/dist/vespa.spec
index 3a3c46dba8c..de92077fdbd 100644
--- a/dist/vespa.spec
+++ b/dist/vespa.spec
@@ -728,7 +728,7 @@ fi
%dir %{_prefix}/lib/jars
%{_prefix}/bin/vespa-feed-client
%{_prefix}/lib/jars/vespa-http-client-jar-with-dependencies.jar
-%{_prefix}/lib/jars/vespa-feed-client-jar-with-dependencies.jar
+%{_prefix}/lib/jars/vespa-feed-client-cli.jar
%files config-model-fat
%if %{_defattr_is_vespa_vespa}
diff --git a/pom.xml b/pom.xml
index c77842a149d..82d9efbb70e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -133,6 +133,7 @@
<module>vespa-athenz</module>
<module>vespa-documentgen-plugin</module>
<module>vespa-feed-client</module>
+ <module>vespa-feed-client-cli</module>
<module>vespa-hadoop</module>
<module>vespa-http-client</module>
<module>vespa-maven-plugin</module>
diff --git a/vespa-feed-client-cli/CMakeLists.txt b/vespa-feed-client-cli/CMakeLists.txt
new file mode 100644
index 00000000000..a918981dcd3
--- /dev/null
+++ b/vespa-feed-client-cli/CMakeLists.txt
@@ -0,0 +1,4 @@
+# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+install_java_artifact(vespa-feed-client-cli)
+
+vespa_install_script(src/main/sh/vespa-feed-client.sh vespa-feed-client bin)
diff --git a/vespa-feed-client-cli/OWNERS b/vespa-feed-client-cli/OWNERS
new file mode 100644
index 00000000000..606d074d8a8
--- /dev/null
+++ b/vespa-feed-client-cli/OWNERS
@@ -0,0 +1,2 @@
+bjorncs
+jonmv
diff --git a/vespa-feed-client-cli/pom.xml b/vespa-feed-client-cli/pom.xml
new file mode 100644
index 00000000000..62ff5c149ec
--- /dev/null
+++ b/vespa-feed-client-cli/pom.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0"?>
+<!-- Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>parent</artifactId>
+ <version>7-SNAPSHOT</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+ <artifactId>vespa-feed-client-cli</artifactId>
+ <packaging>jar</packaging>
+ <version>7-SNAPSHOT</version>
+
+ <properties>
+ <maven.javadoc.skip>true</maven.javadoc.skip>
+ <!-- Used by internal properties that are still using JDK8-->
+ <maven.compiler.release>8</maven.compiler.release>
+ </properties>
+
+ <dependencies>
+ <!-- compile scope -->
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>vespa-feed-client</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ <scope>compile</scope>
+ </dependency>
+
+ <!-- test scope -->
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <jdkToolchain>
+ <version>${java.version}</version>
+ </jdkToolchain>
+ <source>${java.version}</source>
+ <target>${java.version}</target>
+ <showDeprecation>true</showDeprecation>
+ <compilerArgs>
+ <arg>-Xlint:all</arg>
+ <arg>-Xlint:-serial</arg>
+ <arg>-Werror</arg>
+ </compilerArgs>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <mainClass>ai.vespa.feed.client.CliClient</mainClass>
+ </manifest>
+ </archive>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ <appendAssemblyId>false</appendAssemblyId>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/vespa-feed-client/src/main/java/ai/vespa/feed/client/CliArguments.java b/vespa-feed-client-cli/src/main/java/ai/vespa/feed/client/CliArguments.java
index 06c994b12b6..06c994b12b6 100644
--- a/vespa-feed-client/src/main/java/ai/vespa/feed/client/CliArguments.java
+++ b/vespa-feed-client-cli/src/main/java/ai/vespa/feed/client/CliArguments.java
diff --git a/vespa-feed-client/src/main/java/ai/vespa/feed/client/CliClient.java b/vespa-feed-client-cli/src/main/java/ai/vespa/feed/client/CliClient.java
index 84a29f9c3e4..060f406f38f 100644
--- a/vespa-feed-client/src/main/java/ai/vespa/feed/client/CliClient.java
+++ b/vespa-feed-client-cli/src/main/java/ai/vespa/feed/client/CliClient.java
@@ -13,13 +13,13 @@ import java.util.Properties;
*
* @author bjorncs
*/
-class CliClient {
+public class CliClient {
private final PrintStream systemOut;
private final PrintStream systemError;
private final Properties systemProperties;
- CliClient(PrintStream systemOut, PrintStream systemError, Properties systemProperties) {
+ private CliClient(PrintStream systemOut, PrintStream systemError, Properties systemProperties) {
this.systemOut = systemOut;
this.systemError = systemError;
this.systemProperties = systemProperties;
@@ -31,7 +31,7 @@ class CliClient {
System.exit(exitCode);
}
- int run(String[] rawArgs) {
+ private int run(String[] rawArgs) {
try {
CliArguments cliArgs = CliArguments.fromRawArgs(rawArgs);
if (cliArgs.helpSpecified()) {
diff --git a/vespa-feed-client/src/main/sh/vespa-feed-client.sh b/vespa-feed-client-cli/src/main/sh/vespa-feed-client.sh
index 2e8d22a4245..2a166dd40bb 100755
--- a/vespa-feed-client/src/main/sh/vespa-feed-client.sh
+++ b/vespa-feed-client-cli/src/main/sh/vespa-feed-client.sh
@@ -79,4 +79,4 @@ exec java \
-Djava.library.path=${VESPA_HOME}/libexec64/native:${VESPA_HOME}/lib64 \
-Djava.awt.headless=true \
-Xms128m -Xmx2048m $(getJavaOptionsIPV46) \
--cp ${VESPA_HOME}/lib/jars/vespa-feed-client-jar-with-dependencies.jar ai.vespa.feed.client.CliClient "$@" \ No newline at end of file
+-cp ${VESPA_HOME}/lib/jars/vespa-feed-client-cli.jar ai.vespa.feed.client.CliClient "$@"
diff --git a/vespa-feed-client/src/test/java/ai/vespa/feed/client/CliArgumentsTest.java b/vespa-feed-client-cli/src/test/java/ai/vespa/feed/client/CliArgumentsTest.java
index be479d294d5..be479d294d5 100644
--- a/vespa-feed-client/src/test/java/ai/vespa/feed/client/CliArgumentsTest.java
+++ b/vespa-feed-client-cli/src/test/java/ai/vespa/feed/client/CliArgumentsTest.java
diff --git a/vespa-feed-client/src/test/resources/help.txt b/vespa-feed-client-cli/src/test/resources/help.txt
index 8ad153bc0e0..8ad153bc0e0 100644
--- a/vespa-feed-client/src/test/resources/help.txt
+++ b/vespa-feed-client-cli/src/test/resources/help.txt
diff --git a/vespa-feed-client/CMakeLists.txt b/vespa-feed-client/CMakeLists.txt
index 747000169b1..7e6346c81cb 100644
--- a/vespa-feed-client/CMakeLists.txt
+++ b/vespa-feed-client/CMakeLists.txt
@@ -1,4 +1 @@
# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-install_fat_java_artifact(vespa-feed-client)
-
-vespa_install_script(src/main/sh/vespa-feed-client.sh vespa-feed-client bin)
diff --git a/vespa-feed-client/pom.xml b/vespa-feed-client/pom.xml
index b1d11c0c8d5..7759e9d2308 100644
--- a/vespa-feed-client/pom.xml
+++ b/vespa-feed-client/pom.xml
@@ -30,11 +30,6 @@
<scope>compile</scope>
</dependency>
<dependency>
- <groupId>commons-cli</groupId>
- <artifactId>commons-cli</artifactId>
- <scope>compile</scope>
- </dependency>
- <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<scope>compile</scope>
@@ -88,29 +83,6 @@
</execution>
</executions>
</plugin>
- <plugin>
- <artifactId>maven-assembly-plugin</artifactId>
- <configuration>
- <archive>
- <manifest>
- <mainClass>ai.vespa.feed.client.CliClient</mainClass>
- </manifest>
- </archive>
- <descriptorRefs>
- <descriptorRef>jar-with-dependencies</descriptorRef>
- </descriptorRefs>
- </configuration>
- <executions>
- <execution>
- <id>make-assembly</id>
- <phase>package</phase>
- <!-- append to the packaging phase. -->
- <goals>
- <goal>single</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
</project>
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);