diff options
author | Martin Polden <mpolden@mpolden.no> | 2020-02-06 12:45:14 +0100 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2020-02-06 13:18:15 +0100 |
commit | 8437d7892f4f1a074df670dd8e8ee09cfc0b70a1 (patch) | |
tree | 9c2721e1d538e9539deb3c95d28282f262e74ccc /controller-server | |
parent | ce7d49ae1f19bf541556e2f0c097428c44168c93 (diff) |
Include shared routing layer endpoints in endpoints field
Diffstat (limited to 'controller-server')
6 files changed, 98 insertions, 19 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 29d6de858dc..74304f2e49d 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 @@ -71,7 +71,7 @@ public class RoutingController { return rotationRepository; } - /** Returns all known endpoint URLs for given deployment, including global, in the shared routing layer */ + /** Returns all legacy endpoint URLs for given deployment, including global, in the shared routing layer */ public List<URI> legacyEndpointsOf(DeploymentId deployment) { return routingEndpointsOf(deployment).stream() .map(RoutingEndpoint::endpoint) @@ -79,28 +79,38 @@ public class RoutingController { .collect(Collectors.toUnmodifiableList()); } - /** Returns all non-global endpoint URLs for given deployment, grouped by their cluster ID */ + /** Returns legacy zone endpoints for given deployment, in the shared routing layer */ + public Map<ClusterSpec.Id, URI> legacyZoneEndpointsOf(DeploymentId deployment) { + if (!supportsRoutingMethod(RoutingMethod.shared, deployment.zoneId())) { + return Map.of(); + } + try { + return routingGenerator.clusterEndpoints(deployment); + } catch (RuntimeException e) { + log.log(Level.WARNING, "Failed to get endpoint information for " + deployment, e); + return Map.of(); + } + } + + /** + * Returns all non-global endpoint URLs for given deployment, grouped by their cluster ID. If deployment supports + * {@link RoutingMethod#exclusive} endpoints defined through routing polices are returned. + */ public Map<ClusterSpec.Id, URI> zoneEndpointsOf(DeploymentId deployment) { if ( ! controller.applications().getInstance(deployment.applicationId()) .map(application -> application.deployments().containsKey(deployment.zoneId())) .orElse(deployment.applicationId().instance().isTester())) throw new NotExistsException("Deployment", deployment.toString()); - // In directly routed zones we create endpoint URLs from routing policies - if (controller.zoneRegistry().zones().directlyRouted().ids().contains(deployment.zoneId())) { + // In exclusively routed zones we create endpoint URLs from routing policies + if (supportsRoutingMethod(RoutingMethod.exclusive, deployment.zoneId())) { return routingPolicies.get(deployment).values().stream() .filter(policy -> policy.endpointIn(controller.system()).scope() == Endpoint.Scope.zone) .collect(Collectors.toUnmodifiableMap(policy -> policy.id().cluster(), policy -> policy.endpointIn(controller.system()) .url())); } - // In other zones we fetch endpoints from the shared routing layer - try { - return routingGenerator.clusterEndpoints(deployment); - } catch (RuntimeException e) { - log.log(Level.WARNING, "Failed to get endpoint information for " + deployment, e); - return Map.of(); - } + return legacyZoneEndpointsOf(deployment); } /** Returns all non-global endpoint URLs for given deployments, grouped by their cluster ID and zone */ @@ -216,7 +226,7 @@ public class RoutingController { } private List<RoutingEndpoint> routingEndpointsOf(DeploymentId deployment) { - if (!controller.zoneRegistry().zones().routingMethod(RoutingMethod.shared).ids().contains(deployment.zoneId())) { + if (!supportsRoutingMethod(RoutingMethod.shared, deployment.zoneId())) { return List.of(); // No rotations/shared routing layer in this zone. } try { @@ -227,4 +237,8 @@ public class RoutingController { } } + private boolean supportsRoutingMethod(RoutingMethod routingMethod, ZoneId zone) { + return controller.zoneRegistry().zones().routingMethod(routingMethod).ids().contains(zone); + } + } 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 316e29bd247..131c91679b4 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 @@ -848,6 +848,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler { .forEach(globalEndpointUrls::add); } + // TODO(mpolden): Remove once clients stop expecting this field var globalRotationsArray = object.setArray("globalRotations"); globalEndpointUrls.forEach(globalRotationsArray::addString); @@ -1027,7 +1028,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler { response.setString("environment", deploymentId.zoneId().environment().value()); response.setString("region", deploymentId.zoneId().region().value()); - // Add endpoint(s) defined by routing policies + // Add zone endpoints defined by routing policies var endpointArray = response.setArray("endpoints"); for (var policy : controller.routingController().policies().get(deploymentId).values()) { if (!policy.status().isActive()) continue; @@ -1039,7 +1040,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler { endpointObject.setString("url", endpoint.url().toString()); endpointObject.setString("scope", endpointScopeString(endpoint.scope())); } - // Add all global endpoints that point to this policy + // Add global endpoints that point to this policy for (var endpoint : policy.globalEndpointsIn(controller.system()).asList()) { var endpointObject = endpointArray.addObject(); endpointObject.setString("cluster", policy.id().cluster().value()); @@ -1048,10 +1049,37 @@ public class ApplicationApiHandler extends LoggingRequestHandler { endpointObject.setString("scope", endpointScopeString(endpoint.scope())); } } + // Add zone endpoints served by shared routing layer + for (var clusterAndUrl : controller.routingController().legacyZoneEndpointsOf(deploymentId).entrySet()) { + var endpointObject = endpointArray.addObject(); + endpointObject.setString("cluster", clusterAndUrl.getKey().value()); + endpointObject.setBool("tls", true); + endpointObject.setString("url", clusterAndUrl.getValue().toString()); + endpointObject.setString("scope", endpointScopeString(Endpoint.Scope.zone)); + } + // Add global endpoints served by shared routing layer + var application = controller.applications().requireApplication(TenantAndApplicationId.from(deploymentId.applicationId())); + var instance = application.instances().get(deploymentId.applicationId().instance()); + if (deploymentId.zoneId().environment().isProduction()) { // Global endpoints can only point to production deployments + for (var rotation : instance.rotations()) { + var endpoints = instance.endpointsIn(controller.system(), rotation.endpointId()) + .legacy(false) + .scope(Endpoint.Scope.global) + .asList(); + for (var endpoint : endpoints) { + var endpointObject = endpointArray.addObject(); + endpointObject.setString("cluster", rotation.clusterId().value()); + endpointObject.setBool("tls", true); + endpointObject.setString("url", endpoint.url().toString()); + endpointObject.setString("scope", endpointScopeString(endpoint.scope())); + } + } + } // serviceUrls contains all valid endpoints for this deployment, including global. The name of these endpoints // may contain the cluster name (if non-default). Since the controller has no knowledge of clusters for legacy // endpoints, we can't generate these URLs on-the-fly and we have to query the routing layer. + // TODO(mpolden): Remove this once all clients stop reading this. Cursor serviceUrlArray = response.setArray("serviceUrls"); controller.routingController().legacyEndpointsOf(deploymentId) .forEach(endpoint -> serviceUrlArray.addString(endpoint.toString())); @@ -1064,12 +1092,10 @@ public class ApplicationApiHandler extends LoggingRequestHandler { controller.zoneRegistry().getDeploymentTimeToLive(deploymentId.zoneId()) .ifPresent(deploymentTimeToLive -> response.setLong("expiryTimeEpochMs", deployment.at().plus(deploymentTimeToLive).toEpochMilli())); - Application application = controller.applications().requireApplication(TenantAndApplicationId.from(deploymentId.applicationId())); DeploymentStatus status = controller.jobController().deploymentStatus(application); application.projectId().ifPresent(i -> response.setString("screwdriverId", String.valueOf(i))); sourceRevisionToSlime(deployment.applicationVersion().source(), response); - Instance instance = application.instances().get(deploymentId.applicationId().instance()); if (instance != null) { if (!instance.rotations().isEmpty() && deployment.zone().environment() == Environment.prod) toSlime(instance.rotations(), instance.rotationStatus(), deployment, response); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-with-routing-policy.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-with-routing-policy.json index a70f23d26f5..10201af0272 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-with-routing-policy.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-with-routing-policy.json @@ -16,6 +16,12 @@ "tls": true, "url": "https://c0.instance1.application1.tenant1.global.vespa.oath.cloud/", "scope": "global" + }, + { + "cluster": "default", + "tls": true, + "url": "https://instance1--application1--tenant1.us-west-1.prod.vespa:43", + "scope": "zone" } ], "serviceUrls": [ diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment.json index f9692a4afb7..d96b291234d 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment.json @@ -4,7 +4,20 @@ "instance": "instance1", "environment": "prod", "region": "us-central-1", - "endpoints": [], + "endpoints": [ + { + "cluster": "default", + "tls": true, + "url": "https://instance1--application1--tenant1.us-central-1.prod.vespa:43", + "scope": "zone" + }, + { + "cluster": "foo", + "tls": true, + "url": "https://instance1--application1--tenant1.global.vespa.oath.cloud:4443/", + "scope": "global" + } + ], "serviceUrls": [ "https://instance1--application1--tenant1.us-central-1.prod.vespa:43" ], diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/dev-us-east-1.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/dev-us-east-1.json index 204927f6954..3ff8533fdb3 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/dev-us-east-1.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/dev-us-east-1.json @@ -4,7 +4,14 @@ "instance": "instance1", "environment": "dev", "region": "us-east-1", - "endpoints": [], + "endpoints": [ + { + "cluster": "default", + "tls": true, + "url": "https://instance1--application1--tenant1.us-east-1.dev.vespa:43", + "scope": "zone" + } + ], "serviceUrls": [ "https://instance1--application1--tenant1.us-east-1.dev.vespa:43" ], diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/prod-us-central-1.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/prod-us-central-1.json index 39824e22928..bff8326fdeb 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/prod-us-central-1.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/prod-us-central-1.json @@ -7,7 +7,20 @@ "instance": "instance1", "environment": "prod", "region": "us-central-1", - "endpoints": [], + "endpoints": [ + { + "cluster": "default", + "tls": true, + "url": "https://instance1--application1--tenant1.us-central-1.prod.vespa:43", + "scope": "zone" + }, + { + "cluster": "foo", + "tls": true, + "url": "https://instance1--application1--tenant1.global.vespa.oath.cloud:4443/", + "scope": "global" + } + ], "serviceUrls": [ "https://instance1--application1--tenant1.us-central-1.prod.vespa:43" ], |