diff options
author | Jon Marius Venstad <jvenstad@yahoo-inc.com> | 2019-06-13 13:52:18 +0200 |
---|---|---|
committer | Jon Marius Venstad <jvenstad@yahoo-inc.com> | 2019-06-13 13:52:18 +0200 |
commit | 2bb71582b979a83a39260f3f11466737b94ee47f (patch) | |
tree | ac4d17548ae440348a7ecd62bbd87cfa998c6496 /tenant-cd | |
parent | 7d2366a939f64f964a208e01c4455dd530f833c6 (diff) |
Wrap TestConfig in TestRuntime, which includes and Authenticator, and obtain the former from controller
Diffstat (limited to 'tenant-cd')
4 files changed, 95 insertions, 106 deletions
diff --git a/tenant-cd/src/main/java/ai/vespa/hosted/cd/TestConfig.java b/tenant-cd/src/main/java/ai/vespa/hosted/cd/TestConfig.java deleted file mode 100644 index e441254cff7..00000000000 --- a/tenant-cd/src/main/java/ai/vespa/hosted/cd/TestConfig.java +++ /dev/null @@ -1,101 +0,0 @@ -package ai.vespa.hosted.cd; - -import ai.vespa.hosted.api.ControllerHttpClient; -import ai.vespa.hosted.auth.Authenticator; -import com.yahoo.config.provision.ApplicationId; -import com.yahoo.config.provision.SystemName; -import com.yahoo.slime.ArrayTraverser; -import com.yahoo.slime.Inspector; -import com.yahoo.slime.JsonDecoder; -import com.yahoo.slime.ObjectTraverser; -import com.yahoo.config.provision.zone.ZoneId; -import com.yahoo.slime.Slime; - -import java.net.URI; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * The place to obtain environment-dependent configuration for the current test run. - * - * If the system property 'vespa.test.config' is set, this class attempts to parse config - * from a JSON file at that location -- otherwise, attempts to access the config will return null. - * - * @author jvenstad - */ -public class TestConfig { - - private static TestConfig theConfig; - - private final ApplicationId application; - private final ZoneId zone; - private final SystemName system; - private final Map<ZoneId, Deployment> deployments; - - private TestConfig(ApplicationId application, ZoneId zone, SystemName system, Map<ZoneId, Deployment> deployments) { - this.application = application; - this.zone = zone; - this.system = system; - this.deployments = Map.copyOf(deployments); - } - - /** Returns the config for this test, or null if it has not been provided. */ - public static synchronized TestConfig get() { - if (theConfig == null) { - String configPath = System.getProperty("vespa.test.config"); - theConfig = configPath != null ? fromFile(configPath) : fromController(); - } - return theConfig; - } - - /** Returns the full id of the application to be tested. */ - public ApplicationId application() { return application; } - - /** Returns the zone of the deployment to test. */ - public ZoneId zone() { return zone; } - - /** Returns an immutable view of all configured endpoints for each zone of the application to test. */ - public Map<ZoneId, Deployment> allDeployments() { return deployments; } - - /** Returns the deployment to test in this test runtime. */ - public Deployment deploymentToTest() { return deployments.get(zone); } - - /** Returns the system this is run against. */ - public SystemName system() { return system; } - - static TestConfig fromFile(String path) { - if (path == null) - return null; - - try { - return fromJson(Files.readAllBytes(Paths.get(path))); - } - catch (Exception e) { - throw new IllegalArgumentException("Failed reading config from '" + path + "'!", e); - } - } - - static TestConfig fromController() { - ControllerHttpClient controller = new Authenticator().controller(); - return null; - } - - static TestConfig fromJson(byte[] jsonBytes) { - Inspector config = new JsonDecoder().decode(new Slime(), jsonBytes).get(); - 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, Deployment> endpoints = new HashMap<>(); - config.field("endpoints").traverse((ObjectTraverser) (zoneId, endpointArray) -> { - List<URI> uris = new ArrayList<>(); - endpointArray.traverse((ArrayTraverser) (__, uri) -> uris.add(URI.create(uri.asString()))); - endpoints.put(ZoneId.from(zoneId), null); // TODO jvenstad - }); - return new TestConfig(application, zone, system, endpoints); - } - -} diff --git a/tenant-cd/src/main/java/ai/vespa/hosted/cd/TestRuntime.java b/tenant-cd/src/main/java/ai/vespa/hosted/cd/TestRuntime.java new file mode 100644 index 00000000000..fa09d7037c9 --- /dev/null +++ b/tenant-cd/src/main/java/ai/vespa/hosted/cd/TestRuntime.java @@ -0,0 +1,77 @@ +package ai.vespa.hosted.cd; + +import ai.vespa.hosted.api.Authenticator; +import ai.vespa.hosted.api.ControllerHttpClient; +import ai.vespa.hosted.api.Properties; +import ai.vespa.hosted.api.TestConfig; +import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.Environment; +import com.yahoo.config.provision.RegionName; +import com.yahoo.config.provision.zone.ZoneId; + +import java.nio.file.Files; +import java.nio.file.Paths; + +import static ai.vespa.hosted.api.TestConfig.fromJson; + +/** + * The place to obtain environment-dependent configuration for test of a Vespa deployment. + * + * @author jvenstad + */ +public class TestRuntime { + + private static TestRuntime theRuntime; + + private final TestConfig config; + private final Authenticator authenticator; + + private TestRuntime(TestConfig config, Authenticator authenticator) { + this.config = config; + this.authenticator = authenticator; + } + + /** + * Returns the config for this test, or null if it has not been provided. + * + * If the system property {@code "vespa.test.config"} is set (to a file path), a file at that location + * is attempted read, and config parsed from it. + * Otherwise, config is fetched over HTTP from the hosted Vespa API, assuming the deployment indicated + * by the optional {@code "environment"} and {@code "region"} system properties exists. + * When environment is not specified, it defaults to {@link Environment#dev}, + * while region must be set unless the environment is {@link Environment#dev} or {@link Environment#perf}. + */ + public static synchronized TestRuntime get() { + if (theRuntime == null) { + String configPath = System.getProperty("vespa.test.config"); + Authenticator authenticator = new ai.vespa.hosted.auth.Authenticator(); + theRuntime = new TestRuntime(configPath != null ? fromFile(configPath) : fromController(authenticator), + authenticator); + } + return theRuntime; + } + + /** Returns a copy of this runtime, with the given authenticator. */ + public TestRuntime with(Authenticator authenticator) { + return new TestRuntime(config, authenticator); + } + + private static TestConfig fromFile(String path) { + try { + return TestConfig.fromJson(Files.readAllBytes(Paths.get(path))); + } + catch (Exception e) { + throw new IllegalArgumentException("Failed reading config from '" + path + "'!", e); + } + } + + private static TestConfig fromController(Authenticator authenticator) { + ControllerHttpClient controller = authenticator.controller(); + ApplicationId id = Properties.application(); + Environment environment = Properties.environment().orElse(Environment.dev); + ZoneId zone = Properties.region().map(region -> ZoneId.from(environment, region)) + .orElseGet(() -> controller.defaultZone(environment)); + return controller.testConfig(id, zone); + } + +} diff --git a/tenant-cd/src/main/java/ai/vespa/hosted/cd/http/HttpDeployment.java b/tenant-cd/src/main/java/ai/vespa/hosted/cd/http/HttpDeployment.java index 8eebe04ebef..6234b54c0a1 100644 --- a/tenant-cd/src/main/java/ai/vespa/hosted/cd/http/HttpDeployment.java +++ b/tenant-cd/src/main/java/ai/vespa/hosted/cd/http/HttpDeployment.java @@ -1,9 +1,13 @@ package ai.vespa.hosted.cd.http; +import ai.vespa.hosted.api.Authenticator; import ai.vespa.hosted.cd.Deployment; import ai.vespa.hosted.cd.Endpoint; import ai.vespa.hosted.cd.TestDeployment; -import ai.vespa.hosted.cd.TestEndpoint; + +import java.net.URI; +import java.util.Map; +import java.util.stream.Collectors; /** * A remote deployment of a Vespa application, reachable over HTTP. Contains {@link HttpEndpoint}s. @@ -12,6 +16,15 @@ import ai.vespa.hosted.cd.TestEndpoint; */ public class HttpDeployment implements Deployment { + private final Map<String, HttpEndpoint> endpoints; + + /** Creates a representation of the given deployment endpoints, using the authenticator for data plane access. */ + public HttpDeployment(Map<String, URI> endpoints, Authenticator authenticator) { + this.endpoints = endpoints.entrySet().stream() + .collect(Collectors.toUnmodifiableMap(entry -> entry.getKey(), + entry -> new HttpEndpoint(entry.getValue(), authenticator))); + } + @Override public Endpoint endpoint() { return null; diff --git a/tenant-cd/src/main/java/ai/vespa/hosted/cd/http/HttpEndpoint.java b/tenant-cd/src/main/java/ai/vespa/hosted/cd/http/HttpEndpoint.java index 4fafa65773d..798eb1e692b 100644 --- a/tenant-cd/src/main/java/ai/vespa/hosted/cd/http/HttpEndpoint.java +++ b/tenant-cd/src/main/java/ai/vespa/hosted/cd/http/HttpEndpoint.java @@ -1,6 +1,6 @@ package ai.vespa.hosted.cd.http; -import ai.vespa.hosted.auth.Authenticator; +import ai.vespa.hosted.api.Authenticator; import com.yahoo.slime.Inspector; import com.yahoo.slime.JsonDecoder; import com.yahoo.slime.Slime; @@ -34,11 +34,11 @@ public class HttpEndpoint implements TestEndpoint { private final URI endpoint; private final HttpClient client; - private final Authenticator authenticator; + private final ai.vespa.hosted.api.Authenticator authenticator; - public HttpEndpoint(URI endpoint) { + public HttpEndpoint(URI endpoint, Authenticator authenticator) { this.endpoint = requireNonNull(endpoint); - this.authenticator = new Authenticator(); + this.authenticator = requireNonNull(authenticator); this.client = HttpClient.newBuilder() .sslContext(authenticator.sslContext()) .connectTimeout(Duration.ofSeconds(5)) |