mirror of https://github.com/grpc/grpc-java.git
xds: wire up re-resolution requests from LB policies for DNS clusters and bypass requests from LB policies for EDS clusters (#7769)
This change wires up the refreshNameResolution() API for triggering DNS re-resolution in ClusterResolverLoadBalancer, which provides a way for downstream LB policies to request a resolution refresh and only re-resolution requests from LB policies for the DNS cluster should trigger the DNS refresh.
This commit is contained in:
parent
2755afeaa5
commit
18772e2470
|
|
@ -38,6 +38,7 @@ import io.grpc.internal.BackoffPolicy;
|
|||
import io.grpc.internal.ExponentialBackoffPolicy;
|
||||
import io.grpc.internal.ObjectPool;
|
||||
import io.grpc.internal.ServiceConfigUtil.PolicySelection;
|
||||
import io.grpc.util.ForwardingLoadBalancerHelper;
|
||||
import io.grpc.util.GracefulSwitchLoadBalancer;
|
||||
import io.grpc.xds.ClusterImplLoadBalancerProvider.ClusterImplConfig;
|
||||
import io.grpc.xds.ClusterResolverLoadBalancerProvider.ClusterResolverConfig;
|
||||
|
|
@ -49,6 +50,7 @@ import io.grpc.xds.EnvoyProtoData.LocalityLbEndpoints;
|
|||
import io.grpc.xds.EnvoyServerProtoData.UpstreamTlsContext;
|
||||
import io.grpc.xds.LrsLoadBalancerProvider.LrsConfig;
|
||||
import io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig;
|
||||
import io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig.PriorityChildConfig;
|
||||
import io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedPolicySelection;
|
||||
import io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedTargetConfig;
|
||||
import io.grpc.xds.XdsClient.EdsResourceWatcher;
|
||||
|
|
@ -166,7 +168,7 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
|
|||
private LoadBalancer childLb;
|
||||
|
||||
ClusterResolverLbState(Helper helper) {
|
||||
this.helper = checkNotNull(helper, "helper");
|
||||
this.helper = new RefreshableHelper(checkNotNull(helper, "helper"));
|
||||
logger.log(XdsLogLevel.DEBUG, "New ClusterResolverLbState");
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +216,7 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
|
|||
|
||||
private void handleEndpointResourceUpdate() {
|
||||
List<EquivalentAddressGroup> addresses = new ArrayList<>();
|
||||
Map<String, PolicySelection> priorityLbPolicies = new HashMap<>();
|
||||
Map<String, PriorityChildConfig> priorityChildConfigs = new HashMap<>();
|
||||
List<String> priorities = new ArrayList<>(); // totally ordered priority list
|
||||
boolean allResolved = true;
|
||||
for (String cluster : clusters) {
|
||||
|
|
@ -225,7 +227,7 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
|
|||
}
|
||||
if (state.result != null) {
|
||||
addresses.addAll(state.result.addresses);
|
||||
priorityLbPolicies.putAll(state.result.priorityLbPolicies);
|
||||
priorityChildConfigs.putAll(state.result.priorityChildConfigs);
|
||||
priorities.addAll(state.result.priorities);
|
||||
}
|
||||
}
|
||||
|
|
@ -243,7 +245,7 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
|
|||
return;
|
||||
}
|
||||
PriorityLbConfig childConfig =
|
||||
new PriorityLbConfig(Collections.unmodifiableMap(priorityLbPolicies),
|
||||
new PriorityLbConfig(Collections.unmodifiableMap(priorityChildConfigs),
|
||||
Collections.unmodifiableList(priorities));
|
||||
if (childLb == null) {
|
||||
childLb = lbRegistry.getProvider(PRIORITY_POLICY_NAME).newLoadBalancer(helper);
|
||||
|
|
@ -273,6 +275,31 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wires re-resolution requests from downstream LB policies with DNS resolver.
|
||||
*/
|
||||
private final class RefreshableHelper extends ForwardingLoadBalancerHelper {
|
||||
private final Helper delegate;
|
||||
|
||||
private RefreshableHelper(Helper delegate) {
|
||||
this.delegate = checkNotNull(delegate, "delegate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshNameResolution() {
|
||||
for (ClusterState state : clusterStates.values()) {
|
||||
if (state instanceof LogicalDnsClusterState) {
|
||||
((LogicalDnsClusterState) state).refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Helper delegate() {
|
||||
return delegate;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolution state of an underlying cluster.
|
||||
*/
|
||||
|
|
@ -390,13 +417,13 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
|
|||
}
|
||||
List<String> priorities = new ArrayList<>(prioritizedLocalityWeights.keySet());
|
||||
Collections.sort(priorities);
|
||||
Map<String, PolicySelection> priorityLbPolicies =
|
||||
generateClusterPriorityLbPolicies(name, edsServiceName, lrsServerName,
|
||||
maxConcurrentRequests, tlsContext, localityPickingPolicy,
|
||||
endpointPickingPolicy, lbRegistry, prioritizedLocalityWeights, dropOverloads);
|
||||
Map<String, PriorityChildConfig> priorityChildConfigs = generatePriorityChildConfigs(
|
||||
name, edsServiceName, lrsServerName, maxConcurrentRequests, tlsContext,
|
||||
localityPickingPolicy, endpointPickingPolicy, true, lbRegistry,
|
||||
prioritizedLocalityWeights, dropOverloads);
|
||||
status = Status.OK;
|
||||
resolved = true;
|
||||
result = new ClusterResolutionResult(addresses, priorityLbPolicies, priorities);
|
||||
result = new ClusterResolutionResult(addresses, priorityChildConfigs, priorities);
|
||||
handleEndpointResourceUpdate();
|
||||
}
|
||||
}
|
||||
|
|
@ -463,12 +490,23 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
|
|||
resolver.start(new NameResolverListener());
|
||||
}
|
||||
|
||||
void refresh() {
|
||||
cancelBackoff();
|
||||
resolver.refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
void shutdown() {
|
||||
super.shutdown();
|
||||
resolver.shutdown();
|
||||
cancelBackoff();
|
||||
}
|
||||
|
||||
private void cancelBackoff() {
|
||||
if (scheduledRefresh != null) {
|
||||
scheduledRefresh.cancel();
|
||||
scheduledRefresh = null;
|
||||
backoffPolicy = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -505,13 +543,13 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
|
|||
lbRegistry.getProvider("pick_first");
|
||||
PolicySelection endpointPickingPolicy =
|
||||
new PolicySelection(endpointPickingLbProvider, null);
|
||||
PolicySelection priorityLbPolicy =
|
||||
generateClusterPriorityLbPolicy(name, edsServiceName, lrsServerName,
|
||||
maxConcurrentRequests, tlsContext, endpointPickingPolicy, lbRegistry,
|
||||
LOGICAL_DNS_CLUSTER_LOCALITY, Collections.<DropOverload>emptyList());
|
||||
PriorityChildConfig priorityChildConfig = generatePriorityChildConfig(
|
||||
name, edsServiceName, lrsServerName, maxConcurrentRequests, tlsContext,
|
||||
endpointPickingPolicy, false, lbRegistry, LOGICAL_DNS_CLUSTER_LOCALITY,
|
||||
Collections.<DropOverload>emptyList());
|
||||
status = Status.OK;
|
||||
resolved = true;
|
||||
result = new ClusterResolutionResult(addresses, priorityName, priorityLbPolicy);
|
||||
result = new ClusterResolutionResult(addresses, priorityName, priorityChildConfig);
|
||||
handleEndpointResourceUpdate();
|
||||
}
|
||||
}
|
||||
|
|
@ -555,35 +593,35 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
|
|||
private static class ClusterResolutionResult {
|
||||
// Endpoint addresses.
|
||||
private final List<EquivalentAddressGroup> addresses;
|
||||
// Load balancing policy (with config) for each priority in the cluster.
|
||||
private final Map<String, PolicySelection> priorityLbPolicies;
|
||||
// Config (include load balancing policy/config) for each priority in the cluster.
|
||||
private final Map<String, PriorityChildConfig> priorityChildConfigs;
|
||||
// List of priority names ordered in descending priorities.
|
||||
private final List<String> priorities;
|
||||
|
||||
ClusterResolutionResult(List<EquivalentAddressGroup> addresses, String priority,
|
||||
PolicySelection priorityLbPolicy) {
|
||||
this(addresses, Collections.singletonMap(priority, priorityLbPolicy),
|
||||
PriorityChildConfig config) {
|
||||
this(addresses, Collections.singletonMap(priority, config),
|
||||
Collections.singletonList(priority));
|
||||
}
|
||||
|
||||
ClusterResolutionResult(List<EquivalentAddressGroup> addresses,
|
||||
Map<String, PolicySelection> priorityLbPolicies, List<String> priorities) {
|
||||
Map<String, PriorityChildConfig> configs, List<String> priorities) {
|
||||
this.addresses = addresses;
|
||||
this.priorityLbPolicies = priorityLbPolicies;
|
||||
this.priorityChildConfigs = configs;
|
||||
this.priorities = priorities;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the intra-priority LB policy for a single priority with the single given locality.
|
||||
* Generates the config to be used in the priority LB policy for a single priority.
|
||||
*
|
||||
* <p>priority LB -> cluster_impl LB -> (lrs LB) -> pick_first
|
||||
*/
|
||||
private PolicySelection generateClusterPriorityLbPolicy(
|
||||
private static PriorityChildConfig generatePriorityChildConfig(
|
||||
String cluster, @Nullable String edsServiceName, @Nullable String lrsServerName,
|
||||
@Nullable Long maxConcurrentRequests, @Nullable UpstreamTlsContext tlsContext,
|
||||
PolicySelection endpointPickingPolicy, LoadBalancerRegistry lbRegistry,
|
||||
Locality locality, List<DropOverload> dropOverloads) {
|
||||
PolicySelection endpointPickingPolicy, boolean ignoreReresolution,
|
||||
LoadBalancerRegistry lbRegistry, Locality locality, List<DropOverload> dropOverloads) {
|
||||
PolicySelection localityLbPolicy =
|
||||
generateLocalityLbConfig(locality, cluster, edsServiceName, lrsServerName,
|
||||
endpointPickingPolicy, lbRegistry);
|
||||
|
|
@ -592,23 +630,25 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
|
|||
dropOverloads, localityLbPolicy, tlsContext);
|
||||
LoadBalancerProvider clusterImplLbProvider =
|
||||
lbRegistry.getProvider(XdsLbPolicies.CLUSTER_IMPL_POLICY_NAME);
|
||||
return new PolicySelection(clusterImplLbProvider, clusterImplConfig);
|
||||
PolicySelection clusterImplPolicy =
|
||||
new PolicySelection(clusterImplLbProvider, clusterImplConfig);
|
||||
return new PriorityChildConfig(clusterImplPolicy, ignoreReresolution);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates intra-priority LB policies (with config) for priorities in the cluster.
|
||||
* Generates configs to be used in the priority LB policy for priorities in the cluster.
|
||||
*
|
||||
* <p>priority LB -> cluster_impl LB (one per priority) -> weighted_target LB
|
||||
* -> (lrs LB (one per locality)) -> round_robin
|
||||
*/
|
||||
private static Map<String, PolicySelection> generateClusterPriorityLbPolicies(
|
||||
private static Map<String, PriorityChildConfig> generatePriorityChildConfigs(
|
||||
String cluster, @Nullable String edsServiceName, @Nullable String lrsServerName,
|
||||
@Nullable Long maxConcurrentRequests, @Nullable UpstreamTlsContext tlsContext,
|
||||
PolicySelection localityPickingPolicy, PolicySelection endpointPickingPolicy,
|
||||
LoadBalancerRegistry lbRegistry,
|
||||
boolean ignoreReresolution, LoadBalancerRegistry lbRegistry,
|
||||
Map<String, Map<Locality, Integer>> prioritizedLocalityWeights,
|
||||
List<DropOverload> dropOverloads) {
|
||||
Map<String, PolicySelection> policies = new HashMap<>();
|
||||
Map<String, PriorityChildConfig> configs = new HashMap<>();
|
||||
for (String priority : prioritizedLocalityWeights.keySet()) {
|
||||
WeightedTargetConfig localityPickingLbConfig =
|
||||
generateLocalityPickingLbConfig(cluster, edsServiceName, lrsServerName,
|
||||
|
|
@ -622,9 +662,9 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
|
|||
lbRegistry.getProvider(XdsLbPolicies.CLUSTER_IMPL_POLICY_NAME);
|
||||
PolicySelection clusterImplPolicy =
|
||||
new PolicySelection(clusterImplLbProvider, clusterImplConfig);
|
||||
policies.put(priority, clusterImplPolicy);
|
||||
configs.put(priority, new PriorityChildConfig(clusterImplPolicy, ignoreReresolution));
|
||||
}
|
||||
return policies;
|
||||
return configs;
|
||||
}
|
||||
|
||||
private static WeightedTargetConfig generateLocalityPickingLbConfig(
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import io.grpc.xds.EnvoyProtoData.Locality;
|
|||
import io.grpc.xds.EnvoyProtoData.LocalityLbEndpoints;
|
||||
import io.grpc.xds.LrsLoadBalancerProvider.LrsConfig;
|
||||
import io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig;
|
||||
import io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig.PriorityChildConfig;
|
||||
import io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedPolicySelection;
|
||||
import io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedTargetConfig;
|
||||
import io.grpc.xds.XdsClient.EdsResourceWatcher;
|
||||
|
|
@ -293,8 +294,8 @@ final class EdsLoadBalancer2 extends LoadBalancer {
|
|||
private void handleResourceUpdate() {
|
||||
// Populate configurations used by downstream LB policies from the freshest result.
|
||||
EdsConfig config = (EdsConfig) resolvedAddresses.getLoadBalancingPolicyConfig();
|
||||
// Load balancing policy for each priority.
|
||||
Map<String, PolicySelection> priorityChildPolicies = new HashMap<>();
|
||||
// Config for each priority.
|
||||
Map<String, PriorityChildConfig> priorityChildConfigs = new HashMap<>();
|
||||
List<String> priorities = new ArrayList<>();
|
||||
for (Integer priority : prioritizedLocalityWeights.keySet()) {
|
||||
WeightedTargetConfig weightedTargetConfig =
|
||||
|
|
@ -312,12 +313,12 @@ final class EdsLoadBalancer2 extends LoadBalancer {
|
|||
PolicySelection clusterImplPolicy =
|
||||
new PolicySelection(clusterImplLbProvider, clusterImplConfig);
|
||||
String priorityName = priorityName(priority);
|
||||
priorityChildPolicies.put(priorityName, clusterImplPolicy);
|
||||
priorityChildConfigs.put(priorityName, new PriorityChildConfig(clusterImplPolicy, true));
|
||||
priorities.add(priorityName);
|
||||
}
|
||||
Collections.sort(priorities);
|
||||
PriorityLbConfig priorityLbConfig =
|
||||
new PriorityLbConfig(Collections.unmodifiableMap(priorityChildPolicies),
|
||||
new PriorityLbConfig(Collections.unmodifiableMap(priorityChildConfigs),
|
||||
Collections.unmodifiableList(priorities));
|
||||
lb.handleResolvedAddresses(
|
||||
resolvedAddresses.toBuilder()
|
||||
|
|
|
|||
|
|
@ -34,17 +34,22 @@ import io.grpc.internal.ServiceConfigUtil.PolicySelection;
|
|||
import io.grpc.util.ForwardingLoadBalancerHelper;
|
||||
import io.grpc.util.GracefulSwitchLoadBalancer;
|
||||
import io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig;
|
||||
import io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig.PriorityChildConfig;
|
||||
import io.grpc.xds.XdsLogger.XdsLogLevel;
|
||||
import io.grpc.xds.XdsSubchannelPickers.ErrorPicker;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/** Load balancer for priority policy. */
|
||||
/**
|
||||
* Load balancer for priority policy. A <em>priority</em> represents a logical entity within a
|
||||
* cluster for load balancing purposes.
|
||||
*/
|
||||
final class PriorityLoadBalancer extends LoadBalancer {
|
||||
private final Helper helper;
|
||||
private final SynchronizationContext syncContext;
|
||||
|
|
@ -57,8 +62,10 @@ final class PriorityLoadBalancer extends LoadBalancer {
|
|||
|
||||
// Following fields are only null initially.
|
||||
private ResolvedAddresses resolvedAddresses;
|
||||
// List of priority names in order.
|
||||
private List<String> priorityNames;
|
||||
private Map<String, Integer> priorityNameToIndex;
|
||||
// Config for each priority.
|
||||
private Map<String, PriorityChildConfig> priorityConfigs;
|
||||
private ConnectivityState currentConnectivityState;
|
||||
private SubchannelPicker currentPicker;
|
||||
|
||||
|
|
@ -78,13 +85,10 @@ final class PriorityLoadBalancer extends LoadBalancer {
|
|||
PriorityLbConfig config = (PriorityLbConfig) resolvedAddresses.getLoadBalancingPolicyConfig();
|
||||
checkNotNull(config, "missing priority lb config");
|
||||
priorityNames = config.priorities;
|
||||
Map<String, Integer> pToI = new HashMap<>();
|
||||
for (int i = 0; i < priorityNames.size(); i++) {
|
||||
pToI.put(priorityNames.get(i), i);
|
||||
}
|
||||
priorityNameToIndex = Collections.unmodifiableMap(pToI);
|
||||
priorityConfigs = config.childConfigs;
|
||||
Set<String> prioritySet = new HashSet<>(config.priorities);
|
||||
for (String priority : children.keySet()) {
|
||||
if (!priorityNameToIndex.containsKey(priority)) {
|
||||
if (!prioritySet.contains(priority)) {
|
||||
children.get(priority).deactivate();
|
||||
}
|
||||
}
|
||||
|
|
@ -125,7 +129,8 @@ final class PriorityLoadBalancer extends LoadBalancer {
|
|||
for (int i = 0; i < priorityNames.size(); i++) {
|
||||
String priority = priorityNames.get(i);
|
||||
if (!children.containsKey(priority)) {
|
||||
ChildLbState child = new ChildLbState(priority);
|
||||
ChildLbState child =
|
||||
new ChildLbState(priority, priorityConfigs.get(priority).ignoreReresolution);
|
||||
children.put(priority, child);
|
||||
child.updateResolvedAddresses();
|
||||
updateOverallState(CONNECTING, BUFFER_PICKER);
|
||||
|
|
@ -180,9 +185,9 @@ final class PriorityLoadBalancer extends LoadBalancer {
|
|||
ConnectivityState connectivityState = CONNECTING;
|
||||
SubchannelPicker picker = BUFFER_PICKER;
|
||||
|
||||
ChildLbState(final String priority) {
|
||||
ChildLbState(final String priority, boolean ignoreReresolution) {
|
||||
this.priority = priority;
|
||||
childHelper = new ChildHelper();
|
||||
childHelper = new ChildHelper(ignoreReresolution);
|
||||
lb = new GracefulSwitchLoadBalancer(childHelper);
|
||||
|
||||
class FailOverTask implements Runnable {
|
||||
|
|
@ -253,7 +258,7 @@ final class PriorityLoadBalancer extends LoadBalancer {
|
|||
void updateResolvedAddresses() {
|
||||
PriorityLbConfig config =
|
||||
(PriorityLbConfig) resolvedAddresses.getLoadBalancingPolicyConfig();
|
||||
PolicySelection childPolicySelection = config.childConfigs.get(priority);
|
||||
PolicySelection childPolicySelection = config.childConfigs.get(priority).policySelection;
|
||||
LoadBalancerProvider lbProvider = childPolicySelection.getProvider();
|
||||
String newPolicy = lbProvider.getPolicyName();
|
||||
if (!newPolicy.equals(policy)) {
|
||||
|
|
@ -268,6 +273,19 @@ final class PriorityLoadBalancer extends LoadBalancer {
|
|||
}
|
||||
|
||||
final class ChildHelper extends ForwardingLoadBalancerHelper {
|
||||
private final boolean ignoreReresolution;
|
||||
|
||||
ChildHelper(boolean ignoreReresolution) {
|
||||
this.ignoreReresolution = ignoreReresolution;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshNameResolution() {
|
||||
if (!ignoreReresolution) {
|
||||
delegate().refreshNameResolution();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBalancingState(final ConnectivityState newState,
|
||||
final SubchannelPicker newPicker) {
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@ public final class PriorityLoadBalancerProvider extends LoadBalancerProvider {
|
|||
}
|
||||
|
||||
static final class PriorityLbConfig {
|
||||
final Map<String, PolicySelection> childConfigs;
|
||||
final Map<String, PriorityChildConfig> childConfigs;
|
||||
final List<String> priorities;
|
||||
|
||||
PriorityLbConfig(Map<String, PolicySelection> childConfigs, List<String> priorities) {
|
||||
PriorityLbConfig(Map<String, PriorityChildConfig> childConfigs, List<String> priorities) {
|
||||
this.childConfigs = Collections.unmodifiableMap(checkNotNull(childConfigs, "childConfigs"));
|
||||
this.priorities = Collections.unmodifiableList(checkNotNull(priorities, "priorities"));
|
||||
checkArgument(!priorities.isEmpty(), "priority list is empty");
|
||||
|
|
@ -86,5 +86,15 @@ public final class PriorityLoadBalancerProvider extends LoadBalancerProvider {
|
|||
.add("priorities", priorities)
|
||||
.toString();
|
||||
}
|
||||
|
||||
static final class PriorityChildConfig {
|
||||
final PolicySelection policySelection;
|
||||
final boolean ignoreReresolution;
|
||||
|
||||
PriorityChildConfig(PolicySelection policySelection, boolean ignoreReresolution) {
|
||||
this.policySelection = checkNotNull(policySelection, "policySelection");
|
||||
this.ignoreReresolution = ignoreReresolution;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ import io.grpc.Status.Code;
|
|||
import io.grpc.SynchronizationContext;
|
||||
import io.grpc.internal.BackoffPolicy;
|
||||
import io.grpc.internal.FakeClock;
|
||||
import io.grpc.internal.FakeClock.ScheduledTask;
|
||||
import io.grpc.internal.GrpcUtil;
|
||||
import io.grpc.internal.ObjectPool;
|
||||
import io.grpc.internal.ServiceConfigUtil.PolicySelection;
|
||||
|
|
@ -66,6 +67,7 @@ import io.grpc.xds.EnvoyProtoData.LocalityLbEndpoints;
|
|||
import io.grpc.xds.EnvoyServerProtoData.UpstreamTlsContext;
|
||||
import io.grpc.xds.LrsLoadBalancerProvider.LrsConfig;
|
||||
import io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig;
|
||||
import io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig.PriorityChildConfig;
|
||||
import io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedPolicySelection;
|
||||
import io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedTargetConfig;
|
||||
import io.grpc.xds.internal.sds.CommonTlsContextTestsUtil;
|
||||
|
|
@ -151,7 +153,9 @@ public class ClusterResolverLoadBalancerTest {
|
|||
@Mock
|
||||
private BackoffPolicy.Provider backoffPolicyProvider;
|
||||
@Mock
|
||||
private BackoffPolicy backoffPolicy;
|
||||
private BackoffPolicy backoffPolicy1;
|
||||
@Mock
|
||||
private BackoffPolicy backoffPolicy2;
|
||||
@Captor
|
||||
private ArgumentCaptor<SubchannelPicker> pickerCaptor;
|
||||
private int xdsClientRefs;
|
||||
|
|
@ -181,9 +185,11 @@ public class ClusterResolverLoadBalancerTest {
|
|||
when(helper.getSynchronizationContext()).thenReturn(syncContext);
|
||||
when(helper.getScheduledExecutorService()).thenReturn(fakeClock.getScheduledExecutorService());
|
||||
when(helper.getAuthority()).thenReturn(AUTHORITY);
|
||||
when(backoffPolicyProvider.get()).thenReturn(backoffPolicy);
|
||||
when(backoffPolicy.nextBackoffNanos())
|
||||
when(backoffPolicyProvider.get()).thenReturn(backoffPolicy1, backoffPolicy2);
|
||||
when(backoffPolicy1.nextBackoffNanos())
|
||||
.thenReturn(TimeUnit.SECONDS.toNanos(1L), TimeUnit.SECONDS.toNanos(10L));
|
||||
when(backoffPolicy2.nextBackoffNanos())
|
||||
.thenReturn(TimeUnit.SECONDS.toNanos(5L), TimeUnit.SECONDS.toNanos(50L));
|
||||
loadBalancer = new ClusterResolverLoadBalancer(helper, lbRegistry, backoffPolicyProvider);
|
||||
}
|
||||
|
||||
|
|
@ -193,6 +199,7 @@ public class ClusterResolverLoadBalancerTest {
|
|||
assertThat(resolvers).isEmpty();
|
||||
assertThat(xdsClient.watchers).isEmpty();
|
||||
assertThat(xdsClientRefs).isEqualTo(0);
|
||||
assertThat(fakeClock.getPendingTasks()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -224,10 +231,12 @@ public class ClusterResolverLoadBalancerTest {
|
|||
assertThat(childBalancer.name).isEqualTo(PRIORITY_POLICY_NAME);
|
||||
PriorityLbConfig priorityLbConfig = (PriorityLbConfig) childBalancer.config;
|
||||
assertThat(priorityLbConfig.priorities).containsExactly(priority1, priority2).inOrder();
|
||||
PolicySelection priorityChildPolicy = priorityLbConfig.childConfigs.get(priority1);
|
||||
assertThat(priorityChildPolicy.getProvider().getPolicyName())
|
||||
PriorityChildConfig priorityChildConfig = priorityLbConfig.childConfigs.get(priority1);
|
||||
assertThat(priorityChildConfig.ignoreReresolution).isTrue();
|
||||
assertThat(priorityChildConfig.policySelection.getProvider().getPolicyName())
|
||||
.isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
||||
ClusterImplConfig clusterImplConfig = (ClusterImplConfig) priorityChildPolicy.getConfig();
|
||||
ClusterImplConfig clusterImplConfig =
|
||||
(ClusterImplConfig) priorityChildConfig.policySelection.getConfig();
|
||||
assertClusterImplConfig(clusterImplConfig, CLUSTER2, EDS_SERVICE_NAME2, LRS_SERVER_NAME, 200L,
|
||||
tlsContext, Collections.<DropOverload>emptyList(), WEIGHTED_TARGET_POLICY_NAME);
|
||||
WeightedTargetConfig weightedTargetConfig =
|
||||
|
|
@ -239,10 +248,11 @@ public class ClusterResolverLoadBalancerTest {
|
|||
assertLrsConfig((LrsConfig) target.policySelection.getConfig(), CLUSTER2, EDS_SERVICE_NAME2,
|
||||
LRS_SERVER_NAME, locality1, "round_robin");
|
||||
|
||||
priorityChildPolicy = priorityLbConfig.childConfigs.get(priority2);
|
||||
assertThat(priorityChildPolicy.getProvider().getPolicyName())
|
||||
priorityChildConfig = priorityLbConfig.childConfigs.get(priority2);
|
||||
assertThat(priorityChildConfig.ignoreReresolution).isTrue();
|
||||
assertThat(priorityChildConfig.policySelection.getProvider().getPolicyName())
|
||||
.isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
||||
clusterImplConfig = (ClusterImplConfig) priorityChildPolicy.getConfig();
|
||||
clusterImplConfig = (ClusterImplConfig) priorityChildConfig.policySelection.getConfig();
|
||||
assertClusterImplConfig(clusterImplConfig, CLUSTER2, EDS_SERVICE_NAME2, LRS_SERVER_NAME, 200L,
|
||||
tlsContext, Collections.<DropOverload>emptyList(), WEIGHTED_TARGET_POLICY_NAME);
|
||||
weightedTargetConfig = (WeightedTargetConfig) clusterImplConfig.childPolicy.getConfig();
|
||||
|
|
@ -269,10 +279,11 @@ public class ClusterResolverLoadBalancerTest {
|
|||
assertThat(priorityLbConfig.priorities)
|
||||
.containsExactly(priority3, priority1, priority2).inOrder();
|
||||
|
||||
priorityChildPolicy = priorityLbConfig.childConfigs.get(priority3);
|
||||
assertThat(priorityChildPolicy.getProvider().getPolicyName())
|
||||
priorityChildConfig = priorityLbConfig.childConfigs.get(priority3);
|
||||
assertThat(priorityChildConfig.ignoreReresolution).isTrue();
|
||||
assertThat(priorityChildConfig.policySelection.getProvider().getPolicyName())
|
||||
.isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
||||
clusterImplConfig = (ClusterImplConfig) priorityChildPolicy.getConfig();
|
||||
clusterImplConfig = (ClusterImplConfig) priorityChildConfig.policySelection.getConfig();
|
||||
assertClusterImplConfig(clusterImplConfig, CLUSTER1, EDS_SERVICE_NAME1, LRS_SERVER_NAME, 100L,
|
||||
tlsContext, Collections.<DropOverload>emptyList(), WEIGHTED_TARGET_POLICY_NAME);
|
||||
weightedTargetConfig = (WeightedTargetConfig) clusterImplConfig.childPolicy.getConfig();
|
||||
|
|
@ -374,8 +385,9 @@ public class ClusterResolverLoadBalancerTest {
|
|||
|
||||
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
||||
PriorityLbConfig priorityLbConfig = (PriorityLbConfig) childBalancer.config;
|
||||
PolicySelection priorityChildPolicy = priorityLbConfig.childConfigs.get(priority);
|
||||
ClusterImplConfig clusterImplConfig = (ClusterImplConfig) priorityChildPolicy.getConfig();
|
||||
PriorityChildConfig priorityChildConfig = priorityLbConfig.childConfigs.get(priority);
|
||||
ClusterImplConfig clusterImplConfig =
|
||||
(ClusterImplConfig) priorityChildConfig.policySelection.getConfig();
|
||||
WeightedTargetConfig weightedTargetConfig =
|
||||
(WeightedTargetConfig) clusterImplConfig.childPolicy.getConfig();
|
||||
assertThat(weightedTargetConfig.targets.keySet()).containsExactly(locality2.toString());
|
||||
|
|
@ -439,10 +451,12 @@ public class ClusterResolverLoadBalancerTest {
|
|||
assertThat(childBalancer.name).isEqualTo(PRIORITY_POLICY_NAME);
|
||||
PriorityLbConfig priorityLbConfig = (PriorityLbConfig) childBalancer.config;
|
||||
String priority = Iterables.getOnlyElement(priorityLbConfig.priorities);
|
||||
PolicySelection priorityChildPolicy = priorityLbConfig.childConfigs.get(priority);
|
||||
assertThat(priorityChildPolicy.getProvider().getPolicyName())
|
||||
PriorityChildConfig priorityChildConfig = priorityLbConfig.childConfigs.get(priority);
|
||||
assertThat(priorityChildConfig.ignoreReresolution).isFalse();
|
||||
assertThat(priorityChildConfig.policySelection.getProvider().getPolicyName())
|
||||
.isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
||||
ClusterImplConfig clusterImplConfig = (ClusterImplConfig) priorityChildPolicy.getConfig();
|
||||
ClusterImplConfig clusterImplConfig =
|
||||
(ClusterImplConfig) priorityChildConfig.policySelection.getConfig();
|
||||
assertClusterImplConfig(clusterImplConfig, CLUSTER_DNS, null, LRS_SERVER_NAME, 100L, null,
|
||||
Collections.<DropOverload>emptyList(), LRS_POLICY_NAME);
|
||||
LrsConfig lrsConfig = (LrsConfig) clusterImplConfig.childPolicy.getConfig();
|
||||
|
|
@ -451,9 +465,23 @@ public class ClusterResolverLoadBalancerTest {
|
|||
assertAddressesEqual(Arrays.asList(endpoint1, endpoint2), childBalancer.addresses);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onlyLogicalDnsCluster_handleRefreshNameResolution() {
|
||||
deliverConfigWithSingleLogicalDnsCluster();
|
||||
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1");
|
||||
EquivalentAddressGroup endpoint2 = makeAddress("endpoint-addr-2");
|
||||
FakeNameResolver resolver = Iterables.getOnlyElement(resolvers);
|
||||
resolver.deliverEndpointAddresses(Arrays.asList(endpoint1, endpoint2));
|
||||
assertThat(resolver.refreshCount).isEqualTo(0);
|
||||
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
||||
childBalancer.helper.refreshNameResolution();
|
||||
assertThat(resolver.refreshCount).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onlyLogicalDnsCluster_resolutionError_backoffAndRefresh() {
|
||||
InOrder inOrder = Mockito.inOrder(helper, backoffPolicyProvider, backoffPolicy);
|
||||
InOrder inOrder = Mockito.inOrder(helper, backoffPolicyProvider,
|
||||
backoffPolicy1, backoffPolicy2);
|
||||
deliverConfigWithSingleLogicalDnsCluster();
|
||||
FakeNameResolver resolver = Iterables.getOnlyElement(resolvers);
|
||||
Status error = Status.UNAVAILABLE.withDescription("cannot reach DNS server");
|
||||
|
|
@ -463,7 +491,7 @@ public class ClusterResolverLoadBalancerTest {
|
|||
assertPicker(pickerCaptor.getValue(), error, null);
|
||||
assertThat(resolver.refreshCount).isEqualTo(0);
|
||||
inOrder.verify(backoffPolicyProvider).get();
|
||||
inOrder.verify(backoffPolicy).nextBackoffNanos();
|
||||
inOrder.verify(backoffPolicy1).nextBackoffNanos();
|
||||
assertThat(fakeClock.getPendingTasks()).hasSize(1);
|
||||
assertThat(Iterables.getOnlyElement(fakeClock.getPendingTasks()).getDelay(TimeUnit.SECONDS))
|
||||
.isEqualTo(1L);
|
||||
|
|
@ -474,7 +502,7 @@ public class ClusterResolverLoadBalancerTest {
|
|||
resolver.deliverError(error);
|
||||
inOrder.verify(helper).updateBalancingState(
|
||||
eq(ConnectivityState.TRANSIENT_FAILURE), pickerCaptor.capture());
|
||||
inOrder.verify(backoffPolicy).nextBackoffNanos();
|
||||
inOrder.verify(backoffPolicy1).nextBackoffNanos();
|
||||
assertPicker(pickerCaptor.getValue(), error, null);
|
||||
assertThat(fakeClock.getPendingTasks()).hasSize(1);
|
||||
assertThat(Iterables.getOnlyElement(fakeClock.getPendingTasks()).getDelay(TimeUnit.SECONDS))
|
||||
|
|
@ -494,6 +522,42 @@ public class ClusterResolverLoadBalancerTest {
|
|||
inOrder.verifyNoMoreInteractions();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onlyLogicalDnsCluster_refreshNameResolutionRaceWithResolutionError() {
|
||||
InOrder inOrder = Mockito.inOrder(backoffPolicyProvider, backoffPolicy1, backoffPolicy2);
|
||||
deliverConfigWithSingleLogicalDnsCluster();
|
||||
EquivalentAddressGroup endpoint = makeAddress("endpoint-addr");
|
||||
FakeNameResolver resolver = Iterables.getOnlyElement(resolvers);
|
||||
resolver.deliverEndpointAddresses(Collections.singletonList(endpoint));
|
||||
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
||||
assertAddressesEqual(Collections.singletonList(endpoint), childBalancer.addresses);
|
||||
assertThat(resolver.refreshCount).isEqualTo(0);
|
||||
|
||||
childBalancer.helper.refreshNameResolution();
|
||||
assertThat(resolver.refreshCount).isEqualTo(1);
|
||||
resolver.deliverError(Status.UNAVAILABLE.withDescription("I am lost"));
|
||||
inOrder.verify(backoffPolicyProvider).get();
|
||||
inOrder.verify(backoffPolicy1).nextBackoffNanos();
|
||||
assertThat(fakeClock.getPendingTasks()).hasSize(1);
|
||||
ScheduledTask task = Iterables.getOnlyElement(fakeClock.getPendingTasks());
|
||||
assertThat(task.getDelay(TimeUnit.SECONDS)).isEqualTo(1L);
|
||||
|
||||
fakeClock.forwardTime( 100L, TimeUnit.MILLISECONDS);
|
||||
childBalancer.helper.refreshNameResolution();
|
||||
assertThat(resolver.refreshCount).isEqualTo(2);
|
||||
assertThat(task.isCancelled()).isTrue();
|
||||
assertThat(fakeClock.getPendingTasks()).isEmpty();
|
||||
resolver.deliverError(Status.UNAVAILABLE.withDescription("I am still lost"));
|
||||
inOrder.verify(backoffPolicyProvider).get(); // active refresh resets backoff sequence
|
||||
inOrder.verify(backoffPolicy2).nextBackoffNanos();
|
||||
task = Iterables.getOnlyElement(fakeClock.getPendingTasks());
|
||||
assertThat(task.getDelay(TimeUnit.SECONDS)).isEqualTo(5L);
|
||||
|
||||
fakeClock.forwardTime(5L, TimeUnit.SECONDS);
|
||||
assertThat(resolver.refreshCount).isEqualTo(3);
|
||||
inOrder.verifyNoMoreInteractions();
|
||||
}
|
||||
|
||||
private void deliverConfigWithSingleLogicalDnsCluster() {
|
||||
DiscoveryMechanism instance =
|
||||
DiscoveryMechanism.forLogicalDns(CLUSTER_DNS, LRS_SERVER_NAME, 100L, null);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ import io.grpc.xds.EnvoyProtoData.LocalityLbEndpoints;
|
|||
import io.grpc.xds.EnvoyServerProtoData.UpstreamTlsContext;
|
||||
import io.grpc.xds.LrsLoadBalancerProvider.LrsConfig;
|
||||
import io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig;
|
||||
import io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig.PriorityChildConfig;
|
||||
import io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedPolicySelection;
|
||||
import io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedTargetConfig;
|
||||
import io.grpc.xds.internal.sds.CommonTlsContextTestsUtil;
|
||||
|
|
@ -170,9 +171,12 @@ public class EdsLoadBalancer2Test {
|
|||
assertThat(childBalancer.name).isEqualTo(PRIORITY_POLICY_NAME);
|
||||
PriorityLbConfig config = (PriorityLbConfig) childBalancer.config;
|
||||
assertThat(config.priorities).containsExactly("priority1", "priority2");
|
||||
PolicySelection priorityChild1 = config.childConfigs.get("priority1");
|
||||
assertThat(priorityChild1.getProvider().getPolicyName()).isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
||||
ClusterImplConfig clusterImplConfig1 = (ClusterImplConfig) priorityChild1.getConfig();
|
||||
PriorityChildConfig priorityChild1 = config.childConfigs.get("priority1");
|
||||
assertThat(priorityChild1.ignoreReresolution).isTrue();
|
||||
assertThat(priorityChild1.policySelection.getProvider().getPolicyName())
|
||||
.isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
||||
ClusterImplConfig clusterImplConfig1 =
|
||||
(ClusterImplConfig) priorityChild1.policySelection.getConfig();
|
||||
assertClusterImplConfig(clusterImplConfig1, CLUSTER, EDS_SERVICE_NAME, LRS_SERVER_NAME,
|
||||
null, Collections.<DropOverload>emptyList(), WEIGHTED_TARGET_POLICY_NAME);
|
||||
PolicySelection weightedTargetPolicy1 = clusterImplConfig1.childPolicy;
|
||||
|
|
@ -193,9 +197,12 @@ public class EdsLoadBalancer2Test {
|
|||
assertLrsConfig((LrsConfig) target2.policySelection.getConfig(), CLUSTER, EDS_SERVICE_NAME,
|
||||
LRS_SERVER_NAME, locality2, "round_robin");
|
||||
|
||||
PolicySelection priorityChild2 = config.childConfigs.get("priority2");
|
||||
assertThat(priorityChild2.getProvider().getPolicyName()).isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
||||
ClusterImplConfig clusterImplConfig2 = (ClusterImplConfig) priorityChild2.getConfig();
|
||||
PriorityChildConfig priorityChild2 = config.childConfigs.get("priority2");
|
||||
assertThat(priorityChild2.ignoreReresolution).isTrue();
|
||||
assertThat(priorityChild2.policySelection.getProvider().getPolicyName())
|
||||
.isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
||||
ClusterImplConfig clusterImplConfig2 =
|
||||
(ClusterImplConfig) priorityChild2.policySelection.getConfig();
|
||||
assertClusterImplConfig(clusterImplConfig2, CLUSTER, EDS_SERVICE_NAME, LRS_SERVER_NAME,
|
||||
null, Collections.<DropOverload>emptyList(), WEIGHTED_TARGET_POLICY_NAME);
|
||||
PolicySelection weightedTargetPolicy2 = clusterImplConfig2.childPolicy;
|
||||
|
|
@ -244,9 +251,12 @@ public class EdsLoadBalancer2Test {
|
|||
assertThat(childBalancer.name).isEqualTo(PRIORITY_POLICY_NAME);
|
||||
PriorityLbConfig config = (PriorityLbConfig) childBalancer.config;
|
||||
assertThat(config.priorities).containsExactly("priority1");
|
||||
PolicySelection priorityChild = config.childConfigs.get("priority1");
|
||||
assertThat(priorityChild.getProvider().getPolicyName()).isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
||||
ClusterImplConfig clusterImplConfig = (ClusterImplConfig) priorityChild.getConfig();
|
||||
PriorityChildConfig priorityChild = config.childConfigs.get("priority1");
|
||||
assertThat(priorityChild.ignoreReresolution).isTrue();
|
||||
assertThat(priorityChild.policySelection.getProvider().getPolicyName())
|
||||
.isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
||||
ClusterImplConfig clusterImplConfig =
|
||||
(ClusterImplConfig) priorityChild.policySelection.getConfig();
|
||||
PolicySelection weightedTargetPolicy = clusterImplConfig.childPolicy;
|
||||
assertThat(weightedTargetPolicy.getProvider().getPolicyName())
|
||||
.isEqualTo(WEIGHTED_TARGET_POLICY_NAME);
|
||||
|
|
@ -276,8 +286,10 @@ public class EdsLoadBalancer2Test {
|
|||
config = (PriorityLbConfig) childBalancer.config;
|
||||
assertThat(config.priorities).containsExactly("priority1");
|
||||
priorityChild = config.childConfigs.get("priority1");
|
||||
assertThat(priorityChild.getProvider().getPolicyName()).isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
||||
clusterImplConfig = (ClusterImplConfig) priorityChild.getConfig();
|
||||
assertThat(priorityChild.ignoreReresolution).isTrue();
|
||||
assertThat(priorityChild.policySelection.getProvider().getPolicyName())
|
||||
.isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
||||
clusterImplConfig = (ClusterImplConfig) priorityChild.policySelection.getConfig();
|
||||
weightedTargetPolicy = clusterImplConfig.childPolicy;
|
||||
assertThat(weightedTargetPolicy.getProvider().getPolicyName())
|
||||
.isEqualTo(WEIGHTED_TARGET_POLICY_NAME);
|
||||
|
|
@ -355,8 +367,9 @@ public class EdsLoadBalancer2Test {
|
|||
|
||||
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
||||
PriorityLbConfig config = (PriorityLbConfig) childBalancer.config;
|
||||
PolicySelection priorityChildPolicy = config.childConfigs.get("priority1");
|
||||
ClusterImplConfig clusterImplConfig = (ClusterImplConfig) priorityChildPolicy.getConfig();
|
||||
PriorityChildConfig priorityChildConfig = config.childConfigs.get("priority1");
|
||||
ClusterImplConfig clusterImplConfig =
|
||||
(ClusterImplConfig) priorityChildConfig.policySelection.getConfig();
|
||||
WeightedTargetConfig weightedTargetConfig =
|
||||
(WeightedTargetConfig) clusterImplConfig.childPolicy.getConfig();
|
||||
assertThat(weightedTargetConfig.targets.keySet()).containsExactly(locality2.toString());
|
||||
|
|
@ -484,7 +497,7 @@ public class EdsLoadBalancer2Test {
|
|||
}
|
||||
|
||||
private Long populateMaxConcurrentRequests(PriorityLbConfig config, String priority) {
|
||||
PolicySelection priorityChildConfig = config.childConfigs.get(priority);
|
||||
PolicySelection priorityChildConfig = config.childConfigs.get(priority).policySelection;
|
||||
ClusterImplConfig clusterImplConfig = (ClusterImplConfig) priorityChildConfig.getConfig();
|
||||
return clusterImplConfig.maxConcurrentRequests;
|
||||
}
|
||||
|
|
@ -510,7 +523,7 @@ public class EdsLoadBalancer2Test {
|
|||
}
|
||||
|
||||
private UpstreamTlsContext populateTlsContext(PriorityLbConfig config, String priority) {
|
||||
PolicySelection priorityChildConfig = config.childConfigs.get(priority);
|
||||
PolicySelection priorityChildConfig = config.childConfigs.get(priority).policySelection;
|
||||
ClusterImplConfig clusterImplConfig = (ClusterImplConfig) priorityChildConfig.getConfig();
|
||||
return clusterImplConfig.tlsContext;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableMap;
|
|||
import io.grpc.LoadBalancerProvider;
|
||||
import io.grpc.internal.ServiceConfigUtil.PolicySelection;
|
||||
import io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig;
|
||||
import io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig.PriorityChildConfig;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.Rule;
|
||||
|
|
@ -40,8 +41,11 @@ public class PriorityLoadBalancerProviderTest {
|
|||
@SuppressWarnings("ExpectedExceptionChecker")
|
||||
@Test
|
||||
public void priorityLbConfig_emptyPriorities() {
|
||||
Map<String, PolicySelection> childConfigs =
|
||||
ImmutableMap.of("p0", new PolicySelection(mock(LoadBalancerProvider.class), null));
|
||||
Map<String, PriorityChildConfig> childConfigs =
|
||||
ImmutableMap.of(
|
||||
"p0",
|
||||
new PriorityChildConfig(
|
||||
new PolicySelection(mock(LoadBalancerProvider.class), null), true));
|
||||
List<String> priorities = ImmutableList.of();
|
||||
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
|
|
@ -51,8 +55,11 @@ public class PriorityLoadBalancerProviderTest {
|
|||
@SuppressWarnings("ExpectedExceptionChecker")
|
||||
@Test
|
||||
public void priorityLbConfig_missingChildConfig() {
|
||||
Map<String, PolicySelection> childConfigs =
|
||||
ImmutableMap.of("p1", new PolicySelection(mock(LoadBalancerProvider.class), null));
|
||||
Map<String, PriorityChildConfig> childConfigs =
|
||||
ImmutableMap.of(
|
||||
"p1",
|
||||
new PriorityChildConfig(
|
||||
new PolicySelection(mock(LoadBalancerProvider.class), null), true));
|
||||
List<String> priorities = ImmutableList.of("p0", "p1");
|
||||
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ import io.grpc.internal.FakeClock;
|
|||
import io.grpc.internal.ServiceConfigUtil.PolicySelection;
|
||||
import io.grpc.internal.TestUtils.StandardLoadBalancerProvider;
|
||||
import io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig;
|
||||
import io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig.PriorityChildConfig;
|
||||
import io.grpc.xds.XdsSubchannelPickers.ErrorPicker;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
|
|
@ -137,14 +138,18 @@ public class PriorityLoadBalancerTest {
|
|||
Attributes attributes =
|
||||
Attributes.newBuilder().set(Attributes.Key.create("fakeKey"), "fakeValue").build();
|
||||
Object fooConfig0 = new Object();
|
||||
PolicySelection fooPolicy0 = new PolicySelection(fooLbProvider, fooConfig0);
|
||||
PriorityChildConfig priorityChildConfig0 =
|
||||
new PriorityChildConfig(new PolicySelection(fooLbProvider, fooConfig0), true);
|
||||
Object barConfig0 = new Object();
|
||||
PolicySelection barPolicy0 = new PolicySelection(barLbProvider, barConfig0);
|
||||
PriorityChildConfig priorityChildConfig1 =
|
||||
new PriorityChildConfig(new PolicySelection(barLbProvider, barConfig0), true);
|
||||
Object fooConfig1 = new Object();
|
||||
PolicySelection fooPolicy1 = new PolicySelection(fooLbProvider, fooConfig1);
|
||||
PriorityChildConfig priorityChildConfig2 =
|
||||
new PriorityChildConfig(new PolicySelection(fooLbProvider, fooConfig1), true);
|
||||
PriorityLbConfig priorityLbConfig =
|
||||
new PriorityLbConfig(
|
||||
ImmutableMap.of("p0", fooPolicy0, "p1", barPolicy0, "p2", fooPolicy1),
|
||||
ImmutableMap.of("p0", priorityChildConfig0, "p1", priorityChildConfig1,
|
||||
"p2", priorityChildConfig2),
|
||||
ImmutableList.of("p0", "p1", "p2"));
|
||||
priorityLb.handleResolvedAddresses(
|
||||
ResolvedAddresses.newBuilder()
|
||||
|
|
@ -190,9 +195,11 @@ public class PriorityLoadBalancerTest {
|
|||
newEag = AddressFilter.setPathFilter(newEag, ImmutableList.of("p1"));
|
||||
List<EquivalentAddressGroup> newAddresses = ImmutableList.of(newEag);
|
||||
Object newBarConfig = new Object();
|
||||
PolicySelection newBarPolicy = new PolicySelection(barLbProvider, newBarConfig);
|
||||
PriorityLbConfig newPriorityLbConfig =
|
||||
new PriorityLbConfig(ImmutableMap.of("p1", newBarPolicy), ImmutableList.of("p1"));
|
||||
new PriorityLbConfig(
|
||||
ImmutableMap.of("p1",
|
||||
new PriorityChildConfig(new PolicySelection(barLbProvider, newBarConfig), true)),
|
||||
ImmutableList.of("p1"));
|
||||
priorityLb.handleResolvedAddresses(
|
||||
ResolvedAddresses.newBuilder()
|
||||
.setAddresses(newAddresses)
|
||||
|
|
@ -217,12 +224,14 @@ public class PriorityLoadBalancerTest {
|
|||
@Test
|
||||
public void handleNameResolutionError() {
|
||||
Object fooConfig0 = new Object();
|
||||
PolicySelection fooPolicy0 = new PolicySelection(fooLbProvider, fooConfig0);
|
||||
PriorityChildConfig priorityChildConfig0 =
|
||||
new PriorityChildConfig(new PolicySelection(fooLbProvider, fooConfig0), true);
|
||||
Object fooConfig1 = new Object();
|
||||
PolicySelection fooPolicy1 = new PolicySelection(fooLbProvider, fooConfig1);
|
||||
PriorityChildConfig priorityChildConfig1 =
|
||||
new PriorityChildConfig(new PolicySelection(fooLbProvider, fooConfig1), true);
|
||||
|
||||
PriorityLbConfig priorityLbConfig =
|
||||
new PriorityLbConfig(ImmutableMap.of("p0", fooPolicy0), ImmutableList.of("p0"));
|
||||
new PriorityLbConfig(ImmutableMap.of("p0", priorityChildConfig0), ImmutableList.of("p0"));
|
||||
priorityLb.handleResolvedAddresses(
|
||||
ResolvedAddresses.newBuilder()
|
||||
.setAddresses(ImmutableList.<EquivalentAddressGroup>of())
|
||||
|
|
@ -234,7 +243,7 @@ public class PriorityLoadBalancerTest {
|
|||
verify(fooLb0).handleNameResolutionError(status);
|
||||
|
||||
priorityLbConfig =
|
||||
new PriorityLbConfig(ImmutableMap.of("p1", fooPolicy1), ImmutableList.of("p1"));
|
||||
new PriorityLbConfig(ImmutableMap.of("p1", priorityChildConfig1), ImmutableList.of("p1"));
|
||||
priorityLb.handleResolvedAddresses(
|
||||
ResolvedAddresses.newBuilder()
|
||||
.setAddresses(ImmutableList.<EquivalentAddressGroup>of())
|
||||
|
|
@ -253,13 +262,18 @@ public class PriorityLoadBalancerTest {
|
|||
|
||||
@Test
|
||||
public void typicalPriorityFailOverFlow() {
|
||||
PolicySelection policy0 = new PolicySelection(fooLbProvider, new Object());
|
||||
PolicySelection policy1 = new PolicySelection(fooLbProvider, new Object());
|
||||
PolicySelection policy2 = new PolicySelection(fooLbProvider, new Object());
|
||||
PolicySelection policy3 = new PolicySelection(fooLbProvider, new Object());
|
||||
PriorityChildConfig priorityChildConfig0 =
|
||||
new PriorityChildConfig(new PolicySelection(fooLbProvider, new Object()), true);
|
||||
PriorityChildConfig priorityChildConfig1 =
|
||||
new PriorityChildConfig(new PolicySelection(fooLbProvider, new Object()), true);
|
||||
PriorityChildConfig priorityChildConfig2 =
|
||||
new PriorityChildConfig(new PolicySelection(fooLbProvider, new Object()), true);
|
||||
PriorityChildConfig priorityChildConfig3 =
|
||||
new PriorityChildConfig(new PolicySelection(fooLbProvider, new Object()), true);
|
||||
PriorityLbConfig priorityLbConfig =
|
||||
new PriorityLbConfig(
|
||||
ImmutableMap.of("p0", policy0, "p1", policy1, "p2", policy2, "p3", policy3),
|
||||
ImmutableMap.of("p0", priorityChildConfig0, "p1", priorityChildConfig1,
|
||||
"p2", priorityChildConfig2, "p3", priorityChildConfig3),
|
||||
ImmutableList.of("p0", "p1", "p2", "p3"));
|
||||
priorityLb.handleResolvedAddresses(
|
||||
ResolvedAddresses.newBuilder()
|
||||
|
|
@ -379,6 +393,33 @@ public class PriorityLoadBalancerTest {
|
|||
verify(balancer3).shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bypassReresolutionRequestsIfConfiged() {
|
||||
PriorityChildConfig priorityChildConfig0 =
|
||||
new PriorityChildConfig(new PolicySelection(fooLbProvider, new Object()), true);
|
||||
PriorityChildConfig priorityChildConfig1 =
|
||||
new PriorityChildConfig(new PolicySelection(fooLbProvider, new Object()), false);
|
||||
PriorityLbConfig priorityLbConfig =
|
||||
new PriorityLbConfig(
|
||||
ImmutableMap.of("p0", priorityChildConfig0, "p1", priorityChildConfig1),
|
||||
ImmutableList.of("p0", "p1"));
|
||||
priorityLb.handleResolvedAddresses(
|
||||
ResolvedAddresses.newBuilder()
|
||||
.setAddresses(ImmutableList.<EquivalentAddressGroup>of())
|
||||
.setLoadBalancingPolicyConfig(priorityLbConfig)
|
||||
.build());
|
||||
Helper priorityHelper0 = Iterables.getOnlyElement(fooHelpers); // priority p0
|
||||
priorityHelper0.refreshNameResolution();
|
||||
verify(helper, never()).refreshNameResolution();
|
||||
|
||||
// Simulate fallback to priority p1.
|
||||
priorityHelper0.updateBalancingState(TRANSIENT_FAILURE, new ErrorPicker(Status.UNAVAILABLE));
|
||||
assertThat(fooHelpers).hasSize(2);
|
||||
Helper priorityHelper1 = Iterables.getLast(fooHelpers);
|
||||
priorityHelper1.refreshNameResolution();
|
||||
verify(helper).refreshNameResolution();
|
||||
}
|
||||
|
||||
private void assertLatestConnectivityState(ConnectivityState expectedState) {
|
||||
verify(helper, atLeastOnce())
|
||||
.updateBalancingState(connectivityStateCaptor.capture(), pickerCaptor.capture());
|
||||
|
|
|
|||
Loading…
Reference in New Issue