diff options
author | Martin Polden <mpolden@mpolden.no> | 2021-10-22 09:06:14 +0200 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2021-10-22 09:06:14 +0200 |
commit | f099b80ba8fbf902c3800d6b02ad62715db0c657 (patch) | |
tree | e8687d3e8ab7422f3413dcf5dad7f6e0bf3dc482 | |
parent | 9abe019606f2367b05e4e13d796de65dddf7c449 (diff) |
Support building named region endpoints
3 files changed, 113 insertions, 79 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Endpoint.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Endpoint.java index b441d40c1c3..67156ec4f41 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Endpoint.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Endpoint.java @@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.controller.application; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ClusterSpec; +import com.yahoo.config.provision.InstanceName; import com.yahoo.config.provision.RegionName; import com.yahoo.config.provision.SystemName; import com.yahoo.config.provision.zone.RoutingMethod; @@ -13,13 +14,15 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId; import java.net.URI; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; /** - * Represents an application's endpoint in hosted Vespa. This encapsulates all logic for building URLs and DNS names for - * application endpoints. + * Represents an application or instance endpoint in hosted Vespa. + * + * This encapsulates the logic for building URLs and DNS names for applications in all hosted Vespa systems. * * @author mpolden */ @@ -50,7 +53,7 @@ public class Endpoint { if (scope == Scope.global) { if (id == null) throw new IllegalArgumentException("Endpoint ID must be set for global endpoints"); } else { - if (id != null) throw new IllegalArgumentException("Endpoint ID cannot be set for " + scope + " endpoints"); + if (scope == Scope.zone && id != null) throw new IllegalArgumentException("Endpoint ID cannot be set for " + scope + " endpoints"); if (zones.size() != 1) throw new IllegalArgumentException("A single zone must be given for " + scope + " endpoints"); } this.id = id; @@ -63,12 +66,14 @@ public class Endpoint { this.tls = port.tls; } - private Endpoint(EndpointId id, ClusterSpec.Id cluster, ApplicationId application, List<ZoneId> zones, Scope scope, SystemName system, - Port port, boolean legacy, RoutingMethod routingMethod) { + private Endpoint(EndpointId id, ClusterSpec.Id cluster, TenantAndApplicationId application, + Optional<InstanceName> instance, List<ZoneId> zones, Scope scope, SystemName system, Port port, + boolean legacy, RoutingMethod routingMethod) { this(id, cluster, createUrl(endpointOrClusterAsString(id, cluster), Objects.requireNonNull(application, "application must be non-null"), + Objects.requireNonNull(instance, "instance must be non-null"), zones, scope, Objects.requireNonNull(system, "system must be non-null"), @@ -164,15 +169,16 @@ public class Endpoint { return id == null ? cluster.value() : id.id(); } - private static URI createUrl(String name, ApplicationId application, List<ZoneId> zones, Scope scope, - SystemName system, Port port, boolean legacy, RoutingMethod routingMethod) { + private static URI createUrl(String name, TenantAndApplicationId application, Optional<InstanceName> instance, + List<ZoneId> zones, Scope scope, SystemName system, Port port, boolean legacy, + RoutingMethod routingMethod) { String scheme = port.tls ? "https" : "http"; String separator = separator(system, routingMethod, port.tls); String portPart = port.isDefault() ? "" : ":" + port.port; return URI.create(scheme + "://" + sanitize(namePart(name, separator)) + systemPart(system, separator, legacy) + - sanitize(instancePart(application, separator)) + + sanitize(instancePart(instance, separator)) + sanitize(application.application().value()) + separator + sanitize(application.tenant().value()) + @@ -216,9 +222,10 @@ public class Endpoint { return region + "." + zone.environment().value(); } - private static String instancePart(ApplicationId application, String separator) { - if (application.instance().isDefault()) return ""; // Skip "default" - return application.instance().value() + separator; + private static String instancePart(Optional<InstanceName> instance, String separator) { + if (instance.isEmpty()) return ""; + if (instance.get().isDefault()) return ""; // Skip "default" + return instance.get().value() + separator; } private static String systemPart(SystemName system, String separator, boolean legacy) { @@ -246,7 +253,7 @@ public class Endpoint { private static String upstreamIdOf(String name, ApplicationId application, ZoneId zone) { return Stream.of(namePart(name, ""), - instancePart(application, ""), + instancePart(Optional.of(application.instance()), ""), application.application().value(), application.tenant().value(), zone.region().value(), @@ -338,9 +345,14 @@ public class Endpoint { } + /** Build an endpoint for given instance */ + public static EndpointBuilder of(ApplicationId instance) { + return new EndpointBuilder(TenantAndApplicationId.from(instance), Optional.of(instance.instance())); + } + /** Build an endpoint for given application */ - public static EndpointBuilder of(ApplicationId application) { - return new EndpointBuilder(application); + public static EndpointBuilder of(TenantAndApplicationId application) { + return new EndpointBuilder(application, Optional.empty()); } /** Create an endpoint for given system application */ @@ -353,7 +365,8 @@ public class Endpoint { public static class EndpointBuilder { - private final ApplicationId application; + private final TenantAndApplicationId application; + private final Optional<InstanceName> instance; private Scope scope; private List<ZoneId> zones; @@ -363,8 +376,9 @@ public class Endpoint { private RoutingMethod routingMethod = RoutingMethod.shared; private boolean legacy = false; - private EndpointBuilder(ApplicationId application) { - this.application = application; + private EndpointBuilder(TenantAndApplicationId application, Optional<InstanceName> instance) { + this.application = Objects.requireNonNull(application); + this.instance = Objects.requireNonNull(instance); } /** Sets the zone target for this */ @@ -410,6 +424,12 @@ public class Endpoint { return this; } + /** Sets the region target for this by endpointId, deduced from given zone */ + public EndpointBuilder targetRegion(EndpointId endpointId, ClusterSpec.Id cluster, ZoneId zone) { + this.endpointId = endpointId; + return targetRegion(cluster, zone); + } + /** Sets the port of this */ public EndpointBuilder on(Port port) { this.port = port; @@ -436,7 +456,7 @@ public class Endpoint { if (routingMethod.isDirect() && !port.isDefault()) { throw new IllegalArgumentException("Routing method " + routingMethod + " can only use default port"); } - return new Endpoint(endpointId, cluster, application, zones, scope, system, port, legacy, routingMethod); + return new Endpoint(endpointId, cluster, application, instance, zones, scope, system, port, legacy, routingMethod); } private void checkScope() { diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackageValidator.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackageValidator.java index 3dc95251eb8..bd6376e58aa 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackageValidator.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackageValidator.java @@ -102,7 +102,7 @@ public class ApplicationPackageValidator { instant)); } - /** Verify that compactable endpoint parts (instance aname nd endpoint ID) do not clash */ + /** Verify that compactable endpoint parts (instance name and endpoint ID) do not clash */ private void validateCompactedEndpoint(ApplicationPackage applicationPackage) { Map<List<String>, InstanceEndpoint> instanceEndpoints = new HashMap<>(); for (var instanceSpec : applicationPackage.deploymentSpec().instances()) { diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/EndpointTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/EndpointTest.java index da641d17a8a..00154227f66 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/EndpointTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/EndpointTest.java @@ -20,8 +20,10 @@ import static org.junit.Assert.assertEquals; */ public class EndpointTest { - private static final ApplicationId app1 = ApplicationId.from("t1", "a1", "default"); - private static final ApplicationId app2 = ApplicationId.from("t2", "a2", "i2"); + private static final ApplicationId instance1 = ApplicationId.from("t1", "a1", "default"); + private static final ApplicationId instance2 = ApplicationId.from("t2", "a2", "i2"); + private static final TenantAndApplicationId app1 = TenantAndApplicationId.from(instance1); + private static final TenantAndApplicationId app2 = TenantAndApplicationId.from(instance2); @Test public void global_endpoints() { @@ -30,62 +32,62 @@ public class EndpointTest { Map<String, Endpoint> tests = Map.of( // Legacy endpoint "http://a1.t1.global.vespa.yahooapis.com:4080/", - Endpoint.of(app1).target(endpointId).on(Port.plain(4080)).legacy().in(SystemName.main), + Endpoint.of(instance1).target(endpointId).on(Port.plain(4080)).legacy().in(SystemName.main), // Legacy endpoint with TLS "https://a1--t1.global.vespa.yahooapis.com:4443/", - Endpoint.of(app1).target(endpointId).on(Port.tls(4443)).legacy().in(SystemName.main), + Endpoint.of(instance1).target(endpointId).on(Port.tls(4443)).legacy().in(SystemName.main), // Main endpoint "https://a1--t1.global.vespa.oath.cloud:4443/", - Endpoint.of(app1).target(endpointId).on(Port.tls(4443)).in(SystemName.main), + Endpoint.of(instance1).target(endpointId).on(Port.tls(4443)).in(SystemName.main), // Main endpoint in CD "https://cd--a1--t1.global.vespa.oath.cloud:4443/", - Endpoint.of(app1).target(endpointId).on(Port.tls(4443)).in(SystemName.cd), + Endpoint.of(instance1).target(endpointId).on(Port.tls(4443)).in(SystemName.cd), // Main endpoint in CD "https://cd--i2--a2--t2.global.vespa.oath.cloud:4443/", - Endpoint.of(app2).target(endpointId).on(Port.tls(4443)).in(SystemName.cd), + Endpoint.of(instance2).target(endpointId).on(Port.tls(4443)).in(SystemName.cd), // Main endpoint with direct routing and default TLS port "https://a1.t1.global.vespa.oath.cloud/", - Endpoint.of(app1).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main), + Endpoint.of(instance1).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main), // Main endpoint with custom rotation name "https://r1.a1.t1.global.vespa.oath.cloud/", - Endpoint.of(app1).target(EndpointId.of("r1")).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main), + Endpoint.of(instance1).target(EndpointId.of("r1")).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main), // Main endpoint for custom instance in default rotation "https://i2.a2.t2.global.vespa.oath.cloud/", - Endpoint.of(app2).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main), + Endpoint.of(instance2).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main), // Main endpoint for custom instance with custom rotation name "https://r2.i2.a2.t2.global.vespa.oath.cloud/", - Endpoint.of(app2).target(EndpointId.of("r2")).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main), + Endpoint.of(instance2).target(EndpointId.of("r2")).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main), // Main endpoint in public system (legacy) "https://a1.t1.global.public.vespa.oath.cloud/", - Endpoint.of(app1).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).legacy().in(SystemName.Public) + Endpoint.of(instance1).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).legacy().in(SystemName.Public) ); tests.forEach((expected, endpoint) -> assertEquals(expected, endpoint.url().toString())); Map<String, Endpoint> tests2 = Map.of( // Main endpoint in public CD system (legacy) "https://publiccd.a1.t1.global.public-cd.vespa.oath.cloud/", - Endpoint.of(app1).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).legacy().in(SystemName.PublicCd), + Endpoint.of(instance1).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).legacy().in(SystemName.PublicCd), // Default endpoint in public system "https://a1.t1.g.vespa-app.cloud/", - Endpoint.of(app1).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public), + Endpoint.of(instance1).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public), // Default endpoint in public CD system "https://a1.t1.g.cd.vespa-app.cloud/", - Endpoint.of(app1).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.PublicCd), + Endpoint.of(instance1).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.PublicCd), // Custom instance in public system "https://i2.a2.t2.g.vespa-app.cloud/", - Endpoint.of(app2).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public) + Endpoint.of(instance2).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public) ); tests2.forEach((expected, endpoint) -> assertEquals(expected, endpoint.url().toString())); } @@ -97,54 +99,54 @@ public class EndpointTest { Map<String, Endpoint> tests = Map.of( // Legacy endpoint "http://a1.t1.global.vespa.yahooapis.com:4080/", - Endpoint.of(app1).target(endpointId).on(Port.plain(4080)).legacy().in(SystemName.main), + Endpoint.of(instance1).target(endpointId).on(Port.plain(4080)).legacy().in(SystemName.main), // Legacy endpoint with TLS "https://a1--t1.global.vespa.yahooapis.com:4443/", - Endpoint.of(app1).target(endpointId).on(Port.tls(4443)).legacy().in(SystemName.main), + Endpoint.of(instance1).target(endpointId).on(Port.tls(4443)).legacy().in(SystemName.main), // Main endpoint "https://a1--t1.global.vespa.oath.cloud:4443/", - Endpoint.of(app1).target(endpointId).on(Port.tls(4443)).in(SystemName.main), + Endpoint.of(instance1).target(endpointId).on(Port.tls(4443)).in(SystemName.main), // Main endpoint in CD "https://cd--i2--a2--t2.global.vespa.oath.cloud:4443/", - Endpoint.of(app2).target(endpointId).on(Port.tls(4443)).in(SystemName.cd), + Endpoint.of(instance2).target(endpointId).on(Port.tls(4443)).in(SystemName.cd), // Main endpoint in CD "https://cd--a1--t1.global.vespa.oath.cloud:4443/", - Endpoint.of(app1).target(endpointId).on(Port.tls(4443)).in(SystemName.cd), + Endpoint.of(instance1).target(endpointId).on(Port.tls(4443)).in(SystemName.cd), // Main endpoint with direct routing and default TLS port "https://a1.t1.global.vespa.oath.cloud/", - Endpoint.of(app1).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main), + Endpoint.of(instance1).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main), // Main endpoint with custom rotation name "https://r1.a1.t1.global.vespa.oath.cloud/", - Endpoint.of(app1).target(EndpointId.of("r1")).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main), + Endpoint.of(instance1).target(EndpointId.of("r1")).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main), // Main endpoint for custom instance in default rotation "https://i2.a2.t2.global.vespa.oath.cloud/", - Endpoint.of(app2).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main), + Endpoint.of(instance2).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main), // Main endpoint for custom instance with custom rotation name "https://r2.i2.a2.t2.global.vespa.oath.cloud/", - Endpoint.of(app2).target(EndpointId.of("r2")).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main), + Endpoint.of(instance2).target(EndpointId.of("r2")).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.main), // Main endpoint in public system (legacy) "https://a1.t1.global.public.vespa.oath.cloud/", - Endpoint.of(app1).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).legacy().in(SystemName.Public) + Endpoint.of(instance1).target(endpointId).on(Port.tls()).routingMethod(RoutingMethod.exclusive).legacy().in(SystemName.Public) ); tests.forEach((expected, endpoint) -> assertEquals(expected, endpoint.url().toString())); Map<String, Endpoint> tests2 = Map.of( // Custom endpoint and instance in public CD system (legacy) "https://foo.publiccd.i2.a2.t2.global.public-cd.vespa.oath.cloud/", - Endpoint.of(app2).target(EndpointId.of("foo")).on(Port.tls()).routingMethod(RoutingMethod.exclusive).legacy().in(SystemName.PublicCd), + Endpoint.of(instance2).target(EndpointId.of("foo")).on(Port.tls()).routingMethod(RoutingMethod.exclusive).legacy().in(SystemName.PublicCd), // Custom endpoint and instance in public system "https://foo.i2.a2.t2.g.vespa-app.cloud/", - Endpoint.of(app2).target(EndpointId.of("foo")).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public) + Endpoint.of(instance2).target(EndpointId.of("foo")).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public) ); tests2.forEach((expected, endpoint) -> assertEquals(expected, endpoint.url().toString())); } @@ -158,62 +160,62 @@ public class EndpointTest { Map<String, Endpoint> tests = Map.of( // Legacy endpoint (always contains environment) "http://a1.t1.us-north-1.prod.vespa.yahooapis.com:4080/", - Endpoint.of(app1).target(cluster, prodZone).on(Port.plain(4080)).legacy().in(SystemName.main), + Endpoint.of(instance1).target(cluster, prodZone).on(Port.plain(4080)).legacy().in(SystemName.main), // Secure legacy endpoint "https://a1--t1.us-north-1.prod.vespa.yahooapis.com:4443/", - Endpoint.of(app1).target(cluster, prodZone).on(Port.tls(4443)).legacy().in(SystemName.main), + Endpoint.of(instance1).target(cluster, prodZone).on(Port.tls(4443)).legacy().in(SystemName.main), // Prod endpoint in main "https://a1--t1.us-north-1.vespa.oath.cloud:4443/", - Endpoint.of(app1).target(cluster, prodZone).on(Port.tls(4443)).in(SystemName.main), + Endpoint.of(instance1).target(cluster, prodZone).on(Port.tls(4443)).in(SystemName.main), // Prod endpoint in CD "https://cd--a1--t1.us-north-1.vespa.oath.cloud:4443/", - Endpoint.of(app1).target(cluster, prodZone).on(Port.tls(4443)).in(SystemName.cd), + Endpoint.of(instance1).target(cluster, prodZone).on(Port.tls(4443)).in(SystemName.cd), // Test endpoint in main "https://a1--t1.us-north-2.test.vespa.oath.cloud:4443/", - Endpoint.of(app1).target(cluster, testZone).on(Port.tls(4443)).in(SystemName.main), + Endpoint.of(instance1).target(cluster, testZone).on(Port.tls(4443)).in(SystemName.main), // Non-default cluster in main "https://c1--a1--t1.us-north-1.vespa.oath.cloud/", - Endpoint.of(app1).target(ClusterSpec.Id.from("c1"), prodZone).on(Port.tls()).in(SystemName.main), + Endpoint.of(instance1).target(ClusterSpec.Id.from("c1"), prodZone).on(Port.tls()).in(SystemName.main), // Non-default instance in main "https://i2--a2--t2.us-north-1.vespa.oath.cloud:4443/", - Endpoint.of(app2).target(cluster, prodZone).on(Port.tls(4443)).in(SystemName.main), + Endpoint.of(instance2).target(cluster, prodZone).on(Port.tls(4443)).in(SystemName.main), // Non-default cluster in public (legacy) "https://c1.a1.t1.us-north-1.public.vespa.oath.cloud/", - Endpoint.of(app1).target(ClusterSpec.Id.from("c1"), prodZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).legacy().in(SystemName.Public), + Endpoint.of(instance1).target(ClusterSpec.Id.from("c1"), prodZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).legacy().in(SystemName.Public), // Non-default cluster and instance in public (legacy) "https://c2.i2.a2.t2.us-north-1.public.vespa.oath.cloud/", - Endpoint.of(app2).target(ClusterSpec.Id.from("c2"), prodZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).legacy().in(SystemName.Public), + Endpoint.of(instance2).target(ClusterSpec.Id.from("c2"), prodZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).legacy().in(SystemName.Public), // Endpoint in main using shared layer 4 "https://a1.t1.us-north-1.vespa.oath.cloud/", - Endpoint.of(app1).target(cluster, prodZone).on(Port.tls()).routingMethod(RoutingMethod.sharedLayer4).in(SystemName.main) + Endpoint.of(instance1).target(cluster, prodZone).on(Port.tls()).routingMethod(RoutingMethod.sharedLayer4).in(SystemName.main) ); tests.forEach((expected, endpoint) -> assertEquals(expected, endpoint.url().toString())); Map<String, Endpoint> tests2 = Map.of( // Non-default cluster and instance in public CD (legacy) "https://c2.publiccd.i2.a2.t2.us-north-1.public-cd.vespa.oath.cloud/", - Endpoint.of(app2).target(ClusterSpec.Id.from("c2"), prodZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).legacy().in(SystemName.PublicCd), + Endpoint.of(instance2).target(ClusterSpec.Id.from("c2"), prodZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).legacy().in(SystemName.PublicCd), // Custom cluster name in public "https://c1.a1.t1.us-north-1.z.vespa-app.cloud/", - Endpoint.of(app1).target(ClusterSpec.Id.from("c1"), prodZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public), + Endpoint.of(instance1).target(ClusterSpec.Id.from("c1"), prodZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public), // Default cluster name in non-production zone in public "https://a1.t1.us-north-2.test.z.vespa-app.cloud/", - Endpoint.of(app1).target(ClusterSpec.Id.from("default"), testZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public), + Endpoint.of(instance1).target(ClusterSpec.Id.from("default"), testZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.Public), // Default cluster name in public CD "https://a1.t1.us-north-1.z.cd.vespa-app.cloud/", - Endpoint.of(app1).target(ClusterSpec.Id.from("default"), prodZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.PublicCd) + Endpoint.of(instance1).target(ClusterSpec.Id.from("default"), prodZone).on(Port.tls()).routingMethod(RoutingMethod.exclusive).in(SystemName.PublicCd) ); tests2.forEach((expected, endpoint) -> assertEquals(expected, endpoint.url().toString())); } @@ -227,7 +229,7 @@ public class EndpointTest { var tests = Map.of( // Default rotation "https://a1.t1.global.public.vespa.oath.cloud/", - Endpoint.of(app1) + Endpoint.of(instance1) .target(EndpointId.defaultId()) .routingMethod(RoutingMethod.exclusive) .on(Port.tls()) @@ -236,7 +238,7 @@ public class EndpointTest { // Wildcard to match other rotations "https://*.a1.t1.global.public.vespa.oath.cloud/", - Endpoint.of(app1) + Endpoint.of(instance1) .wildcard() .routingMethod(RoutingMethod.exclusive) .on(Port.tls()) @@ -245,7 +247,7 @@ public class EndpointTest { // Default cluster in zone "https://a1.t1.us-north-1.public.vespa.oath.cloud/", - Endpoint.of(app1) + Endpoint.of(instance1) .target(defaultCluster, prodZone) .routingMethod(RoutingMethod.exclusive) .on(Port.tls()) @@ -254,7 +256,7 @@ public class EndpointTest { // Wildcard to match other clusters in zone "https://*.a1.t1.us-north-1.public.vespa.oath.cloud/", - Endpoint.of(app1) + Endpoint.of(instance1) .wildcard(prodZone) .routingMethod(RoutingMethod.exclusive) .on(Port.tls()) @@ -263,7 +265,7 @@ public class EndpointTest { // Default cluster in test zone "https://a1.t1.us-north-2.test.public.vespa.oath.cloud/", - Endpoint.of(app1) + Endpoint.of(instance1) .target(defaultCluster, testZone) .routingMethod(RoutingMethod.exclusive) .on(Port.tls()) @@ -272,7 +274,7 @@ public class EndpointTest { // Wildcard to match other clusters in test zone "https://*.a1.t1.us-north-2.test.public.vespa.oath.cloud/", - Endpoint.of(app1) + Endpoint.of(instance1) .wildcard(testZone) .routingMethod(RoutingMethod.exclusive) .on(Port.tls()) @@ -281,7 +283,7 @@ public class EndpointTest { // Wildcard to match other clusters in zone "https://*.a1.t1.us-north-1.z.vespa-app.cloud/", - Endpoint.of(app1) + Endpoint.of(instance1) .wildcard(prodZone) .routingMethod(RoutingMethod.exclusive) .on(Port.tls()) @@ -297,35 +299,47 @@ public class EndpointTest { var prodZone = ZoneId.from("prod", "us-north-2"); Map<String, Endpoint> tests = Map.of( "https://a1.t1.us-north-1-w.public.vespa.oath.cloud/", - Endpoint.of(app1) + Endpoint.of(instance1) .targetRegion(cluster, ZoneId.from("prod", "us-north-1a")) .routingMethod(RoutingMethod.exclusive) .on(Port.tls()) .legacy() .in(SystemName.Public), "https://a1.t1.us-north-2-w.public.vespa.oath.cloud/", - Endpoint.of(app1) + Endpoint.of(instance1) .targetRegion(cluster, prodZone) .routingMethod(RoutingMethod.exclusive) .on(Port.tls()) .legacy() .in(SystemName.Public), "https://a1.t1.us-north-2-w.test.public.vespa.oath.cloud/", - Endpoint.of(app1) + Endpoint.of(instance1) .targetRegion(cluster, ZoneId.from("test", "us-north-2")) .routingMethod(RoutingMethod.exclusive) .on(Port.tls()) .legacy() .in(SystemName.Public), "https://c1.a1.t1.us-north-2.r.vespa-app.cloud/", - Endpoint.of(app1) + Endpoint.of(instance1) .targetRegion(ClusterSpec.Id.from("c1"), prodZone) .routingMethod(RoutingMethod.exclusive) .on(Port.tls()) + .in(SystemName.Public), + "https://r0.a1.t1.us-north-2-w.vespa.oath.cloud/", + Endpoint.of(app1) + .targetRegion(EndpointId.of("r0"), ClusterSpec.Id.from("c1"), prodZone) + .routingMethod(RoutingMethod.sharedLayer4) + .on(Port.tls()) + .in(SystemName.main), + "https://r0.a2.t2.us-north-2.r.vespa-app.cloud/", + Endpoint.of(app2) + .targetRegion(EndpointId.of("r0"), ClusterSpec.Id.from("c1"), prodZone) + .routingMethod(RoutingMethod.exclusive) + .on(Port.tls()) .in(SystemName.Public) ); tests.forEach((expected, endpoint) -> assertEquals(expected, endpoint.url().toString())); - Endpoint endpoint = Endpoint.of(app1) + Endpoint endpoint = Endpoint.of(instance1) .targetRegion(cluster, ZoneId.from("prod", "us-north-1a")) .routingMethod(RoutingMethod.exclusive) .on(Port.tls()) @@ -341,23 +355,23 @@ public class EndpointTest { var tests1 = Map.of( // With default cluster "a1.t1.us-north-1.prod", - Endpoint.of(app1).target(EndpointId.defaultId()).on(Port.tls(4443)).in(SystemName.main), + Endpoint.of(instance1).target(EndpointId.defaultId()).on(Port.tls(4443)).in(SystemName.main), // With non-default cluster "c1.a1.t1.us-north-1.prod", - Endpoint.of(app1).target(EndpointId.of("ignored1"), ClusterSpec.Id.from("c1"), List.of(zone)).on(Port.tls(4443)).in(SystemName.main) + Endpoint.of(instance1).target(EndpointId.of("ignored1"), ClusterSpec.Id.from("c1"), List.of(zone)).on(Port.tls(4443)).in(SystemName.main) ); var tests2 = Map.of( // With non-default instance and default cluster "i2.a2.t2.us-north-1.prod", - Endpoint.of(app2).target(EndpointId.defaultId(), ClusterSpec.Id.from("default"), List.of(zone)).on(Port.tls(4443)).in(SystemName.main), + Endpoint.of(instance2).target(EndpointId.defaultId(), ClusterSpec.Id.from("default"), List.of(zone)).on(Port.tls(4443)).in(SystemName.main), // With non-default instance and cluster "c2.i2.a2.t2.us-north-1.prod", - Endpoint.of(app2).target(EndpointId.of("ignored2"), ClusterSpec.Id.from("c2"), List.of(zone)).on(Port.tls(4443)).in(SystemName.main) + Endpoint.of(instance2).target(EndpointId.of("ignored2"), ClusterSpec.Id.from("c2"), List.of(zone)).on(Port.tls(4443)).in(SystemName.main) ); - tests1.forEach((expected, endpoint) -> assertEquals(expected, endpoint.upstreamIdOf(new DeploymentId(app1, zone)))); - tests2.forEach((expected, endpoint) -> assertEquals(expected, endpoint.upstreamIdOf(new DeploymentId(app2, zone)))); + tests1.forEach((expected, endpoint) -> assertEquals(expected, endpoint.upstreamIdOf(new DeploymentId(instance1, zone)))); + tests2.forEach((expected, endpoint) -> assertEquals(expected, endpoint.upstreamIdOf(new DeploymentId(instance2, zone)))); } } |