aboutsummaryrefslogtreecommitdiffstats
path: root/tenant-cd-api
diff options
context:
space:
mode:
authorjonmv <venstad@gmail.com>2022-05-04 16:20:14 +0200
committerjonmv <venstad@gmail.com>2022-05-04 16:20:14 +0200
commit4204e6ea8a1f133dce2ac9d7265c45e5d4c84395 (patch)
treee4a0c425340930be65abe5ee8f886b41dd6deb3b /tenant-cd-api
parent565de130d7a7a176d6658cce756288831ec3f387 (diff)
Expose EndpointAuthenticator
Diffstat (limited to 'tenant-cd-api')
-rw-r--r--tenant-cd-api/abi-spec.json16
-rw-r--r--tenant-cd-api/src/main/java/ai/vespa/hosted/cd/Endpoint.java3
-rw-r--r--tenant-cd-api/src/main/java/ai/vespa/hosted/cd/EndpointAuthenticator.java43
3 files changed, 62 insertions, 0 deletions
diff --git a/tenant-cd-api/abi-spec.json b/tenant-cd-api/abi-spec.json
index 18094f2973f..48222a63e28 100644
--- a/tenant-cd-api/abi-spec.json
+++ b/tenant-cd-api/abi-spec.json
@@ -22,6 +22,7 @@
],
"methods": [
"public abstract java.net.URI uri()",
+ "public abstract ai.vespa.hosted.cd.EndpointAuthenticator authenticator()",
"public abstract java.net.http.HttpResponse send(java.net.http.HttpRequest$Builder, java.net.http.HttpResponse$BodyHandler)",
"public java.net.http.HttpResponse send(java.net.http.HttpRequest$Builder)",
"public abstract java.net.http.HttpRequest$Builder request(java.lang.String, java.util.Map)",
@@ -29,6 +30,21 @@
],
"fields": []
},
+ "ai.vespa.hosted.cd.EndpointAuthenticator": {
+ "superClass": "java.lang.Object",
+ "interfaces": [],
+ "attributes": [
+ "public",
+ "interface",
+ "abstract"
+ ],
+ "methods": [
+ "public javax.net.ssl.SSLContext sslContext()",
+ "public java.net.http.HttpRequest$Builder authenticated(java.net.http.HttpRequest$Builder)",
+ "public java.util.Map authorizationHeaders()"
+ ],
+ "fields": []
+ },
"ai.vespa.hosted.cd.InconclusiveTestException": {
"superClass": "java.lang.RuntimeException",
"interfaces": [],
diff --git a/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/Endpoint.java b/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/Endpoint.java
index 3fd345abaff..319d835c73a 100644
--- a/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/Endpoint.java
+++ b/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/Endpoint.java
@@ -18,6 +18,9 @@ public interface Endpoint {
/** Returns the URI of the endpoint, with scheme, host and port. */
URI uri();
+ /** Returns the authenticator for HTTP requests against this particular endpoint. */
+ EndpointAuthenticator authenticator();
+
/** Sends the given request with required authentication. */
<T> HttpResponse<T> send(HttpRequest.Builder request, HttpResponse.BodyHandler<T> handler);
diff --git a/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/EndpointAuthenticator.java b/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/EndpointAuthenticator.java
new file mode 100644
index 00000000000..8985375fce2
--- /dev/null
+++ b/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/EndpointAuthenticator.java
@@ -0,0 +1,43 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package ai.vespa.hosted.cd;
+
+import javax.net.ssl.SSLContext;
+import java.net.http.HttpRequest;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Adds environment dependent authentication to HTTP request against Vespa deployments.
+ *
+ * An implementation typically needs to override either of the methods in this interface,
+ * and needs to run in different environments, e.g., local user testing and automatic testing
+ * in a deployment pipeline.
+ *
+ * @author jonmv
+ */
+public interface EndpointAuthenticator {
+
+ /** 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) {
+ Map<String, List<String>> headers = request.build().headers().map();
+ authorizationHeaders().forEach((name, value) -> {
+ if ( ! headers.containsKey(name))
+ request.setHeader(name, value);
+ });
+ return request;
+ }
+
+ default Map<String, String> authorizationHeaders() {
+ return Map.of();
+ }
+}