diff options
Diffstat (limited to 'cloud-tenant-cd/src/main/java/ai/vespa/hosted/cd/impl/CloudEndpoint.java')
-rw-r--r-- | cloud-tenant-cd/src/main/java/ai/vespa/hosted/cd/impl/CloudEndpoint.java | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/cloud-tenant-cd/src/main/java/ai/vespa/hosted/cd/impl/CloudEndpoint.java b/cloud-tenant-cd/src/main/java/ai/vespa/hosted/cd/impl/CloudEndpoint.java new file mode 100644 index 00000000000..7d1f97e55f8 --- /dev/null +++ b/cloud-tenant-cd/src/main/java/ai/vespa/hosted/cd/impl/CloudEndpoint.java @@ -0,0 +1,68 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package ai.vespa.hosted.cd.impl; + +import ai.vespa.hosted.api.EndpointAuthenticator; +import ai.vespa.hosted.cd.Endpoint; + +import javax.net.ssl.SSLParameters; +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.util.Map; +import java.util.stream.Collectors; + +import static java.net.URLEncoder.encode; +import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Objects.requireNonNull; + +/** + * A remote endpoint in a {@link CloudDeployment} of a Vespa application, reachable over HTTP. + * + * @author jonmv + */ +class CloudEndpoint implements Endpoint { + + private final URI endpoint; + private final HttpClient client; + private final EndpointAuthenticator authenticator; + + CloudEndpoint(URI endpoint, EndpointAuthenticator authenticator) { + this.endpoint = requireNonNull(endpoint); + this.authenticator = requireNonNull(authenticator); + SSLParameters sslParameters = new SSLParameters(); + sslParameters.setProtocols(new String[] {"TLSv1.2" }); + this.client = HttpClient.newBuilder() + .sslContext(authenticator.sslContext()) + .connectTimeout(Duration.ofSeconds(5)) + .version(HttpClient.Version.HTTP_1_1) + .sslParameters(sslParameters) + .build(); + } + + @Override + public URI uri() { + return endpoint; + } + + @Override + public <T> HttpResponse<T> send(HttpRequest.Builder request, HttpResponse.BodyHandler<T> handler) { + try { + return client.send(authenticator.authenticated(request).build(), handler); + } + catch (IOException | InterruptedException e) { + throw new RuntimeException(request.build() + " failed: " + e.getMessage(), e); + } + } + + @Override + public HttpRequest.Builder request(String path, Map<String, String> properties) { + return HttpRequest.newBuilder(endpoint.resolve(path + + properties.entrySet().stream() + .map(entry -> encode(entry.getKey(), UTF_8) + "=" + encode(entry.getValue(), UTF_8)) + .collect(Collectors.joining("&", path.contains("?") ? "&" : "?", "")))); + } + +} |