diff options
6 files changed, 29 insertions, 51 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/RoutingController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/RoutingController.java index 90c4a506f10..b1ffce65852 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/RoutingController.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/RoutingController.java @@ -197,22 +197,19 @@ public class RoutingController { /** Returns the zone- and region-scoped endpoints of given deployment */ public EndpointList endpointsOf(DeploymentId deployment, ClusterSpec.Id cluster, GeneratedEndpointList generatedEndpoints) { requireGeneratedEndpoints(generatedEndpoints, false); - boolean generatedEndpointsAvailable = !generatedEndpoints.isEmpty(); boolean tokenSupported = !generatedEndpoints.authMethod(AuthMethod.token).isEmpty(); - boolean isProduction = deployment.zoneId().environment().isProduction(); RoutingMethod routingMethod = controller.zoneRegistry().routingMethod(deployment.zoneId()); + boolean isProduction = deployment.zoneId().environment().isProduction(); List<Endpoint> endpoints = new ArrayList<>(); Endpoint.EndpointBuilder zoneEndpoint = Endpoint.of(deployment.applicationId()) .routingMethod(routingMethod) .on(Port.fromRoutingMethod(routingMethod)) - .legacy(generatedEndpointsAvailable) .target(cluster, deployment); endpoints.add(zoneEndpoint.in(controller.system())); ZoneApi zone = controller.zoneRegistry().zones().all().get(deployment.zoneId()).get(); Endpoint.EndpointBuilder regionEndpoint = Endpoint.of(deployment.applicationId()) .routingMethod(routingMethod) .on(Port.fromRoutingMethod(routingMethod)) - .legacy(generatedEndpointsAvailable) .targetRegion(cluster, zone.getCloudNativeRegionName(), zone.getCloudName()); @@ -229,14 +226,12 @@ public class RoutingController { }; if (include) { endpoints.add(zoneEndpoint.generatedFrom(generatedEndpoint) - .legacy(false) .authMethod(generatedEndpoint.authMethod()) .in(controller.system())); // Only a single region endpoint is needed, not one per auth method if (isProduction && generatedEndpoint.authMethod() == AuthMethod.mtls) { GeneratedEndpoint weightedGeneratedEndpoint = generatedEndpoint.withClusterPart(weightedClusterPart(cluster, deployment)); endpoints.add(regionEndpoint.generatedFrom(weightedGeneratedEndpoint) - .legacy(false) .authMethod(AuthMethod.none) .in(controller.system())); } @@ -262,7 +257,6 @@ public class RoutingController { var endpoints = new ArrayList<Endpoint>(); var directMethods = 0; var availableRoutingMethods = routingMethodsOfAll(deployments); - boolean generatedEndpointsAvailable = !generatedEndpoints.isEmpty(); for (var method : availableRoutingMethods) { if (method.isDirect() && ++directMethods > 1) { throw new IllegalArgumentException("Invalid routing methods for " + routingId + ": Exceeded maximum " + @@ -271,11 +265,10 @@ public class RoutingController { Endpoint.EndpointBuilder builder = Endpoint.of(routingId.instance()) .target(routingId.endpointId(), cluster, deployments) .on(Port.fromRoutingMethod(method)) - .legacy(generatedEndpointsAvailable) .routingMethod(method); endpoints.add(builder.in(controller.system())); for (var ge : generatedEndpoints) { - endpoints.add(builder.generatedFrom(ge).legacy(false).authMethod(ge.authMethod()).in(controller.system())); + endpoints.add(builder.generatedFrom(ge).authMethod(ge.authMethod()).in(controller.system())); } } return filterEndpoints(routingId.instance(), EndpointList.copyOf(endpoints)); @@ -287,18 +280,16 @@ public class RoutingController { requireGeneratedEndpoints(generatedEndpoints, true); ZoneId zone = deployments.keySet().iterator().next().zoneId(); // Where multiple zones are possible, they all have the same routing method. RoutingMethod routingMethod = usesSharedRouting(zone) ? RoutingMethod.sharedLayer4 : RoutingMethod.exclusive; - boolean generatedEndpointsAvailable = !generatedEndpoints.isEmpty(); Endpoint.EndpointBuilder builder = Endpoint.of(application) .targetApplication(endpoint, cluster, deployments) .routingMethod(routingMethod) - .legacy(generatedEndpointsAvailable) .on(Port.fromRoutingMethod(routingMethod)); List<Endpoint> endpoints = new ArrayList<>(); endpoints.add(builder.in(controller.system())); for (var ge : generatedEndpoints) { - endpoints.add(builder.generatedFrom(ge).legacy(false).authMethod(ge.authMethod()).in(controller.system())); + endpoints.add(builder.generatedFrom(ge).authMethod(ge.authMethod()).in(controller.system())); } return EndpointList.copyOf(endpoints); } 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 2c13a7ddb11..5c6611f80c3 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 @@ -122,7 +122,7 @@ public class Endpoint { return scope; } - /** Returns whether this is considered a legacy DNS name intended to be removed at some point */ + /** Returns whether this is considered a legacy DNS name that is due for removal */ public boolean legacy() { return legacy; } @@ -557,9 +557,9 @@ public class Endpoint { return this; } - /** Set whether this is a legacy endpoint */ - public EndpointBuilder legacy(boolean legacy) { - this.legacy = legacy; + /** Marks this as a legacy endpoint */ + public EndpointBuilder legacy() { + this.legacy = true; return this; } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/EndpointList.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/EndpointList.java index 6e8cd16336a..310a78e45f0 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/EndpointList.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/EndpointList.java @@ -28,6 +28,11 @@ public class EndpointList extends AbstractFilteringList<Endpoint, EndpointList> } } + /** Returns the primary (non-legacy) endpoint, if any */ + public Optional<Endpoint> primary() { + return not().legacy().asList().stream().findFirst(); + } + /** Returns the subset of endpoints named according to given ID and scope */ public EndpointList named(EndpointId id, Endpoint.Scope scope) { return matching(endpoint -> endpoint.scope() == scope && // ID is only unique within a scope diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java index d3612052a75..577cc737691 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java @@ -2075,12 +2075,19 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler { metrics.instant().ifPresent(instant -> metricsObject.setLong("lastUpdated", instant.toEpochMilli())); } - private EndpointList endpointsOf(DeploymentId deploymentId, Application application, boolean includeWeighted) { + private EndpointList endpointsOf(DeploymentId deploymentId, Application application, boolean includeHidden) { EndpointList zoneEndpoints = controller.routing().readEndpointsOf(deploymentId).direct(); EndpointList declaredEndpoints = controller.routing().readDeclaredEndpointsOf(application).targets(deploymentId); EndpointList endpoints = zoneEndpoints.and(declaredEndpoints); - if (!includeWeighted) { - endpoints = endpoints.not().scope(Endpoint.Scope.weighted); + EndpointList generatedEndpoints = endpoints.generated(); + if (!includeHidden) { + // If we have generated endpoints, hide non-generated + if (!generatedEndpoints.isEmpty()) { + endpoints = endpoints.generated(); + } + // Hide legacy and weighted endpoints + endpoints = endpoints.not().legacy() + .not().scope(Endpoint.Scope.weighted); } return endpoints; } @@ -2230,7 +2237,7 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler { Cursor array = slime.setObject().setArray("globalrotationoverride"); Optional<Endpoint> primaryEndpoint = controller.routing().readDeclaredEndpointsOf(deploymentId.applicationId()) .requiresRotation() - .first(); + .primary(); if (primaryEndpoint.isPresent()) { DeploymentRoutingContext context = controller.routing().of(deploymentId); RoutingStatus status = context.routingStatus(); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/RoutingPoliciesTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/RoutingPoliciesTest.java index 22523103208..b2b34441219 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/RoutingPoliciesTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/RoutingPoliciesTest.java @@ -141,13 +141,6 @@ public class RoutingPoliciesTest { assertEquals(numberOfDeployments * clustersPerZone, tester.policiesOf(context1.instance().id()).size(), "Routing policy count is equal to cluster count"); - assertEquals(List.of(), - tester.controllerTester().controller().routing() - .readDeclaredEndpointsOf(context1.instanceId()) - .scope(Endpoint.Scope.zone) - .legacy() - .asList(), - "No endpoints marked as legacy"); // Applications gains a new deployment ApplicationPackage applicationPackage2 = applicationPackageBuilder() @@ -312,13 +305,6 @@ public class RoutingPoliciesTest { ); assertEquals(expectedRecords, tester.recordNames()); assertEquals(4, tester.policiesOf(context1.instanceId()).size()); - assertEquals(List.of(), - tester.controllerTester().controller().routing() - .readEndpointsOf(context1.deploymentIdIn(zone1)) - .scope(Endpoint.Scope.zone) - .legacy() - .asList(), - "No endpoints marked as legacy"); // Next deploy does nothing context1.submit(applicationPackage).deferLoadBalancerProvisioningIn(Environment.prod).deploy(); @@ -1121,27 +1107,16 @@ public class RoutingPoliciesTest { assertEquals(6, tester.policiesOf(context.instanceId()).size()); ClusterSpec.Id cluster0 = ClusterSpec.Id.from("c0"); ClusterSpec.Id cluster1 = ClusterSpec.Id.from("c1"); - // The expected number of endpoints are created for (var zone : List.of(zone1, zone2)) { - EndpointList zoneEndpoints = tester.controllerTester().controller().routing() - .readEndpointsOf(context.deploymentIdIn(zone)) - .scope(Endpoint.Scope.zone); - EndpointList generated = zoneEndpoints.generated(); + EndpointList generated = tester.controllerTester().controller().routing() + .readEndpointsOf(context.deploymentIdIn(zone)) + .scope(Endpoint.Scope.zone) + .generated(); assertEquals(1, generated.cluster(cluster0).size()); assertEquals(0, generated.cluster(cluster0).authMethod(AuthMethod.token).size()); assertEquals(2, generated.cluster(cluster1).size()); assertEquals(1, generated.cluster(cluster1).authMethod(AuthMethod.token).size()); - EndpointList legacy = zoneEndpoints.legacy(); - assertEquals(1, legacy.cluster(cluster0).size()); - assertEquals(0, legacy.cluster(cluster0).authMethod(AuthMethod.token).size()); - assertEquals(1, legacy.cluster(cluster1).size()); - assertEquals(0, legacy.cluster(cluster1).authMethod(AuthMethod.token).size()); } - EndpointList declaredEndpoints = tester.controllerTester().controller().routing().readDeclaredEndpointsOf(context.application()); - assertEquals(1, declaredEndpoints.scope(Endpoint.Scope.global).generated().size()); - assertEquals(1, declaredEndpoints.scope(Endpoint.Scope.global).legacy().size()); - assertEquals(1, declaredEndpoints.scope(Endpoint.Scope.application).generated().size()); - assertEquals(1, declaredEndpoints.scope(Endpoint.Scope.application).legacy().size()); Map<DeploymentId, Set<ContainerEndpoint>> containerEndpointsInProd = tester.containerEndpoints(Environment.prod); // Ordinary endpoints point to expected targets @@ -1580,7 +1555,7 @@ public class RoutingPoliciesTest { } else { global = global.not().generated(); } - String globalEndpoint = global.first() + String globalEndpoint = global.primary() .map(Endpoint::dnsName) .orElse("<none>"); assertEquals(latencyTargets, Set.copyOf(aliasDataOf(globalEndpoint)), "Global endpoint " + globalEndpoint + " points to expected latency targets"); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/rotation/RotationRepositoryTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/rotation/RotationRepositoryTest.java index e053e432862..6190680d098 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/rotation/RotationRepositoryTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/rotation/RotationRepositoryTest.java @@ -146,7 +146,7 @@ public class RotationRepositoryTest { application2.submit(applicationPackage).deploy(); assertEquals(List.of(new RotationId("foo-1")), rotationIds(application2.instance().rotations())); assertEquals("https://cd.app2.tenant2.global.cd.vespa.oath.cloud/", - tester.controller().routing().readDeclaredEndpointsOf(application2.instanceId()).first().get().url().toString()); + tester.controller().routing().readDeclaredEndpointsOf(application2.instanceId()).primary().get().url().toString()); } @Test |