diff options
author | Martin Polden <mpolden@mpolden.no> | 2022-02-10 14:22:24 +0100 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2022-02-11 09:58:08 +0100 |
commit | 4415929f77b8a2caa23fbd08a9a840f28c3ef4ad (patch) | |
tree | e1a1925c3d9568e5b5de6ce1cf6d36ea86737208 /routing-generator | |
parent | 2d06f5ddf396157d9898b56f0e59d6352947001b (diff) |
Include only sharedLayer4 endpoints in Nginx config
Diffstat (limited to 'routing-generator')
8 files changed, 97 insertions, 39 deletions
diff --git a/routing-generator/src/main/java/com/yahoo/vespa/hosted/routing/RoutingTable.java b/routing-generator/src/main/java/com/yahoo/vespa/hosted/routing/RoutingTable.java index c19dd506c87..90a38da8687 100644 --- a/routing-generator/src/main/java/com/yahoo/vespa/hosted/routing/RoutingTable.java +++ b/routing-generator/src/main/java/com/yahoo/vespa/hosted/routing/RoutingTable.java @@ -8,17 +8,18 @@ import com.yahoo.config.provision.ApplicationName; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.InstanceName; import com.yahoo.config.provision.TenantName; +import com.yahoo.config.provision.zone.RoutingMethod; import com.yahoo.config.provision.zone.ZoneId; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.SortedMap; import java.util.TreeMap; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -35,7 +36,7 @@ public class RoutingTable { private static final String HOSTED_VESPA_TENANT_NAME = "hosted-vespa"; - private final Map<Endpoint, Target> table; + private final SortedMap<Endpoint, Target> table; private final long generation; public RoutingTable(Map<Endpoint, Target> table, long generation) { @@ -43,13 +44,20 @@ public class RoutingTable { this.generation = generation; } + public SortedMap<Endpoint, Target> asMap() { + return table; + } + /** Returns the target for given dnsName, if any */ - public Optional<Target> targetOf(String dnsName) { - return Optional.ofNullable(table.get(new Endpoint(dnsName))); + public Optional<Target> targetOf(String dnsName, RoutingMethod routingMethod) { + return Optional.ofNullable(table.get(new Endpoint(dnsName, routingMethod))); } - public Map<Endpoint, Target> asMap() { - return table; + /** Returns a copy of this containing only endpoints using given routing method */ + public RoutingTable routingMethod(RoutingMethod method) { + Map<Endpoint, Target> copy = new TreeMap<>(table); + copy.keySet().removeIf(endpoint -> !endpoint.routingMethod().equals(method)); + return new RoutingTable(copy, generation); } /** Returns the Vespa config generation this is based on */ @@ -76,7 +84,7 @@ public class RoutingTable { } public static RoutingTable from(LbServicesConfig config, long generation) { - Map<Endpoint, Target> entries = new HashMap<>(); + Map<Endpoint, Target> entries = new TreeMap<>(); for (var tenants : config.tenants().entrySet()) { TenantName tenantName = TenantName.from(tenants.getKey()); if (tenantName.value().equals(HOSTED_VESPA_TENANT_NAME)) continue; @@ -95,7 +103,7 @@ public class RoutingTable { configuredEndpoint.weight(), applications.getValue().activeRotation())) .collect(Collectors.toList()); - Endpoint endpoint = new Endpoint(configuredEndpoint.dnsName()); + Endpoint endpoint = new Endpoint(configuredEndpoint.dnsName(), routingMethodFrom(configuredEndpoint)); ClusterSpec.Id cluster = ClusterSpec.Id.from(configuredEndpoint.clusterId()); Target target; boolean applicationEndpoint = configuredEndpoint.scope() == LbServicesConfig.Tenants.Applications.Endpoints.Scope.Enum.application; @@ -118,6 +126,14 @@ public class RoutingTable { return new RoutingTable(entries, generation); } + private static RoutingMethod routingMethodFrom(LbServicesConfig.Tenants.Applications.Endpoints endpoint) { + switch (endpoint.routingMethod()) { + case shared: return RoutingMethod.shared; + case sharedLayer4: return RoutingMethod.sharedLayer4; + } + throw new IllegalArgumentException("Unhandled routing method: " + endpoint.routingMethod()); + } + /** The target of an {@link Endpoint} */ public static class Target implements Comparable<Target> { @@ -217,6 +233,11 @@ public class RoutingTable { ",reals=" + reals; } + @Override + public int compareTo(RoutingTable.Target other) { + return id.compareTo(other.id); + } + /** Create an instance-level tartget */ public static Target create(ApplicationId instance, ClusterSpec.Id cluster, ZoneId zone, List<Real> reals) { return new Target(createId("", instance.tenant(), instance.application(), Optional.of(instance.instance()), cluster, zone), @@ -260,20 +281,20 @@ public class RoutingTable { .replaceAll("[^a-z0-9-]*", ""); } - @Override - public int compareTo(RoutingTable.Target other) { - return id.compareTo(other.id); - } - } /** An externally visible endpoint */ public static class Endpoint implements Comparable<Endpoint> { + private static final Comparator<Endpoint> COMPARATOR = Comparator.comparing(Endpoint::dnsName) + .thenComparing(Endpoint::routingMethod); + private final String dnsName; + private final RoutingMethod routingMethod; - public Endpoint(String dnsName) { + public Endpoint(String dnsName, RoutingMethod routingMethod) { this.dnsName = Objects.requireNonNull(dnsName); + this.routingMethod = Objects.requireNonNull(routingMethod); } /** The DNS name of this endpoint. This does not contain a trailing dot */ @@ -281,9 +302,13 @@ public class RoutingTable { return dnsName; } + public RoutingMethod routingMethod() { + return routingMethod; + } + @Override public String toString() { - return "endpoint " + dnsName; + return "endpoint " + dnsName + " (routing method: " + routingMethod + ")"; } @Override @@ -291,17 +316,17 @@ public class RoutingTable { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Endpoint endpoint = (Endpoint) o; - return dnsName.equals(endpoint.dnsName); + return dnsName.equals(endpoint.dnsName) && routingMethod == endpoint.routingMethod; } @Override public int hashCode() { - return Objects.hash(dnsName); + return Objects.hash(dnsName, routingMethod); } @Override - public int compareTo(RoutingTable.Endpoint o) { - return dnsName.compareTo(o.dnsName); + public int compareTo(Endpoint o) { + return COMPARATOR.compare(this, o); } } diff --git a/routing-generator/src/main/java/com/yahoo/vespa/hosted/routing/nginx/Nginx.java b/routing-generator/src/main/java/com/yahoo/vespa/hosted/routing/nginx/Nginx.java index f3368c43b92..408deabbcb6 100644 --- a/routing-generator/src/main/java/com/yahoo/vespa/hosted/routing/nginx/Nginx.java +++ b/routing-generator/src/main/java/com/yahoo/vespa/hosted/routing/nginx/Nginx.java @@ -2,6 +2,7 @@ package com.yahoo.vespa.hosted.routing.nginx; import com.yahoo.collections.Pair; +import com.yahoo.config.provision.zone.RoutingMethod; import com.yahoo.jdisc.Metric; import com.yahoo.system.ProcessExecuter; import com.yahoo.vespa.hosted.routing.Router; @@ -63,6 +64,7 @@ public class Nginx implements Router { public void load(RoutingTable table) { synchronized (monitor) { try { + table = table.routingMethod(RoutingMethod.sharedLayer4); // This router only supports layer 4 endpoints testConfig(table); loadConfig(table.asMap().size()); gcConfig(); diff --git a/routing-generator/src/main/java/com/yahoo/vespa/hosted/routing/restapi/AkamaiHandler.java b/routing-generator/src/main/java/com/yahoo/vespa/hosted/routing/restapi/AkamaiHandler.java index e4507edd850..9ed05278331 100644 --- a/routing-generator/src/main/java/com/yahoo/vespa/hosted/routing/restapi/AkamaiHandler.java +++ b/routing-generator/src/main/java/com/yahoo/vespa/hosted/routing/restapi/AkamaiHandler.java @@ -2,6 +2,7 @@ package com.yahoo.vespa.hosted.routing.restapi; import com.yahoo.component.annotation.Inject; +import com.yahoo.config.provision.zone.RoutingMethod; import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.container.jdisc.ThreadedHttpRequestHandler; @@ -73,7 +74,7 @@ public class AkamaiHandler extends ThreadedHttpRequestHandler { private HttpResponse status(HttpRequest request) { String hostHeader = request.getHeader("host"); String hostname = withoutPort(hostHeader); - Optional<RoutingTable.Target> target = tableSupplier.get().flatMap(table -> table.targetOf(hostname)); + Optional<RoutingTable.Target> target = tableSupplier.get().flatMap(table -> table.targetOf(hostname, RoutingMethod.sharedLayer4)); if (target.isEmpty()) return response(404, hostHeader, "", ROTATION_UNKNOWN_MESSAGE); diff --git a/routing-generator/src/test/java/com/yahoo/vespa/hosted/routing/RoutingTableTest.java b/routing-generator/src/test/java/com/yahoo/vespa/hosted/routing/RoutingTableTest.java index 288eabe16f7..dc4df7d45ad 100644 --- a/routing-generator/src/test/java/com/yahoo/vespa/hosted/routing/RoutingTableTest.java +++ b/routing-generator/src/test/java/com/yahoo/vespa/hosted/routing/RoutingTableTest.java @@ -5,6 +5,7 @@ import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ApplicationName; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.TenantName; +import com.yahoo.config.provision.zone.RoutingMethod; import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.vespa.hosted.routing.RoutingTable.Endpoint; import com.yahoo.vespa.hosted.routing.RoutingTable.Real; @@ -24,31 +25,43 @@ public class RoutingTableTest { @Test public void translate_from_lb_services_config() { RoutingTable expected = new RoutingTable(Map.of( - new Endpoint("beta.music.vespa.us-north-1.vespa.oath.cloud"), + new Endpoint("beta.music.vespa.us-north-1.vespa.oath.cloud", RoutingMethod.sharedLayer4), Target.create(ApplicationId.from("vespa", "music", "beta"), ClusterSpec.Id.from("default"), ZoneId.from("prod.us-north-1"), List.of(new Real("host3-beta", 4443, 1, true), new Real("host4-beta", 4443, 1, true))), - new Endpoint("music.vespa.global.vespa.oath.cloud"), + new Endpoint("music.vespa.global.vespa.oath.cloud", RoutingMethod.sharedLayer4), Target.create(ApplicationId.from("vespa", "music", "default"), ClusterSpec.Id.from("default"), ZoneId.from("prod.us-north-1"), List.of(new Real("host1-default", 4443, 1, true), new Real("host2-default", 4443, 1, true))), - new Endpoint("music.vespa.us-north-1.vespa.oath.cloud"), + new Endpoint("music.vespa.us-north-1.vespa.oath.cloud", RoutingMethod.sharedLayer4), Target.create(ApplicationId.from("vespa", "music", "default"), ClusterSpec.Id.from("default"), ZoneId.from("prod.us-north-1"), List.of(new Real("host1-default", 4443, 1, true), new Real("host2-default", 4443, 1, true))), - new Endpoint("rotation-02.vespa.global.routing"), + new Endpoint("rotation-02.vespa.global.routing", RoutingMethod.sharedLayer4), Target.create(ApplicationId.from("vespa", "music", "default"), ClusterSpec.Id.from("default"), ZoneId.from("prod.us-north-1"), List.of(new Real("host1-default", 4443, 1, true), new Real("host2-default", 4443, 1, true))), - new Endpoint("use-weighted.music.vespa.us-north-1-r.vespa.oath.cloud"), + new Endpoint("rotation-02.vespa.global.routing", RoutingMethod.shared), + Target.create(ApplicationId.from("vespa", "music", "default"), + ClusterSpec.Id.from("default"), ZoneId.from("prod.us-north-1"), + List.of(new Real("host1-default", 4443, 1, true), + new Real("host2-default", 4443, 1, true))), + + new Endpoint("music--vespa.global.vespa.oath.cloud", RoutingMethod.shared), + Target.create(ApplicationId.from("vespa", "music", "default"), + ClusterSpec.Id.from("default"), ZoneId.from("prod.us-north-1"), + List.of(new Real("host1-default", 4443, 1, true), + new Real("host2-default", 4443, 1, true))), + + new Endpoint("use-weighted.music.vespa.us-north-1-r.vespa.oath.cloud", RoutingMethod.sharedLayer4), Target.create("use-weighted.music.vespa.us-north-1-r.vespa.oath.cloud", TenantName.from("vespa"), ApplicationName.from("music"), ClusterSpec.Id.from("default"), ZoneId.from("prod.us-north-1"), List.of(new Real("host3-beta", 4443, 1, true), diff --git a/routing-generator/src/test/java/com/yahoo/vespa/hosted/routing/nginx/NginxMetricsReporterTest.java b/routing-generator/src/test/java/com/yahoo/vespa/hosted/routing/nginx/NginxMetricsReporterTest.java index 72014047db7..eea3724e7e9 100644 --- a/routing-generator/src/test/java/com/yahoo/vespa/hosted/routing/nginx/NginxMetricsReporterTest.java +++ b/routing-generator/src/test/java/com/yahoo/vespa/hosted/routing/nginx/NginxMetricsReporterTest.java @@ -4,6 +4,7 @@ package com.yahoo.vespa.hosted.routing.nginx; import com.google.common.jimfs.Jimfs; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ClusterSpec; +import com.yahoo.config.provision.zone.RoutingMethod; import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.jdisc.test.MockMetric; import com.yahoo.vespa.hosted.routing.RoutingTable; @@ -152,10 +153,10 @@ public class NginxMetricsReporterTest { } private static RoutingTable createRoutingTable() { - return new RoutingTable(Map.of(new Endpoint("endpoint0"), target0, - new Endpoint("endpoint1"), target1, - new Endpoint("endpoint2"), target2, - new Endpoint("endpoint3"), target3), + return new RoutingTable(Map.of(new Endpoint("endpoint0", RoutingMethod.sharedLayer4), target0, + new Endpoint("endpoint1", RoutingMethod.sharedLayer4), target1, + new Endpoint("endpoint2", RoutingMethod.sharedLayer4), target2, + new Endpoint("endpoint3", RoutingMethod.sharedLayer4), target3), 42); } diff --git a/routing-generator/src/test/java/com/yahoo/vespa/hosted/routing/nginx/NginxTest.java b/routing-generator/src/test/java/com/yahoo/vespa/hosted/routing/nginx/NginxTest.java index bea4d2a822c..f422ae411db 100644 --- a/routing-generator/src/test/java/com/yahoo/vespa/hosted/routing/nginx/NginxTest.java +++ b/routing-generator/src/test/java/com/yahoo/vespa/hosted/routing/nginx/NginxTest.java @@ -5,6 +5,7 @@ import com.google.common.jimfs.Jimfs; import com.yahoo.collections.Pair; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ClusterSpec; +import com.yahoo.config.provision.zone.RoutingMethod; import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.jdisc.test.MockMetric; import com.yahoo.system.ProcessExecuter; @@ -65,7 +66,7 @@ public class NginxTest { // A new table is loaded Map<RoutingTable.Endpoint, RoutingTable.Target> newEntries = new HashMap<>(table0.asMap()); - newEntries.put(new RoutingTable.Endpoint("endpoint1"), + newEntries.put(new RoutingTable.Endpoint("endpoint1", RoutingMethod.sharedLayer4), RoutingTable.Target.create(ApplicationId.from("t1", "a1", "i1"), ClusterSpec.Id.from("default"), ZoneId.from("prod", "us-north-1"), diff --git a/routing-generator/src/test/java/com/yahoo/vespa/hosted/routing/restapi/AkamaiHandlerTest.java b/routing-generator/src/test/java/com/yahoo/vespa/hosted/routing/restapi/AkamaiHandlerTest.java index e38d5a654f7..2814fcff8f7 100644 --- a/routing-generator/src/test/java/com/yahoo/vespa/hosted/routing/restapi/AkamaiHandlerTest.java +++ b/routing-generator/src/test/java/com/yahoo/vespa/hosted/routing/restapi/AkamaiHandlerTest.java @@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.routing.restapi; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ClusterSpec; +import com.yahoo.config.provision.zone.RoutingMethod; import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.container.jdisc.HttpRequestBuilder; @@ -93,10 +94,10 @@ public class AkamaiHandlerTest { private static RoutingTable makeRoutingTable() { return new RoutingTable(Map.of( - new Endpoint(ENDPOINT_OK), createTarget("t1", "a1", "i1", "default", true), - new Endpoint(ENDPOINT_UNAVAILABLE), createTarget("t3", "a3", "i3", "default", true), - new Endpoint(ENDPOINT_UNHEALTHY), createTarget("t2", "a2", "i2", "default", true), - new Endpoint(ENDPOINT_INACTIVE), createTarget("t1", "a1", "i1", "default", false) + new Endpoint(ENDPOINT_OK, RoutingMethod.sharedLayer4), createTarget("t1", "a1", "i1", "default", true), + new Endpoint(ENDPOINT_UNAVAILABLE, RoutingMethod.sharedLayer4), createTarget("t3", "a3", "i3", "default", true), + new Endpoint(ENDPOINT_UNHEALTHY, RoutingMethod.sharedLayer4), createTarget("t2", "a2", "i2", "default", true), + new Endpoint(ENDPOINT_INACTIVE, RoutingMethod.sharedLayer4), createTarget("t1", "a1", "i1", "default", false) ), 42); } diff --git a/routing-generator/src/test/resources/lbservices-config b/routing-generator/src/test/resources/lbservices-config index d19fc5ee4ae..9c79a9b063f 100644 --- a/routing-generator/src/test/resources/lbservices-config +++ b/routing-generator/src/test/resources/lbservices-config @@ -15,18 +15,32 @@ tenants.vespa.applications.music:prod:us-north-1:default.endpoints[1].routingMet tenants.vespa.applications.music:prod:us-north-1:default.endpoints[1].weight 1 tenants.vespa.applications.music:prod:us-north-1:default.endpoints[2].hosts[0] "host1-default" tenants.vespa.applications.music:prod:us-north-1:default.endpoints[2].hosts[1] "host2-default" -tenants.vespa.applications.music:prod:us-north-1:default.endpoints[2].dnsName "rotation-02.vespa.global.routing" +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[2].dnsName "music--vespa.global.vespa.oath.cloud" tenants.vespa.applications.music:prod:us-north-1:default.endpoints[2].clusterId "default" tenants.vespa.applications.music:prod:us-north-1:default.endpoints[2].scope "global" -tenants.vespa.applications.music:prod:us-north-1:default.endpoints[2].routingMethod "sharedLayer4" +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[2].routingMethod "shared" tenants.vespa.applications.music:prod:us-north-1:default.endpoints[2].weight 1 tenants.vespa.applications.music:prod:us-north-1:default.endpoints[3].hosts[0] "host1-default" tenants.vespa.applications.music:prod:us-north-1:default.endpoints[3].hosts[1] "host2-default" -tenants.vespa.applications.music:prod:us-north-1:default.endpoints[3].dnsName "use-weighted.music.vespa.us-north-1-r.vespa.oath.cloud" +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[3].dnsName "rotation-02.vespa.global.routing" tenants.vespa.applications.music:prod:us-north-1:default.endpoints[3].clusterId "default" -tenants.vespa.applications.music:prod:us-north-1:default.endpoints[3].scope "application" +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[3].scope "global" tenants.vespa.applications.music:prod:us-north-1:default.endpoints[3].routingMethod "sharedLayer4" -tenants.vespa.applications.music:prod:us-north-1:default.endpoints[3].weight 0 +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[3].weight 1 +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[4].hosts[0] "host1-default" +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[4].hosts[1] "host2-default" +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[4].dnsName "rotation-02.vespa.global.routing" +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[4].clusterId "default" +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[4].scope "global" +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[4].routingMethod "shared" +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[4].weight 1 +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[5].hosts[0] "host1-default" +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[5].hosts[1] "host2-default" +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[5].dnsName "use-weighted.music.vespa.us-north-1-r.vespa.oath.cloud" +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[5].clusterId "default" +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[5].scope "application" +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[5].routingMethod "sharedLayer4" +tenants.vespa.applications.music:prod:us-north-1:default.endpoints[5].weight 0 tenants.vespa.applications.music:prod:us-north-1:beta.activeRotation true tenants.vespa.applications.music:prod:us-north-1:beta.endpoints[0].hosts[0] "host3-beta" tenants.vespa.applications.music:prod:us-north-1:beta.endpoints[0].hosts[1] "host4-beta" |