summaryrefslogtreecommitdiffstats
path: root/controller-server
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2020-02-06 14:26:03 +0100
committerGitHub <noreply@github.com>2020-02-06 14:26:03 +0100
commitc8d82ecc566acbdaa8dea09e5ae551da177d3802 (patch)
tree76d54d587aa26ce0fc6b01e06c9198cd0d3b5344 /controller-server
parent62ce2c446fbfad39da4c7f11212012d1ab41990e (diff)
parent8437d7892f4f1a074df670dd8e8ee09cfc0b70a1 (diff)
Merge pull request #12089 from vespa-engine/mpolden/include-global-endpoint
Include all endpoints in endpoints field
Diffstat (limited to 'controller-server')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/RoutingController.java38
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java61
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-with-routing-policy.json15
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment.json15
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/dev-us-east-1.json9
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/prod-us-central-1.json15
6 files changed, 129 insertions, 24 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 51c9f51f9b9..c06194fcd73 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,20 +1028,58 @@ 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;
- Cursor endpointObject = endpointArray.addObject();
- Endpoint endpoint = policy.endpointIn(controller.system());
- endpointObject.setString("cluster", policy.id().cluster().value());
- endpointObject.setBool("tls", endpoint.tls());
- endpointObject.setString("url", endpoint.url().toString());
+ {
+ var endpointObject = endpointArray.addObject();
+ var endpoint = policy.endpointIn(controller.system());
+ endpointObject.setString("cluster", policy.id().cluster().value());
+ endpointObject.setBool("tls", endpoint.tls());
+ endpointObject.setString("url", endpoint.url().toString());
+ endpointObject.setString("scope", endpointScopeString(endpoint.scope()));
+ }
+ // 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());
+ endpointObject.setBool("tls", endpoint.tls());
+ endpointObject.setString("url", endpoint.url().toString());
+ 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()));
@@ -1053,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);
@@ -2070,6 +2107,14 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
return "UNKNOWN";
}
+ private static String endpointScopeString(Endpoint.Scope scope) {
+ switch (scope) {
+ case global: return "global";
+ case zone: return "zone";
+ }
+ throw new IllegalArgumentException("Unknown endpoint scope " + scope);
+ }
+
private static <T> T getAttribute(HttpRequest request, String attributeName, Class<T> cls) {
return Optional.ofNullable(request.getJDiscRequest().context().get(attributeName))
.filter(cls::isInstance)
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 22ba83a4730..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
@@ -8,7 +8,20 @@
{
"cluster": "default",
"tls": true,
- "url": "https://instance1.application1.tenant1.us-west-1.vespa.oath.cloud/"
+ "url": "https://instance1.application1.tenant1.us-west-1.vespa.oath.cloud/",
+ "scope": "zone"
+ },
+ {
+ "cluster": "default",
+ "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"
],