summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/ApplicationClusterEndpoint.java35
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/ContainerEndpoint.java13
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java3
-rwxr-xr-xconfig-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java70
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializer.java7
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/session/PrepareParamsTest.java11
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/tenant/ContainerEndpointSerializerTest.java4
7 files changed, 121 insertions, 22 deletions
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ApplicationClusterEndpoint.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ApplicationClusterEndpoint.java
index 0154e5d3b13..ebd4059f9f9 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/ApplicationClusterEndpoint.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ApplicationClusterEndpoint.java
@@ -4,6 +4,7 @@ package com.yahoo.config.model.api;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.SystemName;
import java.util.List;
import java.util.Objects;
@@ -17,6 +18,18 @@ import java.util.stream.Stream;
* @author mortent
*/
public class ApplicationClusterEndpoint {
+ @Override
+ public String toString() {
+ return "ApplicationClusterEndpoint{" +
+ "dnsName=" + dnsName +
+ ", scope=" + scope +
+ ", routingMethod=" + routingMethod +
+ ", weight=" + weight +
+ ", hostNames=" + hostNames +
+ ", clusterId='" + clusterId + '\'' +
+ '}';
+ }
+
public enum Scope {application, global, zone}
public enum RoutingMethod {shared, sharedLayer4}
@@ -133,15 +146,15 @@ public class ApplicationClusterEndpoint {
}
// TODO: remove
- public static DnsName sharedNameFrom(ClusterSpec.Id cluster, ApplicationId applicationId, String suffix) {
- String name = dnsParts(cluster, applicationId)
+ public static DnsName sharedNameFrom(SystemName systemName, ClusterSpec.Id cluster, ApplicationId applicationId, String suffix) {
+ String name = dnsParts(systemName, cluster, applicationId)
.filter(Objects::nonNull) // remove null values that were "default"
.collect(Collectors.joining("--"));
return new DnsName(sanitize(name) + suffix); // Need to sanitize name since it is considered one label
}
- public static DnsName sharedL4NameFrom(ClusterSpec.Id cluster, ApplicationId applicationId, String suffix) {
- String name = dnsParts(cluster, applicationId)
+ public static DnsName sharedL4NameFrom(SystemName systemName, ClusterSpec.Id cluster, ApplicationId applicationId, String suffix) {
+ String name = dnsParts(systemName, cluster, applicationId)
.filter(Objects::nonNull) // remove null values that were "default"
.map(DnsName::sanitize)
.collect(Collectors.joining("."));
@@ -152,9 +165,10 @@ public class ApplicationClusterEndpoint {
return new DnsName(name);
}
- private static Stream<String> dnsParts(ClusterSpec.Id cluster, ApplicationId applicationId) {
+ private static Stream<String> dnsParts(SystemName systemName, ClusterSpec.Id cluster, ApplicationId applicationId) {
return Stream.of(
nullIfDefault(cluster.value()),
+ systemPart(systemName),
nullIfDefault(applicationId.instance().value()),
applicationId.application().value(),
applicationId.tenant().value()
@@ -180,5 +194,16 @@ public class ApplicationClusterEndpoint {
private static String nullIfDefault(String string) {
return Optional.of(string).filter(s -> !s.equals("default")).orElse(null);
}
+
+ private static String systemPart(SystemName systemName) {
+ return "cd".equals(systemName.value()) ? systemName.value() : null;
+ }
+
+ @Override
+ public String toString() {
+ return "DnsName{" +
+ "name='" + name + '\'' +
+ '}';
+ }
}
}
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ContainerEndpoint.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ContainerEndpoint.java
index a114f9d40ef..cd31eb2a49a 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/ContainerEndpoint.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ContainerEndpoint.java
@@ -3,6 +3,9 @@ package com.yahoo.config.model.api;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
+import java.util.OptionalInt;
+import java.util.OptionalLong;
/**
* ContainerEndpoint tracks the service names that a Container Cluster should be
@@ -16,11 +19,17 @@ public class ContainerEndpoint {
private final String clusterId;
private final ApplicationClusterEndpoint.Scope scope;
private final List<String> names;
+ private final OptionalInt weight;
public ContainerEndpoint(String clusterId, ApplicationClusterEndpoint.Scope scope, List<String> names) {
+ this(clusterId, scope, names, OptionalInt.empty());
+ }
+
+ public ContainerEndpoint(String clusterId, ApplicationClusterEndpoint.Scope scope, List<String> names, OptionalInt weight) {
this.clusterId = Objects.requireNonNull(clusterId);
this.scope = Objects.requireNonNull(scope);
this.names = List.copyOf(Objects.requireNonNull(names));
+ this.weight = weight;
}
public String clusterId() {
@@ -35,6 +44,10 @@ public class ContainerEndpoint {
return scope;
}
+ public OptionalInt weight() {
+ return weight;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
index f7e8afc2d94..f6a0eb9ce8d 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
@@ -210,6 +210,7 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
for(String suffix : deployState.getProperties().zoneDnsSuffixes()) {
// L4
ApplicationClusterEndpoint.DnsName l4Name = ApplicationClusterEndpoint.DnsName.sharedL4NameFrom(
+ deployState.zone().system(),
ClusterSpec.Id.from(getName()),
deployState.getProperties().applicationId(),
suffix);
@@ -223,6 +224,7 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
// L7
ApplicationClusterEndpoint.DnsName l7Name = ApplicationClusterEndpoint.DnsName.sharedNameFrom(
+ deployState.zone().system(),
ClusterSpec.Id.from(getName()),
deployState.getProperties().applicationId(),
suffix);
@@ -242,6 +244,7 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
.forEach(ce -> ce.names().forEach(
name -> endpoints.add(ApplicationClusterEndpoint.builder()
.scope(ce.scope())
+ .weight(Long.valueOf(ce.weight().orElse(1)).intValue()) // Default to weight=1 if not set
.sharedL4Routing()
.dnsName(ApplicationClusterEndpoint.DnsName.from(name))
.hosts(hosts)
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
index 2016cea02a9..87dd91a8a11 100755
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
@@ -39,9 +39,13 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
+import java.util.OptionalInt;
+import java.util.OptionalLong;
import java.util.Set;
import java.util.stream.Collectors;
+import static com.yahoo.config.provision.SystemName.cd;
+import static com.yahoo.config.provision.SystemName.main;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasKey;
@@ -358,32 +362,66 @@ public class ContainerClusterTest {
@Test
public void generatesCorrectRoutingInfo() {
-
- assertNames(ApplicationId.from("t1", "a1", "i1"),
+ // main system:
+ assertNames(main,
+ ApplicationId.from("t1", "a1", "i1"),
Set.of(),
List.of("search-cluster.i1.a1.t1.endpoint.suffix", "search-cluster--i1--a1--t1.endpoint.suffix"));
- assertNames(ApplicationId.from("t1", "a1", "default"),
+ assertNames(main,
+ ApplicationId.from("t1", "a1", "default"),
Set.of(),
List.of("search-cluster.a1.t1.endpoint.suffix", "search-cluster--a1--t1.endpoint.suffix"));
- assertNames(ApplicationId.from("t1", "default", "default"),
+ assertNames(main,
+ ApplicationId.from("t1", "default", "default"),
Set.of(),
List.of("search-cluster.default.t1.endpoint.suffix", "search-cluster--default--t1.endpoint.suffix"));
- assertNames(ApplicationId.from("t1", "a1", "default"),
+ assertNames(main,
+ ApplicationId.from("t1", "a1", "default"),
Set.of(new ContainerEndpoint("not-in-this-cluster", ApplicationClusterEndpoint.Scope.global, List.of("foo", "bar"))),
List.of("search-cluster.a1.t1.endpoint.suffix", "search-cluster--a1--t1.endpoint.suffix"));
- assertNames(ApplicationId.from("t1", "a1", "default"),
+ assertNames(main,
+ ApplicationId.from("t1", "a1", "default"),
Set.of(new ContainerEndpoint("search-cluster", ApplicationClusterEndpoint.Scope.global, List.of("rotation-1.x.y.z", "rotation-2.x.y.z")),
- new ContainerEndpoint("search-cluster", ApplicationClusterEndpoint.Scope.application, List.of("app-rotation.x.y.z"))),
+ new ContainerEndpoint("search-cluster", ApplicationClusterEndpoint.Scope.application, List.of("app-rotation.x.y.z"), OptionalInt.of(3))),
List.of("search-cluster.a1.t1.endpoint.suffix", "search-cluster--a1--t1.endpoint.suffix", "rotation-1.x.y.z", "rotation-2.x.y.z", "app-rotation.x.y.z"));
+
+ // cd system:
+ assertNames(cd,
+ ApplicationId.from("t1", "a1", "i1"),
+ Set.of(),
+ List.of("search-cluster.cd.i1.a1.t1.endpoint.suffix", "search-cluster--cd--i1--a1--t1.endpoint.suffix"));
+
+ assertNames(cd,
+ ApplicationId.from("t1", "a1", "default"),
+ Set.of(),
+ List.of("search-cluster.cd.a1.t1.endpoint.suffix", "search-cluster--cd--a1--t1.endpoint.suffix"));
+
+ assertNames(cd,
+ ApplicationId.from("t1", "default", "default"),
+ Set.of(),
+ List.of("search-cluster.cd.default.t1.endpoint.suffix", "search-cluster--cd--default--t1.endpoint.suffix"));
+
+ assertNames(cd,
+ ApplicationId.from("t1", "a1", "default"),
+ Set.of(new ContainerEndpoint("not-in-this-cluster", ApplicationClusterEndpoint.Scope.global, List.of("foo", "bar"))),
+ List.of("search-cluster.cd.a1.t1.endpoint.suffix", "search-cluster--cd--a1--t1.endpoint.suffix"));
+
+ assertNames(cd,
+ ApplicationId.from("t1", "a1", "default"),
+ Set.of(new ContainerEndpoint("search-cluster", ApplicationClusterEndpoint.Scope.global, List.of("rotation-1.x.y.z", "rotation-2.x.y.z")),
+ new ContainerEndpoint("search-cluster", ApplicationClusterEndpoint.Scope.application, List.of("app-rotation.x.y.z"), OptionalInt.of(3))),
+ List.of("search-cluster.cd.a1.t1.endpoint.suffix", "search-cluster--cd--a1--t1.endpoint.suffix", "rotation-1.x.y.z", "rotation-2.x.y.z", "app-rotation.x.y.z"));
+
}
- private void assertNames(ApplicationId appId, Set<ContainerEndpoint> globalEndpoints, List<String> expectedNames) {
+ private void assertNames(SystemName systemName, ApplicationId appId, Set<ContainerEndpoint> globalEndpoints, List<String> expectedNames) {
+ Zone zone = new Zone(systemName, Environment.defaultEnvironment(), RegionName.defaultName());
DeployState state = new DeployState.Builder()
- .zone(Zone.defaultZone())
+ .zone(zone)
.endpoints(globalEndpoints)
.properties(new TestProperties()
.setHostedVespa(true)
@@ -396,7 +434,19 @@ public class ContainerClusterTest {
cluster.doPrepare(state);
List<ApplicationClusterEndpoint> endpoints = cluster.endpoints();
assertEquals(expectedNames.size(), endpoints.size());
- expectedNames.forEach(expected -> assertTrue("Endpoint not matched " + expected, endpoints.stream().anyMatch(e -> Objects.equals(e.dnsName().value(), expected))));
+ expectedNames.forEach(expected -> assertTrue("Endpoint not matched " + expected + " was: " + endpoints, endpoints.stream().anyMatch(e -> Objects.equals(e.dnsName().value(), expected))));
+
+ List<ContainerEndpoint> endpointsWithWeight =
+ globalEndpoints.stream().filter(endpoint -> endpoint.weight().isPresent()).collect(Collectors.toList());
+ endpointsWithWeight.stream()
+ .filter(ce -> ce.weight().isPresent())
+ .forEach(ce -> assertTrue(endpointsMatch(ce, endpoints)));
+ }
+
+ private boolean endpointsMatch(ContainerEndpoint configuredEndpoint, List<ApplicationClusterEndpoint> clusterEndpoints) {
+ return clusterEndpoints.stream().anyMatch(e ->
+ configuredEndpoint.names().contains(e.dnsName().value()) &&
+ configuredEndpoint.weight().getAsInt() == e.weight());
}
private void verifyTesterApplicationInstalledBundles(Zone zone, List<String> expectedBundleNames) {
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 55986e71b3d..3bbf98357f5 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
@@ -30,6 +30,7 @@ public class ContainerEndpointSerializer {
private static final String clusterIdField = "clusterId";
private static final String scopeField = "scope";
private static final String namesField = "names";
+ private static final String weightField = "weight";
private ContainerEndpointSerializer() {}
@@ -39,7 +40,7 @@ public class ContainerEndpointSerializer {
// TODO: Remove default assignment after 7.500
final var scope = SlimeUtils.optionalString(inspector.field(scopeField)).orElse(ApplicationClusterEndpoint.Scope.global.name());
final var namesInspector = inspector.field(namesField);
-
+ final var weight = SlimeUtils.optionalInteger(inspector.field(weightField));
if (clusterId.isEmpty()) {
throw new IllegalStateException("'clusterId' missing on serialized ContainerEndpoint");
}
@@ -59,7 +60,7 @@ public class ContainerEndpointSerializer {
names.add(containerName);
});
- return new ContainerEndpoint(clusterId, ApplicationClusterEndpoint.Scope.valueOf(scope), names);
+ return new ContainerEndpoint(clusterId, ApplicationClusterEndpoint.Scope.valueOf(scope), names, weight);
}
public static List<ContainerEndpoint> endpointListFromSlime(Slime slime) {
@@ -81,7 +82,7 @@ public class ContainerEndpointSerializer {
public static void endpointToSlime(Cursor cursor, ContainerEndpoint endpoint) {
cursor.setString(clusterIdField, endpoint.clusterId());
cursor.setString(scopeField, endpoint.scope().name());
-
+ endpoint.weight().ifPresent(w -> cursor.setLong(weightField, w));
final var namesInspector = cursor.setArray(namesField);
endpoint.names().forEach(namesInspector::addString);
}
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 2c97d0b9382..cd824967fc3 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
@@ -43,6 +43,8 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
+import java.util.OptionalInt;
+import java.util.OptionalLong;
import java.util.stream.Collectors;
import static org.hamcrest.CoreMatchers.is;
@@ -90,18 +92,21 @@ public class PrepareParamsTest {
public void testCorrectParsingWithContainerEndpoints() throws IOException {
var endpoints = List.of(new ContainerEndpoint("qrs1", ApplicationClusterEndpoint.Scope.global,
List.of("c1.example.com",
- "c2.example.com")),
+ "c2.example.com"), OptionalInt.of(3)),
new ContainerEndpoint("qrs2",ApplicationClusterEndpoint.Scope.global,
List.of("c3.example.com",
"c4.example.com")));
var param = "[\n" +
" {\n" +
" \"clusterId\": \"qrs1\",\n" +
- " \"names\": [\"c1.example.com\", \"c2.example.com\"]\n" +
+ " \"names\": [\"c1.example.com\", \"c2.example.com\"],\n" +
+ " \"scope\": \"global\",\n" +
+ " \"weight\": 3\n" +
" },\n" +
" {\n" +
" \"clusterId\": \"qrs2\",\n" +
- " \"names\": [\"c3.example.com\", \"c4.example.com\"]\n" +
+ " \"names\": [\"c3.example.com\", \"c4.example.com\"],\n" +
+ " \"scope\": \"global\"\n" +
" }\n" +
"]";
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 2d767cfded4..2b746a9c1c6 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
@@ -7,6 +7,8 @@ import com.yahoo.slime.Slime;
import org.junit.Test;
import java.util.List;
+import java.util.OptionalInt;
+import java.util.OptionalLong;
import static org.junit.Assert.assertEquals;
@@ -50,7 +52,7 @@ public class ContainerEndpointSerializerTest {
@Test
public void writeReadSingleEndpoint() {
- final var endpoint = new ContainerEndpoint("foo", ApplicationClusterEndpoint.Scope.global, List.of("a", "b"));
+ final var endpoint = new ContainerEndpoint("foo", ApplicationClusterEndpoint.Scope.global, List.of("a", "b"), OptionalInt.of(1));
final var serialized = new Slime();
ContainerEndpointSerializer.endpointToSlime(serialized.setObject(), endpoint);
final var deserialized = ContainerEndpointSerializer.endpointFromSlime(serialized.get());