diff options
author | Martin Polden <mpolden@mpolden.no> | 2022-09-15 15:19:44 +0200 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2022-09-15 15:32:41 +0200 |
commit | eeaec326ab3babc245bb561f497d541632e18986 (patch) | |
tree | b019014a9777b8bc0787a83f1af056de832ed1c9 /controller-server | |
parent | 754926e273acdb87bc43449ffb11f06a40a65ed3 (diff) |
Allow one routing method per zone
Diffstat (limited to 'controller-server')
5 files changed, 35 insertions, 44 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 790f54b5e8c..071d8a4d11f 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 @@ -110,10 +110,9 @@ public class RoutingController { // To discover the cluster name for a zone-scoped endpoint, we need to read routing policies for (var policy : routingPolicies.read(deployment)) { if (!policy.status().isActive()) continue; - for (var routingMethod : controller.zoneRegistry().routingMethods(policy.id().zone())) { - endpoints.addAll(policy.zoneEndpointsIn(controller.system(), routingMethod, controller.zoneRegistry())); - endpoints.add(policy.regionEndpointIn(controller.system(), routingMethod)); - } + RoutingMethod routingMethod = controller.zoneRegistry().routingMethod(policy.id().zone()); + endpoints.addAll(policy.zoneEndpointsIn(controller.system(), routingMethod, controller.zoneRegistry())); + endpoints.add(policy.regionEndpointIn(controller.system(), routingMethod)); } return EndpointList.copyOf(endpoints); } @@ -364,19 +363,18 @@ public class RoutingController { } private boolean usesSharedRouting(ZoneId zone) { - return controller.zoneRegistry().routingMethods(zone).stream().anyMatch(RoutingMethod::isShared); + return controller.zoneRegistry().routingMethod(zone).isShared(); } /** Returns the routing methods that are available across all given deployments */ private List<RoutingMethod> routingMethodsOfAll(Collection<DeploymentId> deployments) { - var deploymentsByMethod = new HashMap<RoutingMethod, Set<DeploymentId>>(); + Map<RoutingMethod, Set<DeploymentId>> deploymentsByMethod = new HashMap<>(); for (var deployment : deployments) { - for (var method : controller.zoneRegistry().routingMethods(deployment.zoneId())) { - deploymentsByMethod.computeIfAbsent(method, k -> new LinkedHashSet<>()) - .add(deployment); - } + RoutingMethod routingMethod = controller.zoneRegistry().routingMethod(deployment.zoneId()); + deploymentsByMethod.computeIfAbsent(routingMethod, k -> new LinkedHashSet<>()) + .add(deployment); } - var routingMethods = new ArrayList<RoutingMethod>(); + List<RoutingMethod> routingMethods = new ArrayList<>(); deploymentsByMethod.forEach((method, supportedDeployments) -> { if (supportedDeployments.containsAll(deployments)) { routingMethods.add(method); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgrader.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgrader.java index 8e74ef9a983..000acd16155 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgrader.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgrader.java @@ -3,7 +3,6 @@ package com.yahoo.vespa.hosted.controller.maintenance; import com.yahoo.component.Version; import com.yahoo.config.provision.zone.NodeSlice; -import com.yahoo.config.provision.zone.RoutingMethod; import com.yahoo.config.provision.zone.ZoneApi; import com.yahoo.text.Text; import com.yahoo.vespa.hosted.controller.Controller; @@ -78,8 +77,7 @@ public class SystemUpgrader extends InfrastructureUpgrader<VespaVersionTarget> { if (application.hasApplicationPackage()) { // For applications with package we do not have a zone-wide version target. This means that we must check // the wanted version of each node. - boolean zoneHasSharedRouting = controller().zoneRegistry().routingMethods(zone.getId()).stream() - .anyMatch(RoutingMethod::isShared); + boolean zoneHasSharedRouting = controller().zoneRegistry().routingMethod(zone.getId()).isShared(); return versionOf(NodeSlice.ALL, zone, application, Node::wantedVersion) .map(wantedVersion -> !wantedVersion.equals(target.version())) .orElse(zoneHasSharedRouting); // Always upgrade if zone uses shared routing, but has no nodes allocated yet diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicies.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicies.java index a5a09ab6551..ac29f8952a0 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicies.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicies.java @@ -7,7 +7,6 @@ import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.zone.RoutingMethod; import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.transaction.Mutex; -import com.yahoo.vespa.curator.Lock; import com.yahoo.vespa.hosted.controller.Application; import com.yahoo.vespa.hosted.controller.Controller; import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId; @@ -203,11 +202,10 @@ public class RoutingPolicies { /** Compute region endpoints and their targets from given policies */ private Collection<RegionEndpoint> computeRegionEndpoints(List<RoutingPolicy> policies, Set<ZoneId> inactiveZones) { Map<Endpoint, RegionEndpoint> endpoints = new LinkedHashMap<>(); - RoutingMethod routingMethod = RoutingMethod.exclusive; for (var policy : policies) { if (policy.dnsZone().isEmpty()) continue; - if (!controller.zoneRegistry().routingMethods(policy.id().zone()).contains(routingMethod)) continue; - Endpoint regionEndpoint = policy.regionEndpointIn(controller.system(), routingMethod); + if (controller.zoneRegistry().routingMethod(policy.id().zone()) != RoutingMethod.exclusive) continue; + Endpoint regionEndpoint = policy.regionEndpointIn(controller.system(), RoutingMethod.exclusive); var zonePolicy = db.readZoneRoutingPolicy(policy.id().zone()); long weight = 1; if (isConfiguredOut(zonePolicy, policy, inactiveZones)) { @@ -437,12 +435,12 @@ public class RoutingPolicies { } private static boolean isActive(LoadBalancer loadBalancer) { - switch (loadBalancer.state()) { - case reserved: // Count reserved as active as we want callers (application API) to see the endpoint as early - // as possible - case active: return true; - } - return false; + return switch (loadBalancer.state()) { + // Count reserved as active as we want callers (application API) to see the endpoint as early + // as possible + case reserved, active -> true; + default -> false; + }; } /** Represents records for a region-wide endpoint */ @@ -556,10 +554,10 @@ public class RoutingPolicies { /** Returns the name updater to use for given zone */ private NameServiceForwarder nameServiceForwarderIn(ZoneId zone) { - if (controller.zoneRegistry().routingMethods(zone).contains(RoutingMethod.exclusive)) { - return controller.nameServiceForwarder(); - } - return new NameServiceDiscarder(controller.curator()); + return switch (controller.zoneRegistry().routingMethod(zone)) { + case exclusive -> controller.nameServiceForwarder(); + case sharedLayer4 -> new NameServiceDiscarder(controller.curator()); + }; } /** A {@link NameServiceForwarder} that does nothing. Used in zones where no explicit DNS updates are needed */ diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ZoneFilterMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ZoneFilterMock.java index 5ec949dfe0c..b27c206e215 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ZoneFilterMock.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ZoneFilterMock.java @@ -25,18 +25,18 @@ import java.util.stream.Collectors; public class ZoneFilterMock implements ZoneList { private final List<ZoneApi> zones; - private final Map<ZoneApi, List<RoutingMethod>> zoneRoutingMethods; + private final Map<ZoneApi, RoutingMethod> zoneRoutingMethods; private final Set<ZoneApi> reprovisionToUpgradeOs; private final boolean negate; - private ZoneFilterMock(List<ZoneApi> zones, Map<ZoneApi, List<RoutingMethod>> zoneRoutingMethods, Set<ZoneApi> reprovisionToUpgradeOs, boolean negate) { + private ZoneFilterMock(List<ZoneApi> zones, Map<ZoneApi, RoutingMethod> zoneRoutingMethods, Set<ZoneApi> reprovisionToUpgradeOs, boolean negate) { this.zones = zones; this.zoneRoutingMethods = zoneRoutingMethods; this.reprovisionToUpgradeOs = reprovisionToUpgradeOs; this.negate = negate; } - public static ZoneFilter from(Collection<? extends ZoneApi> zones, Map<ZoneApi, List<RoutingMethod>> routingMethods, Set<ZoneApi> reprovisionToUpgradeOs) { + public static ZoneFilter from(Collection<? extends ZoneApi> zones, Map<ZoneApi, RoutingMethod> routingMethods, Set<ZoneApi> reprovisionToUpgradeOs) { return new ZoneFilterMock(List.copyOf(zones), Map.copyOf(routingMethods), reprovisionToUpgradeOs, false); } @@ -62,7 +62,7 @@ public class ZoneFilterMock implements ZoneList { @Override public ZoneList routingMethod(RoutingMethod method) { - return filter(zone -> zoneRoutingMethods.getOrDefault(zone, List.of()).contains(method)); + return filter(zone -> zoneRoutingMethods.get(zone) == method); } @Override diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ZoneRegistryMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ZoneRegistryMock.java index 0211a052f76..7f40172db2d 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ZoneRegistryMock.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ZoneRegistryMock.java @@ -32,6 +32,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -43,7 +44,7 @@ public class ZoneRegistryMock extends AbstractComponent implements ZoneRegistry private final Map<ZoneId, Duration> deploymentTimeToLive = new HashMap<>(); private final Map<Environment, RegionName> defaultRegionForEnvironment = new HashMap<>(); private final Map<CloudName, UpgradePolicy> osUpgradePolicies = new HashMap<>(); - private final Map<ZoneApi, List<RoutingMethod>> zoneRoutingMethods = new HashMap<>(); + private final Map<ZoneApi, RoutingMethod> zoneRoutingMethods = new HashMap<>(); private final Map<CloudAccount, Set<ZoneId>> cloudAccountZones = new HashMap<>(); private final Set<ZoneApi> reprovisionToUpgradeOs = new HashSet<>(); private final SystemName system; // Don't even think about making it non-final! ƪ(`▿▿▿▿´ƪ) @@ -125,17 +126,13 @@ public class ZoneRegistryMock extends AbstractComponent implements ZoneRegistry return setRoutingMethod(zones, RoutingMethod.exclusive); } - public ZoneRegistryMock setRoutingMethod(ZoneApi zone, RoutingMethod... routingMethods) { - return setRoutingMethod(zone, Set.of(routingMethods)); - } - - public ZoneRegistryMock setRoutingMethod(List<? extends ZoneApi> zones, RoutingMethod... routingMethods) { - zones.forEach(zone -> setRoutingMethod(zone, Set.of(routingMethods))); + public ZoneRegistryMock setRoutingMethod(List<? extends ZoneApi> zones, RoutingMethod routingMethod) { + zones.forEach(zone -> setRoutingMethod(zone, routingMethod)); return this; } - private ZoneRegistryMock setRoutingMethod(ZoneApi zone, Set<RoutingMethod> routingMethods) { - this.zoneRoutingMethods.put(zone, List.copyOf(routingMethods)); + public ZoneRegistryMock setRoutingMethod(ZoneApi zone, RoutingMethod routingMethod) { + this.zoneRoutingMethods.put(zone, routingMethod); return this; } @@ -214,8 +211,8 @@ public class ZoneRegistryMock extends AbstractComponent implements ZoneRegistry } @Override - public List<RoutingMethod> routingMethods(ZoneId zone) { - return List.copyOf(zoneRoutingMethods.getOrDefault(ZoneApiMock.from(zone), List.of())); + public RoutingMethod routingMethod(ZoneId zone) { + return Objects.requireNonNull(zoneRoutingMethods.get(ZoneApiMock.from(zone))); } @Override @@ -272,7 +269,7 @@ public class ZoneRegistryMock extends AbstractComponent implements ZoneRegistry @Override public Optional<String> getVipHostname(ZoneId zoneId) { - if (routingMethods(zoneId).stream().anyMatch(RoutingMethod::isShared)) { + if (routingMethod(zoneId).isShared()) { return Optional.of("vip." + zoneId.value()); } return Optional.empty(); |