diff options
author | Harald Musum <musum@verizonmedia.com> | 2019-06-12 12:55:54 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-12 12:55:54 +0200 |
commit | a7fe82abe533cf8633af17a0e914fdc89d6db231 (patch) | |
tree | 64cc1411bed55581d4f6c62d312f3c763092fdcb | |
parent | bc3834c6699648f00a018a49e44c6b4cef93e6bc (diff) | |
parent | 22dd1cc435f353171a39b83a8ff9b4c42716ccd9 (diff) |
Merge pull request #9757 from vespa-engine/mpolden/container-endpoints-param
Add prepare parameter for container endpoints
6 files changed, 91 insertions, 22 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/PrepareParams.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/PrepareParams.java index a5e74d3b85f..542addbd7ff 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/PrepareParams.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/PrepareParams.java @@ -6,12 +6,17 @@ import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.Rotation; import com.yahoo.config.provision.TenantName; import com.yahoo.container.jdisc.HttpRequest; +import com.yahoo.slime.Slime; +import com.yahoo.vespa.config.SlimeUtils; import com.yahoo.vespa.config.server.TimeoutBudget; import com.yahoo.vespa.config.server.http.SessionHandler; +import com.yahoo.vespa.config.server.tenant.ContainerEndpoint; +import com.yahoo.vespa.config.server.tenant.ContainerEndpointSerializer; import java.time.Clock; import java.time.Duration; import java.util.LinkedHashSet; +import java.util.List; import java.util.Optional; import java.util.Set; @@ -29,6 +34,7 @@ public final class PrepareParams { static final String VERBOSE_PARAM_NAME = "verbose"; static final String VESPA_VERSION_PARAM_NAME = "vespaVersion"; static final String ROTATIONS_PARAM_NAME = "rotations"; + static final String CONTAINER_ENDPOINTS_PARAM_NAME = "containerEndpoints"; private final ApplicationId applicationId; private final TimeoutBudget timeoutBudget; @@ -38,9 +44,11 @@ public final class PrepareParams { private final boolean isBootstrap; private final Optional<Version> vespaVersion; private final Set<Rotation> rotations; + private final List<ContainerEndpoint> containerEndpoints; private PrepareParams(ApplicationId applicationId, TimeoutBudget timeoutBudget, boolean ignoreValidationErrors, - boolean dryRun, boolean verbose, boolean isBootstrap, Optional<Version> vespaVersion, Set<Rotation> rotations) { + boolean dryRun, boolean verbose, boolean isBootstrap, Optional<Version> vespaVersion, + Set<Rotation> rotations, List<ContainerEndpoint> containerEndpoints) { this.timeoutBudget = timeoutBudget; this.applicationId = applicationId; this.ignoreValidationErrors = ignoreValidationErrors; @@ -49,6 +57,7 @@ public final class PrepareParams { this.isBootstrap = isBootstrap; this.vespaVersion = vespaVersion; this.rotations = rotations; + this.containerEndpoints = containerEndpoints; } public static class Builder { @@ -61,6 +70,7 @@ public final class PrepareParams { private TimeoutBudget timeoutBudget = new TimeoutBudget(Clock.systemUTC(), Duration.ofSeconds(30)); private Optional<Version> vespaVersion = Optional.empty(); private Set<Rotation> rotations; + private List<ContainerEndpoint> containerEndpoints = List.of(); public Builder() { } @@ -119,22 +129,30 @@ public final class PrepareParams { return this; } + public Builder containerEndpoints(String serialized) { + if (serialized == null) return this; + Slime slime = SlimeUtils.jsonToSlime(serialized); + containerEndpoints = ContainerEndpointSerializer.endpointListFromSlime(slime); + return this; + } + public PrepareParams build() { return new PrepareParams(applicationId, timeoutBudget, ignoreValidationErrors, dryRun, - verbose, isBootstrap, vespaVersion, rotations); + verbose, isBootstrap, vespaVersion, rotations, containerEndpoints); } } public static PrepareParams fromHttpRequest(HttpRequest request, TenantName tenant, Duration barrierTimeout) { return new Builder().ignoreValidationErrors(request.getBooleanProperty(IGNORE_VALIDATION_PARAM_NAME)) - .dryRun(request.getBooleanProperty(DRY_RUN_PARAM_NAME)) - .verbose(request.getBooleanProperty(VERBOSE_PARAM_NAME)) - .timeoutBudget(SessionHandler.getTimeoutBudget(request, barrierTimeout)) - .applicationId(createApplicationId(request, tenant)) - .vespaVersion(request.getProperty(VESPA_VERSION_PARAM_NAME)) - .rotations(request.getProperty(ROTATIONS_PARAM_NAME)) - .build(); + .dryRun(request.getBooleanProperty(DRY_RUN_PARAM_NAME)) + .verbose(request.getBooleanProperty(VERBOSE_PARAM_NAME)) + .timeoutBudget(SessionHandler.getTimeoutBudget(request, barrierTimeout)) + .applicationId(createApplicationId(request, tenant)) + .vespaVersion(request.getProperty(VESPA_VERSION_PARAM_NAME)) + .rotations(request.getProperty(ROTATIONS_PARAM_NAME)) + .containerEndpoints(request.getProperty(CONTAINER_ENDPOINTS_PARAM_NAME)) + .build(); } private static ApplicationId createApplicationId(HttpRequest request, TenantName tenant) { @@ -164,8 +182,15 @@ public final class PrepareParams { /** Returns the Vespa version the nodes running the prepared system should have, or empty to use the system version */ public Optional<Version> vespaVersion() { return vespaVersion; } + /** Returns the global rotations that should be made available for this deployment */ + // TODO: Remove this once all applications have to switched to containerEndpoints public Set<Rotation> rotations() { return rotations; } + /** Returns the container endpoints that should be made available for this deployment. One per cluster */ + public List<ContainerEndpoint> containerEndpoints() { + return containerEndpoints; + } + public boolean ignoreValidationErrors() { return ignoreValidationErrors; } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpoint.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpoint.java index fb1035b5a03..eda320bde8f 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpoint.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpoint.java @@ -8,16 +8,17 @@ import java.util.Objects; /** * ContainerEndpoint tracks the service names that a Container Cluster should be - * known as. This is used during request routing both for regular requests and + * known as. This is used during request routing both for regular requests and * for health checks in traffic distribution. * * @author ogronnesby */ public class ContainerEndpoint { + private final ClusterId clusterId; private final List<String> names; - ContainerEndpoint(ClusterId clusterId, List<String> names) { + public ContainerEndpoint(ClusterId clusterId, List<String> names) { this.clusterId = Objects.requireNonNull(clusterId); this.names = List.copyOf(Objects.requireNonNull(names)); } @@ -51,4 +52,5 @@ public class ContainerEndpoint { ", names=" + names + '}'; } + } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializer.java index 83d65f5b38b..379af7f71ea 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializer.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializer.java @@ -17,9 +17,12 @@ import java.util.List; * @author ogronnesby */ public class ContainerEndpointSerializer { + private static final String clusterIdField = "clusterId"; private static final String namesField = "names"; + private ContainerEndpointSerializer() {} + public static ContainerEndpoint endpointFromSlime(Inspector inspector) { final var clusterId = inspector.field(clusterIdField).asString(); final var namesInspector = inspector.field(namesField); @@ -73,4 +76,5 @@ public class ContainerEndpointSerializer { return slime; } + } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointsCache.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointsCache.java index 06f93f2006f..5e2cd5bd9d8 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointsCache.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointsCache.java @@ -24,6 +24,7 @@ import java.util.List; * @author ogronnesby */ public class ContainerEndpointsCache { + private final Path cachePath; private final Curator curator; @@ -37,7 +38,7 @@ public class ContainerEndpointsCache { return optionalData .map(SlimeUtils::jsonToSlime) .map(ContainerEndpointSerializer::endpointListFromSlime) - .orElse(List.of()); + .orElseGet(List::of); } public void write(ApplicationId applicationId, List<ContainerEndpoint> endpoints) { @@ -56,4 +57,5 @@ public class ContainerEndpointsCache { private Path applicationPath(ApplicationId applicationId) { return cachePath.append(applicationId.serializedForm()); } + } diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/session/PrepareParamsTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/session/PrepareParamsTest.java index f2fb4aa1c40..6eba85af37e 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/session/PrepareParamsTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/session/PrepareParamsTest.java @@ -6,10 +6,14 @@ import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.Rotation; import com.yahoo.config.provision.TenantName; import com.yahoo.container.jdisc.HttpRequest; - +import com.yahoo.vespa.applicationmodel.ClusterId; +import com.yahoo.vespa.config.server.tenant.ContainerEndpoint; import org.junit.Test; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.time.Duration; +import java.util.List; import java.util.Optional; import java.util.Set; @@ -17,6 +21,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -26,6 +31,15 @@ import static org.junit.Assert.assertTrue; */ public class PrepareParamsTest { + private static final String rotation = "rotation-042.vespa.a02.yahoodns.net"; + private static final String vespaVersion = "6.37.49"; + private static final String request = "http://foo:19071/application/v2/tenant/foo/application/bar?" + + PrepareParams.DRY_RUN_PARAM_NAME + "=true&" + + PrepareParams.VERBOSE_PARAM_NAME+ "=true&" + + PrepareParams.IGNORE_VALIDATION_PARAM_NAME + "=false&" + + PrepareParams.APPLICATION_NAME_PARAM_NAME + "=baz&" + + PrepareParams.VESPA_VERSION_PARAM_NAME + "=" + vespaVersion; + @Test public void testCorrectParsing() { PrepareParams prepareParams = createParams("http://foo:19071/application/v2/", TenantName.defaultName()); @@ -38,15 +52,6 @@ public class PrepareParamsTest { assertTrue(prepareParams.getTimeoutBudget().hasTimeLeft()); assertThat(prepareParams.rotations().size(), is(0)); } - - private static final String rotation = "rotation-042.vespa.a02.yahoodns.net"; - private static final String vespaVersion = "6.37.49"; - private static final String request = "http://foo:19071/application/v2/tenant/foo/application/bar?" + - PrepareParams.DRY_RUN_PARAM_NAME + "=true&" + - PrepareParams.VERBOSE_PARAM_NAME+ "=true&" + - PrepareParams.IGNORE_VALIDATION_PARAM_NAME + "=false&" + - PrepareParams.APPLICATION_NAME_PARAM_NAME + "=baz&" + - PrepareParams.VESPA_VERSION_PARAM_NAME + "=" + vespaVersion; @Test public void testCorrectParsingWithRotation() { @@ -77,6 +82,31 @@ public class PrepareParamsTest { assertThat(rotations, containsInAnyOrder(new Rotation(rotation), new Rotation(rotationTwo))); } + @Test + public void testCorrectParsingWithContainerEndpoints() { + var endpoints = List.of(new ContainerEndpoint(new ClusterId("qrs1"), + List.of("c1.example.com", + "c2.example.com")), + new ContainerEndpoint(new ClusterId("qrs2"), + List.of("c3.example.com", + "c4.example.com"))); + var param = "[\n" + + " {\n" + + " \"clusterId\": \"qrs1\",\n" + + " \"names\": [\"c1.example.com\", \"c2.example.com\"]\n" + + " },\n" + + " {\n" + + " \"clusterId\": \"qrs2\",\n" + + " \"names\": [\"c3.example.com\", \"c4.example.com\"]\n" + + " }\n" + + "]"; + + var encoded = URLEncoder.encode(param, StandardCharsets.UTF_8); + var prepareParams = createParams(request + "&" + PrepareParams.CONTAINER_ENDPOINTS_PARAM_NAME + + "=" + encoded, TenantName.from("foo")); + assertEquals(endpoints, prepareParams.containerEndpoints()); + } + // Create PrepareParams from a request (based on uri and tenant name) private static PrepareParams createParams(String uri, TenantName tenantName) { return PrepareParams.fromHttpRequest( @@ -84,4 +114,5 @@ public class PrepareParamsTest { tenantName, Duration.ofSeconds(60)); } + } diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializerTest.java index b4d52e6d37c..aac0b6d1a16 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializerTest.java @@ -8,7 +8,11 @@ import java.util.List; import static org.junit.Assert.assertEquals; +/** + * @author ogronnesby + */ public class ContainerEndpointSerializerTest { + @Test public void readSingleEndpoint() { final var slime = new Slime(); @@ -42,4 +46,5 @@ public class ContainerEndpointSerializerTest { assertEquals(endpoints, deserialized); } + } |