summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorØyvind Grønnesby <oyving@verizonmedia.com>2021-09-13 11:45:03 +0200
committerØyvind Grønnesby <oyving@verizonmedia.com>2021-09-13 14:52:17 +0200
commitcc0852cec883e2512969befe88aeed2872b5de45 (patch)
treeb22365bd04c178debda3121fe191c0f9df53abe5
parenta8c616b18803e2e3a959b9ba987deb64fabf252a (diff)
Try to generalise from the toSlime() method
There are multiple types of endpoints and routing methods. Here we try to use the same logic as the toSlime() method to generate the status JSON from the instance/endpoint POV. Not sure if the JSON format makes sense or if are in a position where we can get multiple contradictory statuses per endpoint+zone.
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/routing/RoutingApiHandler.java93
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/routing/responses/endpoint/endpoints.json16
2 files changed, 66 insertions, 43 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/routing/RoutingApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/routing/RoutingApiHandler.java
index 2d7e4f3f29e..e01f2cc13c4 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/routing/RoutingApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/routing/RoutingApiHandler.java
@@ -32,8 +32,10 @@ import java.time.Instant;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
import java.util.logging.Level;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* This implements the /routing/v1 API, which provides operator with global routing control at both zone- and
@@ -95,12 +97,20 @@ public class RoutingApiHandler extends AuditLoggingRequestHandler {
private HttpResponse endpoints(Path path) {
var instanceId = instanceFrom(path);
var endpoints = controller.routing().endpointsOf(instanceId);
- var zoneStatus = endpoints.asList().stream()
+
+ var deployments = endpoints.asList().stream()
.flatMap(e -> e.zones().stream())
.distinct()
+ .map(zoneId -> new DeploymentId(instanceId, zoneId))
+ .collect(Collectors.toList());
+
+ var deploymentsStatus = deployments.stream()
.collect(Collectors.toMap(
- zone -> zone,
- zone -> controller.routing().globalRotationStatus(new DeploymentId(instanceId, zone))
+ deploymentId -> deploymentId,
+ deploymentId -> Stream.concat(
+ directGlobalRoutingStatus(deploymentId).stream(),
+ sharedGlobalRoutingStatus(deploymentId).stream()
+ ).collect(Collectors.toList())
));
var slime = new Slime();
@@ -110,8 +120,11 @@ public class RoutingApiHandler extends AuditLoggingRequestHandler {
var endpointRoot = endpointsRoot.addObject();
endpointToSlime(endpointRoot, endpoint);
var zonesRoot = endpointRoot.setArray("zones");
- zoneStatus.forEach((zone, status) -> {
- endpointStatusToSlime(zonesRoot.addObject(), zone, status.get(endpoint));
+ endpoint.zones().forEach(zoneId -> {
+ var deploymentId = new DeploymentId(instanceId, zoneId);
+ deploymentsStatus.getOrDefault(deploymentId, List.of()).forEach(status -> {
+ deploymentStatusToSlime(zonesRoot.addObject(), deploymentId, status, endpoint.routingMethod());
+ });
});
});
@@ -269,42 +282,50 @@ public class RoutingApiHandler extends AuditLoggingRequestHandler {
for (var zone : zones) {
var deploymentId = requireDeployment(new DeploymentId(instance.id(), zone), instance);
// Include status from rotation
- if (rotationCanRouteTo(zone)) {
- var rotationStatus = controller.routing().globalRotationStatus(deploymentId);
- // Status is equal across all global endpoints, as the status is per deployment, not per endpoint.
- var endpointStatus = rotationStatus.values().stream().findFirst();
- if (endpointStatus.isPresent()) {
- var changedAt = Instant.ofEpochSecond(endpointStatus.get().getEpoch());
- GlobalRouting.Agent agent;
- try {
- agent = GlobalRouting.Agent.valueOf(endpointStatus.get().getAgent());
- } catch (IllegalArgumentException e) {
- agent = GlobalRouting.Agent.unknown;
- }
- var status = endpointStatus.get().getStatus() == EndpointStatus.Status.in
- ? GlobalRouting.Status.in
- : GlobalRouting.Status.out;
- deploymentStatusToSlime(deploymentsArray.addObject(), deploymentId,
- new GlobalRouting(status, agent, changedAt),
- RoutingMethod.shared);
- }
- }
+ sharedGlobalRoutingStatus(deploymentId).ifPresent(status -> {
+ deploymentStatusToSlime(deploymentsArray.addObject(), deploymentId, status, RoutingMethod.shared);
+ });
// Include status from routing policies
- var routingPolicies = controller.routing().policies().get(deploymentId);
- for (var policy : routingPolicies.values()) {
- if (policy.endpoints().isEmpty()) continue; // This policy does not apply to a global endpoint
- if (!controller.zoneRegistry().routingMethods(policy.id().zone()).contains(RoutingMethod.exclusive)) continue;
- deploymentStatusToSlime(deploymentsArray.addObject(), new DeploymentId(policy.id().owner(),
- policy.id().zone()),
- policy.status().globalRouting(), RoutingMethod.exclusive);
- }
+ directGlobalRoutingStatus(deploymentId).forEach(status -> {
+ deploymentStatusToSlime(deploymentsArray.addObject(), deploymentId, status, RoutingMethod.exclusive);
+ });
}
}
}
}
+ private Optional<GlobalRouting> sharedGlobalRoutingStatus(DeploymentId deploymentId) {
+ if (rotationCanRouteTo(deploymentId.zoneId())) {
+ var rotationStatus = controller.routing().globalRotationStatus(deploymentId);
+ // Status is equal across all global endpoints, as the status is per deployment, not per endpoint.
+ var endpointStatus = rotationStatus.values().stream().findFirst();
+ if (endpointStatus.isPresent()) {
+ var changedAt = Instant.ofEpochSecond(endpointStatus.get().getEpoch());
+ GlobalRouting.Agent agent;
+ try {
+ agent = GlobalRouting.Agent.valueOf(endpointStatus.get().getAgent());
+ } catch (IllegalArgumentException e) {
+ agent = GlobalRouting.Agent.unknown;
+ }
+ var status = endpointStatus.get().getStatus() == EndpointStatus.Status.in
+ ? GlobalRouting.Status.in
+ : GlobalRouting.Status.out;
+ return Optional.of(new GlobalRouting(status, agent, changedAt));
+ }
+ }
+ return Optional.empty();
+ }
+
+ private List<GlobalRouting> directGlobalRoutingStatus(DeploymentId deploymentId) {
+ return controller.routing().policies().get(deploymentId).values().stream()
+ .filter(p -> ! p.endpoints().isEmpty()) // This policy does not apply to a global endpoint
+ .filter(p -> controller.zoneRegistry().routingMethods(p.id().zone()).contains(RoutingMethod.exclusive))
+ .map(p -> p.status().globalRouting())
+ .collect(Collectors.toList());
+ }
+
/** Returns whether a rotation can route traffic to given zone */
private boolean rotationCanRouteTo(ZoneId zone) {
// A system may support multiple routing methods, i.e. it has both exclusively routed zones and zones using
@@ -340,12 +361,6 @@ public class RoutingApiHandler extends AuditLoggingRequestHandler {
object.setString("scope", endpoint.scope().name());
}
- private static void endpointStatusToSlime(Cursor object, ZoneId zone, EndpointStatus status) {
- object.setString("zone", zone.value());
- object.setString("status", status.getStatus().name());
- object.setString("reason", status.getReason());
- }
-
private TenantName tenantFrom(Path path) {
return TenantName.from(path.get("tenant"));
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/routing/responses/endpoint/endpoints.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/routing/responses/endpoint/endpoints.json
index a3a5e3d8236..695e53f5611 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/routing/responses/endpoint/endpoints.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/routing/responses/endpoint/endpoints.json
@@ -8,14 +8,22 @@
"scope": "global",
"zones": [
{
- "zone": "prod.us-east-3",
+ "routingMethod": "shared",
+ "instance": "t1:a1:default",
+ "environment": "prod",
+ "region": "us-east-3",
"status": "in",
- "reason": ""
+ "agent": "unknown",
+ "changedAt": 1497618757000
},
{
- "zone": "prod.us-west-1",
+ "routingMethod": "shared",
+ "instance": "t1:a1:default",
+ "environment": "prod",
+ "region": "us-west-1",
"status": "in",
- "reason": ""
+ "agent": "unknown",
+ "changedAt": 1497618757000
}
]
}