aboutsummaryrefslogtreecommitdiffstats
path: root/hosted-api
diff options
context:
space:
mode:
authorJon Marius Venstad <venstad@gmail.com>2019-08-19 11:47:18 +0200
committerJon Marius Venstad <venstad@gmail.com>2019-08-19 11:47:18 +0200
commit0c4ce4cb5bb3573b7b6c21573224b0edd064b177 (patch)
tree673d7d8f8b5c5445c341dc4fd2f60a0f7f0da9f7 /hosted-api
parent1f4bf84e9e89bb0afb000317a35403aad511cea0 (diff)
Support self-hosted test config file
Diffstat (limited to 'hosted-api')
-rw-r--r--hosted-api/src/main/java/ai/vespa/hosted/api/Authenticator.java32
-rw-r--r--hosted-api/src/main/java/ai/vespa/hosted/api/TestConfig.java32
-rw-r--r--hosted-api/src/test/java/ai/vespa/hosted/api/TestConfigTest.java10
-rw-r--r--hosted-api/src/test/resources/clusters-only-config.json6
4 files changed, 76 insertions, 4 deletions
diff --git a/hosted-api/src/main/java/ai/vespa/hosted/api/Authenticator.java b/hosted-api/src/main/java/ai/vespa/hosted/api/Authenticator.java
new file mode 100644
index 00000000000..aaff0bfe5e0
--- /dev/null
+++ b/hosted-api/src/main/java/ai/vespa/hosted/api/Authenticator.java
@@ -0,0 +1,32 @@
+package ai.vespa.hosted.api;
+
+import javax.net.ssl.SSLContext;
+import java.net.http.HttpRequest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Optional;
+
+/**
+ * Adds environment dependent authentication to HTTP request against Vespa deployments.
+ *
+ * An implementation typically needs to override either of the methods in this interface.
+ *
+ * @author jonmv
+ */
+public interface Authenticator {
+
+ /** Returns an SSLContext which provides authentication against a Vespa endpoint. */
+ default SSLContext sslContext() {
+ try {
+ return SSLContext.getDefault();
+ }
+ catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /** Adds necessary authentication data to the given HTTP request builder, to pass the data plane of a Vespa endpoint. */
+ default HttpRequest.Builder authenticated(HttpRequest.Builder request) {
+ return request;
+ }
+
+}
diff --git a/hosted-api/src/main/java/ai/vespa/hosted/api/TestConfig.java b/hosted-api/src/main/java/ai/vespa/hosted/api/TestConfig.java
index 015d5702c59..ed789f9de00 100644
--- a/hosted-api/src/main/java/ai/vespa/hosted/api/TestConfig.java
+++ b/hosted-api/src/main/java/ai/vespa/hosted/api/TestConfig.java
@@ -38,20 +38,44 @@ public class TestConfig {
entry -> Map.copyOf(entry.getValue())));
}
+ /**
+ * Parses the given test config JSON and returns a new config instance.
+ *
+ * If the given JSON has a "clusters" element, a config object with default values
+ * is returned, using {@link #fromEndpointsOnly}. Otherwise, all config attributes are parsed.
+ */
public static TestConfig fromJson(byte[] jsonBytes) {
Inspector config = new JsonDecoder().decode(new Slime(), jsonBytes).get();
+ if (config.field("clusters").valid())
+ return TestConfig.fromEndpointsOnly(toClusterMap(config.field("clusters")));
+
ApplicationId application = ApplicationId.fromSerializedForm(config.field("application").asString());
ZoneId zone = ZoneId.from(config.field("zone").asString());
SystemName system = SystemName.from(config.field("system").asString());
Map<ZoneId, Map<String, URI>> deployments = new HashMap<>();
- config.field("zoneEndpoints").traverse((ObjectTraverser) (zoneId, endpointsObject) -> {
- Map<String, URI> endpoints = new HashMap<>();
- endpointsObject.traverse((ObjectTraverser) (cluster, uri) -> endpoints.put(cluster, URI.create(uri.asString())));
- deployments.put(ZoneId.from(zoneId), endpoints);
+ config.field("zoneEndpoints").traverse((ObjectTraverser) (zoneId, clustersObject) -> {
+ deployments.put(ZoneId.from(zoneId), toClusterMap(clustersObject));
});
return new TestConfig(application, zone, system, deployments);
}
+ static Map<String, URI> toClusterMap(Inspector clustersObject) {
+ Map<String, URI> clusters = new HashMap<>();
+ clustersObject.traverse((ObjectTraverser) (cluster, uri) -> clusters.put(cluster, URI.create(uri.asString())));
+ return clusters;
+ }
+
+ /**
+ * Returns a TestConfig with default values for everything except the endpoints.
+ * @param endpoints a set of cluster name -> URI mappings — one per services.xml container cluster
+ */
+ public static TestConfig fromEndpointsOnly(Map<String, URI> endpoints) {
+ return new TestConfig(ApplicationId.defaultId(),
+ ZoneId.defaultId(),
+ SystemName.defaultSystem(),
+ Map.of(ZoneId.defaultId(), endpoints));
+ }
+
/** Returns the full id of the application to test. */
public ApplicationId application() { return application; }
diff --git a/hosted-api/src/test/java/ai/vespa/hosted/api/TestConfigTest.java b/hosted-api/src/test/java/ai/vespa/hosted/api/TestConfigTest.java
index 51fb7a8cf4a..bad838f0579 100644
--- a/hosted-api/src/test/java/ai/vespa/hosted/api/TestConfigTest.java
+++ b/hosted-api/src/test/java/ai/vespa/hosted/api/TestConfigTest.java
@@ -34,4 +34,14 @@ public class TestConfigTest {
config.deployments());
}
+ @Test
+ public void testClustersOnly() throws IOException {
+ TestConfig config = TestConfig.fromJson(Files.readAllBytes(Paths.get("src/test/resources/clusters-only-config.json")));
+ assertEquals(ApplicationId.defaultId(),
+ config.application());
+ assertEquals(Map.of("default", URI.create("https://localhost:8080/"),
+ "container", URI.create("https://localhost:8081/")),
+ config.deployments().get(ZoneId.defaultId()));
+ }
+
}
diff --git a/hosted-api/src/test/resources/clusters-only-config.json b/hosted-api/src/test/resources/clusters-only-config.json
new file mode 100644
index 00000000000..d111c1685d0
--- /dev/null
+++ b/hosted-api/src/test/resources/clusters-only-config.json
@@ -0,0 +1,6 @@
+{
+ "clusters": {
+ "default": "https://localhost:8080/",
+ "container": "https://localhost:8081/"
+ }
+} \ No newline at end of file