mirror of https://github.com/grpc/grpc-java.git
Xds: Aggregate cluster fixes (A75) (#12186)
Instead of representing an aggregate cluster as a single cluster whose priorities come from different underlying clusters, represent an aggregate cluster as an instance of a priority LB policy where each child is a cds LB policy for the underlying cluster.
This commit is contained in:
parent
c3ef1ab034
commit
7e982e48a1
|
|
@ -18,10 +18,10 @@ package io.grpc.xds;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static io.grpc.ConnectivityState.TRANSIENT_FAILURE;
|
import static io.grpc.ConnectivityState.TRANSIENT_FAILURE;
|
||||||
|
import static io.grpc.xds.XdsLbPolicies.CDS_POLICY_NAME;
|
||||||
import static io.grpc.xds.XdsLbPolicies.CLUSTER_RESOLVER_POLICY_NAME;
|
import static io.grpc.xds.XdsLbPolicies.CLUSTER_RESOLVER_POLICY_NAME;
|
||||||
|
import static io.grpc.xds.XdsLbPolicies.PRIORITY_POLICY_NAME;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.errorprone.annotations.CheckReturnValue;
|
import com.google.errorprone.annotations.CheckReturnValue;
|
||||||
import io.grpc.InternalLogId;
|
import io.grpc.InternalLogId;
|
||||||
import io.grpc.LoadBalancer;
|
import io.grpc.LoadBalancer;
|
||||||
|
|
@ -33,6 +33,7 @@ import io.grpc.util.GracefulSwitchLoadBalancer;
|
||||||
import io.grpc.xds.CdsLoadBalancerProvider.CdsConfig;
|
import io.grpc.xds.CdsLoadBalancerProvider.CdsConfig;
|
||||||
import io.grpc.xds.ClusterResolverLoadBalancerProvider.ClusterResolverConfig;
|
import io.grpc.xds.ClusterResolverLoadBalancerProvider.ClusterResolverConfig;
|
||||||
import io.grpc.xds.ClusterResolverLoadBalancerProvider.ClusterResolverConfig.DiscoveryMechanism;
|
import io.grpc.xds.ClusterResolverLoadBalancerProvider.ClusterResolverConfig.DiscoveryMechanism;
|
||||||
|
import io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig.PriorityChildConfig;
|
||||||
import io.grpc.xds.XdsClusterResource.CdsUpdate;
|
import io.grpc.xds.XdsClusterResource.CdsUpdate;
|
||||||
import io.grpc.xds.XdsClusterResource.CdsUpdate.ClusterType;
|
import io.grpc.xds.XdsClusterResource.CdsUpdate.ClusterType;
|
||||||
import io.grpc.xds.XdsConfig.Subscription;
|
import io.grpc.xds.XdsConfig.Subscription;
|
||||||
|
|
@ -41,10 +42,11 @@ import io.grpc.xds.XdsConfig.XdsClusterConfig.AggregateConfig;
|
||||||
import io.grpc.xds.XdsConfig.XdsClusterConfig.EndpointConfig;
|
import io.grpc.xds.XdsConfig.XdsClusterConfig.EndpointConfig;
|
||||||
import io.grpc.xds.client.XdsLogger;
|
import io.grpc.xds.client.XdsLogger;
|
||||||
import io.grpc.xds.client.XdsLogger.XdsLogLevel;
|
import io.grpc.xds.client.XdsLogger.XdsLogLevel;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load balancer for cds_experimental LB policy. One instance per top-level cluster.
|
* Load balancer for cds_experimental LB policy. One instance per top-level cluster.
|
||||||
|
|
@ -55,19 +57,15 @@ final class CdsLoadBalancer2 extends LoadBalancer {
|
||||||
private final XdsLogger logger;
|
private final XdsLogger logger;
|
||||||
private final Helper helper;
|
private final Helper helper;
|
||||||
private final LoadBalancerRegistry lbRegistry;
|
private final LoadBalancerRegistry lbRegistry;
|
||||||
|
private GracefulSwitchLoadBalancer delegate;
|
||||||
// Following fields are effectively final.
|
// Following fields are effectively final.
|
||||||
private String clusterName;
|
private String clusterName;
|
||||||
private Subscription clusterSubscription;
|
private Subscription clusterSubscription;
|
||||||
private LoadBalancer childLb;
|
|
||||||
|
|
||||||
CdsLoadBalancer2(Helper helper) {
|
|
||||||
this(helper, LoadBalancerRegistry.getDefaultRegistry());
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
CdsLoadBalancer2(Helper helper, LoadBalancerRegistry lbRegistry) {
|
CdsLoadBalancer2(Helper helper, LoadBalancerRegistry lbRegistry) {
|
||||||
this.helper = checkNotNull(helper, "helper");
|
this.helper = checkNotNull(helper, "helper");
|
||||||
this.lbRegistry = checkNotNull(lbRegistry, "lbRegistry");
|
this.lbRegistry = checkNotNull(lbRegistry, "lbRegistry");
|
||||||
|
this.delegate = new GracefulSwitchLoadBalancer(helper);
|
||||||
logger = XdsLogger.withLogId(InternalLogId.allocate("cds-lb", helper.getAuthority()));
|
logger = XdsLogger.withLogId(InternalLogId.allocate("cds-lb", helper.getAuthority()));
|
||||||
logger.log(XdsLogLevel.INFO, "Created");
|
logger.log(XdsLogLevel.INFO, "Created");
|
||||||
}
|
}
|
||||||
|
|
@ -91,7 +89,7 @@ final class CdsLoadBalancer2 extends LoadBalancer {
|
||||||
if (clusterSubscription == null) {
|
if (clusterSubscription == null) {
|
||||||
// Should be impossible, because XdsDependencyManager wouldn't have generated this
|
// Should be impossible, because XdsDependencyManager wouldn't have generated this
|
||||||
return fail(Status.INTERNAL.withDescription(
|
return fail(Status.INTERNAL.withDescription(
|
||||||
errorPrefix() + "Unable to find non-dynamic root cluster"));
|
errorPrefix() + "Unable to find non-dynamic cluster"));
|
||||||
}
|
}
|
||||||
// The dynamic cluster must not have loaded yet
|
// The dynamic cluster must not have loaded yet
|
||||||
return Status.OK;
|
return Status.OK;
|
||||||
|
|
@ -100,42 +98,25 @@ final class CdsLoadBalancer2 extends LoadBalancer {
|
||||||
return fail(clusterConfigOr.getStatus());
|
return fail(clusterConfigOr.getStatus());
|
||||||
}
|
}
|
||||||
XdsClusterConfig clusterConfig = clusterConfigOr.getValue();
|
XdsClusterConfig clusterConfig = clusterConfigOr.getValue();
|
||||||
List<String> leafNames;
|
|
||||||
if (clusterConfig.getChildren() instanceof AggregateConfig) {
|
|
||||||
leafNames = ((AggregateConfig) clusterConfig.getChildren()).getLeafNames();
|
|
||||||
} else if (clusterConfig.getChildren() instanceof EndpointConfig) {
|
|
||||||
leafNames = ImmutableList.of(clusterName);
|
|
||||||
} else {
|
|
||||||
return fail(Status.INTERNAL.withDescription(
|
|
||||||
errorPrefix() + "Unexpected cluster children type: "
|
|
||||||
+ clusterConfig.getChildren().getClass()));
|
|
||||||
}
|
|
||||||
if (leafNames.isEmpty()) {
|
|
||||||
// Should be impossible, because XdsClusterResource validated this
|
|
||||||
return fail(Status.UNAVAILABLE.withDescription(
|
|
||||||
errorPrefix() + "Zero leaf clusters for root cluster " + clusterName));
|
|
||||||
}
|
|
||||||
|
|
||||||
Status noneFoundError = Status.INTERNAL
|
NameResolver.ConfigOrError configOrError;
|
||||||
.withDescription(errorPrefix() + "No leaves and no error; this is a bug");
|
Object gracefulConfig;
|
||||||
List<DiscoveryMechanism> instances = new ArrayList<>();
|
if (clusterConfig.getChildren() instanceof EndpointConfig) {
|
||||||
for (String leafName : leafNames) {
|
// The LB policy config is provided in service_config.proto/JSON format.
|
||||||
StatusOr<XdsClusterConfig> leafConfigOr = xdsConfig.getClusters().get(leafName);
|
configOrError =
|
||||||
if (!leafConfigOr.hasValue()) {
|
GracefulSwitchLoadBalancer.parseLoadBalancingPolicyConfig(
|
||||||
noneFoundError = leafConfigOr.getStatus();
|
Arrays.asList(clusterConfig.getClusterResource().lbPolicyConfig()),
|
||||||
continue;
|
lbRegistry);
|
||||||
|
if (configOrError.getError() != null) {
|
||||||
|
// Should be impossible, because XdsClusterResource validated this
|
||||||
|
return fail(Status.INTERNAL.withDescription(
|
||||||
|
errorPrefix() + "Unable to parse the LB config: " + configOrError.getError()));
|
||||||
}
|
}
|
||||||
if (!(leafConfigOr.getValue().getChildren() instanceof EndpointConfig)) {
|
CdsUpdate result = clusterConfig.getClusterResource();
|
||||||
noneFoundError = Status.INTERNAL.withDescription(
|
|
||||||
errorPrefix() + "Unexpected child " + leafName + " cluster children type: "
|
|
||||||
+ leafConfigOr.getValue().getChildren().getClass());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
CdsUpdate result = leafConfigOr.getValue().getClusterResource();
|
|
||||||
DiscoveryMechanism instance;
|
DiscoveryMechanism instance;
|
||||||
if (result.clusterType() == ClusterType.EDS) {
|
if (result.clusterType() == ClusterType.EDS) {
|
||||||
instance = DiscoveryMechanism.forEds(
|
instance = DiscoveryMechanism.forEds(
|
||||||
leafName,
|
clusterName,
|
||||||
result.edsServiceName(),
|
result.edsServiceName(),
|
||||||
result.lrsServerInfo(),
|
result.lrsServerInfo(),
|
||||||
result.maxConcurrentRequests(),
|
result.maxConcurrentRequests(),
|
||||||
|
|
@ -144,45 +125,49 @@ final class CdsLoadBalancer2 extends LoadBalancer {
|
||||||
result.outlierDetection());
|
result.outlierDetection());
|
||||||
} else {
|
} else {
|
||||||
instance = DiscoveryMechanism.forLogicalDns(
|
instance = DiscoveryMechanism.forLogicalDns(
|
||||||
leafName,
|
clusterName,
|
||||||
result.dnsHostName(),
|
result.dnsHostName(),
|
||||||
result.lrsServerInfo(),
|
result.lrsServerInfo(),
|
||||||
result.maxConcurrentRequests(),
|
result.maxConcurrentRequests(),
|
||||||
result.upstreamTlsContext(),
|
result.upstreamTlsContext(),
|
||||||
result.filterMetadata());
|
result.filterMetadata());
|
||||||
}
|
}
|
||||||
instances.add(instance);
|
gracefulConfig = GracefulSwitchLoadBalancer.createLoadBalancingPolicyConfig(
|
||||||
}
|
lbRegistry.getProvider(CLUSTER_RESOLVER_POLICY_NAME),
|
||||||
if (instances.isEmpty()) {
|
new ClusterResolverConfig(
|
||||||
return fail(noneFoundError);
|
instance,
|
||||||
}
|
configOrError.getConfig(),
|
||||||
|
clusterConfig.getClusterResource().isHttp11ProxyAvailable()));
|
||||||
// The LB policy config is provided in service_config.proto/JSON format.
|
} else if (clusterConfig.getChildren() instanceof AggregateConfig) {
|
||||||
NameResolver.ConfigOrError configOrError =
|
Map<String, PriorityChildConfig> priorityChildConfigs = new HashMap<>();
|
||||||
GracefulSwitchLoadBalancer.parseLoadBalancingPolicyConfig(
|
List<String> leafClusters = ((AggregateConfig) clusterConfig.getChildren()).getLeafNames();
|
||||||
Arrays.asList(clusterConfig.getClusterResource().lbPolicyConfig()), lbRegistry);
|
for (String childCluster: leafClusters) {
|
||||||
if (configOrError.getError() != null) {
|
priorityChildConfigs.put(childCluster,
|
||||||
// Should be impossible, because XdsClusterResource validated this
|
new PriorityChildConfig(
|
||||||
|
GracefulSwitchLoadBalancer.createLoadBalancingPolicyConfig(
|
||||||
|
lbRegistry.getProvider(CDS_POLICY_NAME),
|
||||||
|
new CdsConfig(childCluster)),
|
||||||
|
false));
|
||||||
|
}
|
||||||
|
gracefulConfig = GracefulSwitchLoadBalancer.createLoadBalancingPolicyConfig(
|
||||||
|
lbRegistry.getProvider(PRIORITY_POLICY_NAME),
|
||||||
|
new PriorityLoadBalancerProvider.PriorityLbConfig(
|
||||||
|
Collections.unmodifiableMap(priorityChildConfigs), leafClusters));
|
||||||
|
} else {
|
||||||
return fail(Status.INTERNAL.withDescription(
|
return fail(Status.INTERNAL.withDescription(
|
||||||
errorPrefix() + "Unable to parse the LB config: " + configOrError.getError()));
|
errorPrefix() + "Unexpected cluster children type: "
|
||||||
|
+ clusterConfig.getChildren().getClass()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
return delegate.acceptResolvedAddresses(
|
||||||
Collections.unmodifiableList(instances),
|
resolvedAddresses.toBuilder().setLoadBalancingPolicyConfig(gracefulConfig).build());
|
||||||
configOrError.getConfig(),
|
|
||||||
clusterConfig.getClusterResource().isHttp11ProxyAvailable());
|
|
||||||
if (childLb == null) {
|
|
||||||
childLb = lbRegistry.getProvider(CLUSTER_RESOLVER_POLICY_NAME).newLoadBalancer(helper);
|
|
||||||
}
|
|
||||||
return childLb.acceptResolvedAddresses(
|
|
||||||
resolvedAddresses.toBuilder().setLoadBalancingPolicyConfig(config).build());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleNameResolutionError(Status error) {
|
public void handleNameResolutionError(Status error) {
|
||||||
logger.log(XdsLogLevel.WARNING, "Received name resolution error: {0}", error);
|
logger.log(XdsLogLevel.WARNING, "Received name resolution error: {0}", error);
|
||||||
if (childLb != null) {
|
if (delegate != null) {
|
||||||
childLb.handleNameResolutionError(error);
|
delegate.handleNameResolutionError(error);
|
||||||
} else {
|
} else {
|
||||||
helper.updateBalancingState(
|
helper.updateBalancingState(
|
||||||
TRANSIENT_FAILURE, new FixedResultPicker(PickResult.withError(error)));
|
TRANSIENT_FAILURE, new FixedResultPicker(PickResult.withError(error)));
|
||||||
|
|
@ -192,10 +177,8 @@ final class CdsLoadBalancer2 extends LoadBalancer {
|
||||||
@Override
|
@Override
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
logger.log(XdsLogLevel.INFO, "Shutdown");
|
logger.log(XdsLogLevel.INFO, "Shutdown");
|
||||||
if (childLb != null) {
|
delegate.shutdown();
|
||||||
childLb.shutdown();
|
delegate = new GracefulSwitchLoadBalancer(helper);
|
||||||
childLb = null;
|
|
||||||
}
|
|
||||||
if (clusterSubscription != null) {
|
if (clusterSubscription != null) {
|
||||||
clusterSubscription.close();
|
clusterSubscription.close();
|
||||||
clusterSubscription = null;
|
clusterSubscription = null;
|
||||||
|
|
@ -204,10 +187,7 @@ final class CdsLoadBalancer2 extends LoadBalancer {
|
||||||
|
|
||||||
@CheckReturnValue // don't forget to return up the stack after the fail call
|
@CheckReturnValue // don't forget to return up the stack after the fail call
|
||||||
private Status fail(Status error) {
|
private Status fail(Status error) {
|
||||||
if (childLb != null) {
|
delegate.shutdown();
|
||||||
childLb.shutdown();
|
|
||||||
childLb = null;
|
|
||||||
}
|
|
||||||
helper.updateBalancingState(
|
helper.updateBalancingState(
|
||||||
TRANSIENT_FAILURE, new FixedResultPicker(PickResult.withError(error)));
|
TRANSIENT_FAILURE, new FixedResultPicker(PickResult.withError(error)));
|
||||||
return Status.OK; // XdsNameResolver isn't a polling NR, so this value doesn't matter
|
return Status.OK; // XdsNameResolver isn't a polling NR, so this value doesn't matter
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import io.grpc.Internal;
|
||||||
import io.grpc.LoadBalancer;
|
import io.grpc.LoadBalancer;
|
||||||
import io.grpc.LoadBalancer.Helper;
|
import io.grpc.LoadBalancer.Helper;
|
||||||
import io.grpc.LoadBalancerProvider;
|
import io.grpc.LoadBalancerProvider;
|
||||||
|
import io.grpc.LoadBalancerRegistry;
|
||||||
import io.grpc.NameResolver.ConfigOrError;
|
import io.grpc.NameResolver.ConfigOrError;
|
||||||
import io.grpc.Status;
|
import io.grpc.Status;
|
||||||
import io.grpc.internal.JsonUtil;
|
import io.grpc.internal.JsonUtil;
|
||||||
|
|
@ -51,9 +52,24 @@ public class CdsLoadBalancerProvider extends LoadBalancerProvider {
|
||||||
return XdsLbPolicies.CDS_POLICY_NAME;
|
return XdsLbPolicies.CDS_POLICY_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final LoadBalancerRegistry loadBalancerRegistry;
|
||||||
|
|
||||||
|
public CdsLoadBalancerProvider() {
|
||||||
|
this.loadBalancerRegistry = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CdsLoadBalancerProvider(LoadBalancerRegistry loadBalancerRegistry) {
|
||||||
|
this.loadBalancerRegistry = loadBalancerRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LoadBalancer newLoadBalancer(Helper helper) {
|
public LoadBalancer newLoadBalancer(Helper helper) {
|
||||||
return new CdsLoadBalancer2(helper);
|
LoadBalancerRegistry loadBalancerRegistry = this.loadBalancerRegistry;
|
||||||
|
if (loadBalancerRegistry == null) {
|
||||||
|
loadBalancerRegistry = LoadBalancerRegistry.getDefaultRegistry();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CdsLoadBalancer2(helper, loadBalancerRegistry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -168,8 +168,8 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
|
||||||
*/
|
*/
|
||||||
private final class ClusterResolverLbState extends LoadBalancer {
|
private final class ClusterResolverLbState extends LoadBalancer {
|
||||||
private final Helper helper;
|
private final Helper helper;
|
||||||
private final List<String> clusters = new ArrayList<>();
|
private ClusterState clusterState;
|
||||||
private final Map<String, ClusterState> clusterStates = new HashMap<>();
|
private String cluster;
|
||||||
private Object endpointLbConfig;
|
private Object endpointLbConfig;
|
||||||
private ResolvedAddresses resolvedAddresses;
|
private ResolvedAddresses resolvedAddresses;
|
||||||
private LoadBalancer childLb;
|
private LoadBalancer childLb;
|
||||||
|
|
@ -185,21 +185,18 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
|
||||||
ClusterResolverConfig config =
|
ClusterResolverConfig config =
|
||||||
(ClusterResolverConfig) resolvedAddresses.getLoadBalancingPolicyConfig();
|
(ClusterResolverConfig) resolvedAddresses.getLoadBalancingPolicyConfig();
|
||||||
endpointLbConfig = config.lbConfig;
|
endpointLbConfig = config.lbConfig;
|
||||||
for (DiscoveryMechanism instance : config.discoveryMechanisms) {
|
DiscoveryMechanism instance = config.discoveryMechanism;
|
||||||
clusters.add(instance.cluster);
|
cluster = instance.cluster;
|
||||||
ClusterState state;
|
if (instance.type == DiscoveryMechanism.Type.EDS) {
|
||||||
if (instance.type == DiscoveryMechanism.Type.EDS) {
|
clusterState = new EdsClusterState(instance.cluster, instance.edsServiceName,
|
||||||
state = new EdsClusterState(instance.cluster, instance.edsServiceName,
|
instance.lrsServerInfo, instance.maxConcurrentRequests, instance.tlsContext,
|
||||||
instance.lrsServerInfo, instance.maxConcurrentRequests, instance.tlsContext,
|
instance.filterMetadata, instance.outlierDetection);
|
||||||
instance.filterMetadata, instance.outlierDetection);
|
} else { // logical DNS
|
||||||
} else { // logical DNS
|
clusterState = new LogicalDnsClusterState(instance.cluster, instance.dnsHostName,
|
||||||
state = new LogicalDnsClusterState(instance.cluster, instance.dnsHostName,
|
instance.lrsServerInfo, instance.maxConcurrentRequests, instance.tlsContext,
|
||||||
instance.lrsServerInfo, instance.maxConcurrentRequests, instance.tlsContext,
|
instance.filterMetadata);
|
||||||
instance.filterMetadata);
|
|
||||||
}
|
|
||||||
clusterStates.put(instance.cluster, state);
|
|
||||||
state.start();
|
|
||||||
}
|
}
|
||||||
|
clusterState.start();
|
||||||
return Status.OK;
|
return Status.OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,9 +212,7 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
for (ClusterState state : clusterStates.values()) {
|
clusterState.shutdown();
|
||||||
state.shutdown();
|
|
||||||
}
|
|
||||||
if (childLb != null) {
|
if (childLb != null) {
|
||||||
childLb.shutdown();
|
childLb.shutdown();
|
||||||
}
|
}
|
||||||
|
|
@ -229,24 +224,21 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
|
||||||
List<String> priorities = new ArrayList<>(); // totally ordered priority list
|
List<String> priorities = new ArrayList<>(); // totally ordered priority list
|
||||||
|
|
||||||
Status endpointNotFound = Status.OK;
|
Status endpointNotFound = Status.OK;
|
||||||
for (String cluster : clusters) {
|
// Propagate endpoints to the child LB policy only after all clusters have been resolved.
|
||||||
ClusterState state = clusterStates.get(cluster);
|
if (!clusterState.resolved && clusterState.status.isOk()) {
|
||||||
// Propagate endpoints to the child LB policy only after all clusters have been resolved.
|
return;
|
||||||
if (!state.resolved && state.status.isOk()) {
|
}
|
||||||
return;
|
if (clusterState.result != null) {
|
||||||
}
|
addresses.addAll(clusterState.result.addresses);
|
||||||
if (state.result != null) {
|
priorityChildConfigs.putAll(clusterState.result.priorityChildConfigs);
|
||||||
addresses.addAll(state.result.addresses);
|
priorities.addAll(clusterState.result.priorities);
|
||||||
priorityChildConfigs.putAll(state.result.priorityChildConfigs);
|
} else {
|
||||||
priorities.addAll(state.result.priorities);
|
endpointNotFound = clusterState.status;
|
||||||
} else {
|
|
||||||
endpointNotFound = state.status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (addresses.isEmpty()) {
|
if (addresses.isEmpty()) {
|
||||||
if (endpointNotFound.isOk()) {
|
if (endpointNotFound.isOk()) {
|
||||||
endpointNotFound = Status.UNAVAILABLE.withDescription(
|
endpointNotFound = Status.UNAVAILABLE.withDescription(
|
||||||
"No usable endpoint from cluster(s): " + clusters);
|
"No usable endpoint from cluster: " + cluster);
|
||||||
} else {
|
} else {
|
||||||
endpointNotFound =
|
endpointNotFound =
|
||||||
Status.UNAVAILABLE.withCause(endpointNotFound.getCause())
|
Status.UNAVAILABLE.withCause(endpointNotFound.getCause())
|
||||||
|
|
@ -274,22 +266,12 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleEndpointResolutionError() {
|
private void handleEndpointResolutionError() {
|
||||||
boolean allInError = true;
|
if (!clusterState.status.isOk()) {
|
||||||
Status error = null;
|
|
||||||
for (String cluster : clusters) {
|
|
||||||
ClusterState state = clusterStates.get(cluster);
|
|
||||||
if (state.status.isOk()) {
|
|
||||||
allInError = false;
|
|
||||||
} else {
|
|
||||||
error = state.status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (allInError) {
|
|
||||||
if (childLb != null) {
|
if (childLb != null) {
|
||||||
childLb.handleNameResolutionError(error);
|
childLb.handleNameResolutionError(clusterState.status);
|
||||||
} else {
|
} else {
|
||||||
helper.updateBalancingState(
|
helper.updateBalancingState(
|
||||||
TRANSIENT_FAILURE, new FixedResultPicker(PickResult.withError(error)));
|
TRANSIENT_FAILURE, new FixedResultPicker(PickResult.withError(clusterState.status)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -306,10 +288,8 @@ final class ClusterResolverLoadBalancer extends LoadBalancer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refreshNameResolution() {
|
public void refreshNameResolution() {
|
||||||
for (ClusterState state : clusterStates.values()) {
|
if (clusterState instanceof LogicalDnsClusterState) {
|
||||||
if (state instanceof LogicalDnsClusterState) {
|
((LogicalDnsClusterState) clusterState).refresh();
|
||||||
((LogicalDnsClusterState) state).refresh();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ import io.grpc.Status;
|
||||||
import io.grpc.xds.EnvoyServerProtoData.OutlierDetection;
|
import io.grpc.xds.EnvoyServerProtoData.OutlierDetection;
|
||||||
import io.grpc.xds.EnvoyServerProtoData.UpstreamTlsContext;
|
import io.grpc.xds.EnvoyServerProtoData.UpstreamTlsContext;
|
||||||
import io.grpc.xds.client.Bootstrapper.ServerInfo;
|
import io.grpc.xds.client.Bootstrapper.ServerInfo;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
@ -70,15 +69,15 @@ public final class ClusterResolverLoadBalancerProvider extends LoadBalancerProvi
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class ClusterResolverConfig {
|
static final class ClusterResolverConfig {
|
||||||
// Ordered list of clusters to be resolved.
|
// Cluster to be resolved.
|
||||||
final List<DiscoveryMechanism> discoveryMechanisms;
|
final DiscoveryMechanism discoveryMechanism;
|
||||||
// GracefulSwitch configuration
|
// GracefulSwitch configuration
|
||||||
final Object lbConfig;
|
final Object lbConfig;
|
||||||
private final boolean isHttp11ProxyAvailable;
|
private final boolean isHttp11ProxyAvailable;
|
||||||
|
|
||||||
ClusterResolverConfig(List<DiscoveryMechanism> discoveryMechanisms, Object lbConfig,
|
ClusterResolverConfig(DiscoveryMechanism discoveryMechanism, Object lbConfig,
|
||||||
boolean isHttp11ProxyAvailable) {
|
boolean isHttp11ProxyAvailable) {
|
||||||
this.discoveryMechanisms = checkNotNull(discoveryMechanisms, "discoveryMechanisms");
|
this.discoveryMechanism = checkNotNull(discoveryMechanism, "discoveryMechanism");
|
||||||
this.lbConfig = checkNotNull(lbConfig, "lbConfig");
|
this.lbConfig = checkNotNull(lbConfig, "lbConfig");
|
||||||
this.isHttp11ProxyAvailable = isHttp11ProxyAvailable;
|
this.isHttp11ProxyAvailable = isHttp11ProxyAvailable;
|
||||||
}
|
}
|
||||||
|
|
@ -89,7 +88,7 @@ public final class ClusterResolverLoadBalancerProvider extends LoadBalancerProvi
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(discoveryMechanisms, lbConfig, isHttp11ProxyAvailable);
|
return Objects.hash(discoveryMechanism, lbConfig, isHttp11ProxyAvailable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -101,7 +100,7 @@ public final class ClusterResolverLoadBalancerProvider extends LoadBalancerProvi
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ClusterResolverConfig that = (ClusterResolverConfig) o;
|
ClusterResolverConfig that = (ClusterResolverConfig) o;
|
||||||
return discoveryMechanisms.equals(that.discoveryMechanisms)
|
return discoveryMechanism.equals(that.discoveryMechanism)
|
||||||
&& lbConfig.equals(that.lbConfig)
|
&& lbConfig.equals(that.lbConfig)
|
||||||
&& isHttp11ProxyAvailable == that.isHttp11ProxyAvailable;
|
&& isHttp11ProxyAvailable == that.isHttp11ProxyAvailable;
|
||||||
}
|
}
|
||||||
|
|
@ -109,7 +108,7 @@ public final class ClusterResolverLoadBalancerProvider extends LoadBalancerProvi
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return MoreObjects.toStringHelper(this)
|
return MoreObjects.toStringHelper(this)
|
||||||
.add("discoveryMechanisms", discoveryMechanisms)
|
.add("discoveryMechanism", discoveryMechanism)
|
||||||
.add("lbConfig", lbConfig)
|
.add("lbConfig", lbConfig)
|
||||||
.add("isHttp11ProxyAvailable", isHttp11ProxyAvailable)
|
.add("isHttp11ProxyAvailable", isHttp11ProxyAvailable)
|
||||||
.toString();
|
.toString();
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package io.grpc.xds;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static io.grpc.xds.XdsLbPolicies.CLUSTER_RESOLVER_POLICY_NAME;
|
import static io.grpc.xds.XdsLbPolicies.CLUSTER_RESOLVER_POLICY_NAME;
|
||||||
|
import static io.grpc.xds.XdsLbPolicies.PRIORITY_POLICY_NAME;
|
||||||
import static io.grpc.xds.XdsTestControlPlaneService.ADS_TYPE_URL_CDS;
|
import static io.grpc.xds.XdsTestControlPlaneService.ADS_TYPE_URL_CDS;
|
||||||
import static io.grpc.xds.XdsTestControlPlaneService.ADS_TYPE_URL_EDS;
|
import static io.grpc.xds.XdsTestControlPlaneService.ADS_TYPE_URL_EDS;
|
||||||
import static io.grpc.xds.XdsTestControlPlaneService.ADS_TYPE_URL_LDS;
|
import static io.grpc.xds.XdsTestControlPlaneService.ADS_TYPE_URL_LDS;
|
||||||
|
|
@ -27,6 +28,7 @@ import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import com.github.xds.type.v3.TypedStruct;
|
import com.github.xds.type.v3.TypedStruct;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
@ -157,7 +159,9 @@ public class CdsLoadBalancer2Test {
|
||||||
new LeastRequestLoadBalancerProvider()));
|
new LeastRequestLoadBalancerProvider()));
|
||||||
lbRegistry.register(new FakeLoadBalancerProvider("wrr_locality_experimental",
|
lbRegistry.register(new FakeLoadBalancerProvider("wrr_locality_experimental",
|
||||||
new WrrLocalityLoadBalancerProvider()));
|
new WrrLocalityLoadBalancerProvider()));
|
||||||
loadBalancer = new CdsLoadBalancer2(helper, lbRegistry);
|
CdsLoadBalancerProvider cdsLoadBalancerProvider = new CdsLoadBalancerProvider(lbRegistry);
|
||||||
|
lbRegistry.register(cdsLoadBalancerProvider);
|
||||||
|
loadBalancer = (CdsLoadBalancer2) cdsLoadBalancerProvider.newLoadBalancer(helper);
|
||||||
|
|
||||||
cleanupRule.register(InProcessServerBuilder
|
cleanupRule.register(InProcessServerBuilder
|
||||||
.forName("control-plane.example.com")
|
.forName("control-plane.example.com")
|
||||||
|
|
@ -169,6 +173,8 @@ public class CdsLoadBalancer2Test {
|
||||||
SynchronizationContext syncContext = new SynchronizationContext((t, e) -> {
|
SynchronizationContext syncContext = new SynchronizationContext((t, e) -> {
|
||||||
throw new AssertionError(e);
|
throw new AssertionError(e);
|
||||||
});
|
});
|
||||||
|
when(helper.getSynchronizationContext()).thenReturn(syncContext);
|
||||||
|
when(helper.getScheduledExecutorService()).thenReturn(fakeClock.getScheduledExecutorService());
|
||||||
|
|
||||||
NameResolver.Args nameResolverArgs = NameResolver.Args.newBuilder()
|
NameResolver.Args nameResolverArgs = NameResolver.Args.newBuilder()
|
||||||
.setDefaultPort(8080)
|
.setDefaultPort(8080)
|
||||||
|
|
@ -246,13 +252,12 @@ public class CdsLoadBalancer2Test {
|
||||||
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
||||||
assertThat(childBalancer.name).isEqualTo(CLUSTER_RESOLVER_POLICY_NAME);
|
assertThat(childBalancer.name).isEqualTo(CLUSTER_RESOLVER_POLICY_NAME);
|
||||||
ClusterResolverConfig childLbConfig = (ClusterResolverConfig) childBalancer.config;
|
ClusterResolverConfig childLbConfig = (ClusterResolverConfig) childBalancer.config;
|
||||||
assertThat(childLbConfig.discoveryMechanisms).isEqualTo(
|
assertThat(childLbConfig.discoveryMechanism).isEqualTo(
|
||||||
Arrays.asList(
|
DiscoveryMechanism.forEds(
|
||||||
DiscoveryMechanism.forEds(
|
CLUSTER, EDS_SERVICE_NAME, lrsServerInfo, 100L, upstreamTlsContext,
|
||||||
CLUSTER, EDS_SERVICE_NAME, lrsServerInfo, 100L, upstreamTlsContext,
|
Collections.emptyMap(), io.grpc.xds.EnvoyServerProtoData.OutlierDetection.create(
|
||||||
Collections.emptyMap(), io.grpc.xds.EnvoyServerProtoData.OutlierDetection.create(
|
null, null, null, null, SuccessRateEjection.create(null, null, null, null),
|
||||||
null, null, null, null, SuccessRateEjection.create(null, null, null, null),
|
FailurePercentageEjection.create(null, null, null, null))));
|
||||||
FailurePercentageEjection.create(null, null, null, null)))));
|
|
||||||
assertThat(
|
assertThat(
|
||||||
GracefulSwitchLoadBalancerAccessor.getChildProvider(childLbConfig.lbConfig).getPolicyName())
|
GracefulSwitchLoadBalancerAccessor.getChildProvider(childLbConfig.lbConfig).getPolicyName())
|
||||||
.isEqualTo("wrr_locality_experimental");
|
.isEqualTo("wrr_locality_experimental");
|
||||||
|
|
@ -296,11 +301,10 @@ public class CdsLoadBalancer2Test {
|
||||||
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
||||||
assertThat(childBalancer.name).isEqualTo(CLUSTER_RESOLVER_POLICY_NAME);
|
assertThat(childBalancer.name).isEqualTo(CLUSTER_RESOLVER_POLICY_NAME);
|
||||||
ClusterResolverConfig childLbConfig = (ClusterResolverConfig) childBalancer.config;
|
ClusterResolverConfig childLbConfig = (ClusterResolverConfig) childBalancer.config;
|
||||||
assertThat(childLbConfig.discoveryMechanisms).isEqualTo(
|
assertThat(childLbConfig.discoveryMechanism).isEqualTo(
|
||||||
Arrays.asList(
|
DiscoveryMechanism.forLogicalDns(
|
||||||
DiscoveryMechanism.forLogicalDns(
|
CLUSTER, "dns.example.com:1111", lrsServerInfo, 100L, upstreamTlsContext,
|
||||||
CLUSTER, "dns.example.com:1111", lrsServerInfo, 100L, upstreamTlsContext,
|
Collections.emptyMap()));
|
||||||
Collections.emptyMap())));
|
|
||||||
assertThat(
|
assertThat(
|
||||||
GracefulSwitchLoadBalancerAccessor.getChildProvider(childLbConfig.lbConfig).getPolicyName())
|
GracefulSwitchLoadBalancerAccessor.getChildProvider(childLbConfig.lbConfig).getPolicyName())
|
||||||
.isEqualTo("wrr_locality_experimental");
|
.isEqualTo("wrr_locality_experimental");
|
||||||
|
|
@ -332,10 +336,9 @@ public class CdsLoadBalancer2Test {
|
||||||
assertThat(childBalancers).hasSize(1);
|
assertThat(childBalancers).hasSize(1);
|
||||||
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
||||||
ClusterResolverConfig childLbConfig = (ClusterResolverConfig) childBalancer.config;
|
ClusterResolverConfig childLbConfig = (ClusterResolverConfig) childBalancer.config;
|
||||||
assertThat(childLbConfig.discoveryMechanisms).isEqualTo(
|
assertThat(childLbConfig.discoveryMechanism).isEqualTo(
|
||||||
Arrays.asList(
|
|
||||||
DiscoveryMechanism.forEds(
|
DiscoveryMechanism.forEds(
|
||||||
CLUSTER, EDS_SERVICE_NAME, null, 100L, null, Collections.emptyMap(), null)));
|
CLUSTER, EDS_SERVICE_NAME, null, 100L, null, Collections.emptyMap(), null));
|
||||||
|
|
||||||
cluster = EDS_CLUSTER.toBuilder()
|
cluster = EDS_CLUSTER.toBuilder()
|
||||||
.setCircuitBreakers(CircuitBreakers.newBuilder()
|
.setCircuitBreakers(CircuitBreakers.newBuilder()
|
||||||
|
|
@ -348,10 +351,9 @@ public class CdsLoadBalancer2Test {
|
||||||
assertThat(childBalancers).hasSize(1);
|
assertThat(childBalancers).hasSize(1);
|
||||||
childBalancer = Iterables.getOnlyElement(childBalancers);
|
childBalancer = Iterables.getOnlyElement(childBalancers);
|
||||||
childLbConfig = (ClusterResolverConfig) childBalancer.config;
|
childLbConfig = (ClusterResolverConfig) childBalancer.config;
|
||||||
assertThat(childLbConfig.discoveryMechanisms).isEqualTo(
|
assertThat(childLbConfig.discoveryMechanism).isEqualTo(
|
||||||
Arrays.asList(
|
|
||||||
DiscoveryMechanism.forEds(
|
DiscoveryMechanism.forEds(
|
||||||
CLUSTER, EDS_SERVICE_NAME, null, 200L, null, Collections.emptyMap(), null)));
|
CLUSTER, EDS_SERVICE_NAME, null, 200L, null, Collections.emptyMap(), null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -363,10 +365,9 @@ public class CdsLoadBalancer2Test {
|
||||||
assertThat(childBalancers).hasSize(1);
|
assertThat(childBalancers).hasSize(1);
|
||||||
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
||||||
ClusterResolverConfig childLbConfig = (ClusterResolverConfig) childBalancer.config;
|
ClusterResolverConfig childLbConfig = (ClusterResolverConfig) childBalancer.config;
|
||||||
assertThat(childLbConfig.discoveryMechanisms).isEqualTo(
|
assertThat(childLbConfig.discoveryMechanism).isEqualTo(
|
||||||
Arrays.asList(
|
|
||||||
DiscoveryMechanism.forEds(
|
DiscoveryMechanism.forEds(
|
||||||
CLUSTER, EDS_SERVICE_NAME, null, null, null, Collections.emptyMap(), null)));
|
CLUSTER, EDS_SERVICE_NAME, null, null, null, Collections.emptyMap(), null));
|
||||||
|
|
||||||
controlPlaneService.setXdsConfig(ADS_TYPE_URL_CDS, ImmutableMap.of());
|
controlPlaneService.setXdsConfig(ADS_TYPE_URL_CDS, ImmutableMap.of());
|
||||||
|
|
||||||
|
|
@ -395,10 +396,9 @@ public class CdsLoadBalancer2Test {
|
||||||
assertThat(childBalancers).hasSize(1);
|
assertThat(childBalancers).hasSize(1);
|
||||||
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
||||||
ClusterResolverConfig childLbConfig = (ClusterResolverConfig) childBalancer.config;
|
ClusterResolverConfig childLbConfig = (ClusterResolverConfig) childBalancer.config;
|
||||||
assertThat(childLbConfig.discoveryMechanisms).isEqualTo(
|
assertThat(childLbConfig.discoveryMechanism).isEqualTo(
|
||||||
Arrays.asList(
|
|
||||||
DiscoveryMechanism.forEds(
|
DiscoveryMechanism.forEds(
|
||||||
clusterName, EDS_SERVICE_NAME, null, null, null, Collections.emptyMap(), null)));
|
clusterName, EDS_SERVICE_NAME, null, null, null, Collections.emptyMap(), null));
|
||||||
|
|
||||||
assertThat(this.lastXdsConfig.getClusters()).containsKey(clusterName);
|
assertThat(this.lastXdsConfig.getClusters()).containsKey(clusterName);
|
||||||
shutdownLoadBalancer();
|
shutdownLoadBalancer();
|
||||||
|
|
@ -406,7 +406,12 @@ public class CdsLoadBalancer2Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void discoverAggregateCluster() {
|
public void discoverAggregateCluster_createsPriorityLbPolicy() {
|
||||||
|
lbRegistry.register(new FakeLoadBalancerProvider(PRIORITY_POLICY_NAME));
|
||||||
|
CdsLoadBalancerProvider cdsLoadBalancerProvider = new CdsLoadBalancerProvider(lbRegistry);
|
||||||
|
lbRegistry.register(cdsLoadBalancerProvider);
|
||||||
|
loadBalancer = (CdsLoadBalancer2) cdsLoadBalancerProvider.newLoadBalancer(helper);
|
||||||
|
|
||||||
String cluster1 = "cluster-01.googleapis.com";
|
String cluster1 = "cluster-01.googleapis.com";
|
||||||
String cluster2 = "cluster-02.googleapis.com";
|
String cluster2 = "cluster-02.googleapis.com";
|
||||||
String cluster3 = "cluster-03.googleapis.com";
|
String cluster3 = "cluster-03.googleapis.com";
|
||||||
|
|
@ -459,20 +464,77 @@ public class CdsLoadBalancer2Test {
|
||||||
verify(helper, never()).updateBalancingState(eq(ConnectivityState.TRANSIENT_FAILURE), any());
|
verify(helper, never()).updateBalancingState(eq(ConnectivityState.TRANSIENT_FAILURE), any());
|
||||||
assertThat(childBalancers).hasSize(1);
|
assertThat(childBalancers).hasSize(1);
|
||||||
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
||||||
assertThat(childBalancer.name).isEqualTo(CLUSTER_RESOLVER_POLICY_NAME);
|
assertThat(childBalancer.name).isEqualTo(PRIORITY_POLICY_NAME);
|
||||||
ClusterResolverConfig childLbConfig = (ClusterResolverConfig) childBalancer.config;
|
PriorityLoadBalancerProvider.PriorityLbConfig childLbConfig =
|
||||||
// Clusters are resolved recursively, later duplicates removed: [cluster3, cluster4, cluster2]
|
(PriorityLoadBalancerProvider.PriorityLbConfig) childBalancer.config;
|
||||||
assertThat(childLbConfig.discoveryMechanisms).isEqualTo(
|
assertThat(childLbConfig.priorities).hasSize(3);
|
||||||
Arrays.asList(
|
assertThat(childLbConfig.priorities.get(0)).isEqualTo(cluster3);
|
||||||
DiscoveryMechanism.forEds(
|
assertThat(childLbConfig.priorities.get(1)).isEqualTo(cluster4);
|
||||||
cluster3, EDS_SERVICE_NAME, null, 100L, null, Collections.emptyMap(), null),
|
assertThat(childLbConfig.priorities.get(2)).isEqualTo(cluster2);
|
||||||
DiscoveryMechanism.forEds(
|
assertThat(childLbConfig.childConfigs).hasSize(3);
|
||||||
cluster4, EDS_SERVICE_NAME, null, null, null, Collections.emptyMap(), null),
|
PriorityLoadBalancerProvider.PriorityLbConfig.PriorityChildConfig childConfig3 =
|
||||||
DiscoveryMechanism.forLogicalDns(
|
childLbConfig.childConfigs.get(cluster3);
|
||||||
cluster2, "dns.example.com:1111", null, null, null, Collections.emptyMap())));
|
|
||||||
assertThat(
|
assertThat(
|
||||||
GracefulSwitchLoadBalancerAccessor.getChildProvider(childLbConfig.lbConfig).getPolicyName())
|
GracefulSwitchLoadBalancerAccessor.getChildProvider(childConfig3.childConfig)
|
||||||
.isEqualTo("ring_hash_experimental"); // dominated by top-level cluster's config
|
.getPolicyName())
|
||||||
|
.isEqualTo("cds_experimental");
|
||||||
|
PriorityLoadBalancerProvider.PriorityLbConfig.PriorityChildConfig childConfig4 =
|
||||||
|
childLbConfig.childConfigs.get(cluster4);
|
||||||
|
assertThat(
|
||||||
|
GracefulSwitchLoadBalancerAccessor.getChildProvider(childConfig4.childConfig)
|
||||||
|
.getPolicyName())
|
||||||
|
.isEqualTo("cds_experimental");
|
||||||
|
PriorityLoadBalancerProvider.PriorityLbConfig.PriorityChildConfig childConfig2 =
|
||||||
|
childLbConfig.childConfigs.get(cluster2);
|
||||||
|
assertThat(
|
||||||
|
GracefulSwitchLoadBalancerAccessor.getChildProvider(childConfig2.childConfig)
|
||||||
|
.getPolicyName())
|
||||||
|
.isEqualTo("cds_experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
// Both priorities will get tried using real priority LB policy.
|
||||||
|
public void discoverAggregateCluster_testChildCdsLbPolicyParsing() {
|
||||||
|
lbRegistry.register(new PriorityLoadBalancerProvider());
|
||||||
|
CdsLoadBalancerProvider cdsLoadBalancerProvider = new CdsLoadBalancerProvider(lbRegistry);
|
||||||
|
lbRegistry.register(cdsLoadBalancerProvider);
|
||||||
|
loadBalancer = (CdsLoadBalancer2) cdsLoadBalancerProvider.newLoadBalancer(helper);
|
||||||
|
|
||||||
|
String cluster1 = "cluster-01.googleapis.com";
|
||||||
|
String cluster2 = "cluster-02.googleapis.com";
|
||||||
|
controlPlaneService.setXdsConfig(ADS_TYPE_URL_CDS, ImmutableMap.of(
|
||||||
|
// CLUSTER (aggr.) -> [cluster1 (EDS), cluster2 (EDS)]
|
||||||
|
CLUSTER, Cluster.newBuilder()
|
||||||
|
.setName(CLUSTER)
|
||||||
|
.setClusterType(Cluster.CustomClusterType.newBuilder()
|
||||||
|
.setName("envoy.clusters.aggregate")
|
||||||
|
.setTypedConfig(Any.pack(ClusterConfig.newBuilder()
|
||||||
|
.addClusters(cluster1)
|
||||||
|
.addClusters(cluster2)
|
||||||
|
.build())))
|
||||||
|
.build(),
|
||||||
|
cluster1, EDS_CLUSTER.toBuilder().setName(cluster1).build(),
|
||||||
|
cluster2, EDS_CLUSTER.toBuilder().setName(cluster2).build()));
|
||||||
|
startXdsDepManager();
|
||||||
|
|
||||||
|
verify(helper, never()).updateBalancingState(eq(ConnectivityState.TRANSIENT_FAILURE), any());
|
||||||
|
assertThat(childBalancers).hasSize(2);
|
||||||
|
ClusterResolverConfig cluster1ResolverConfig =
|
||||||
|
(ClusterResolverConfig) childBalancers.get(0).config;
|
||||||
|
assertThat(cluster1ResolverConfig.discoveryMechanism.cluster)
|
||||||
|
.isEqualTo("cluster-01.googleapis.com");
|
||||||
|
assertThat(cluster1ResolverConfig.discoveryMechanism.type)
|
||||||
|
.isEqualTo(DiscoveryMechanism.Type.EDS);
|
||||||
|
assertThat(cluster1ResolverConfig.discoveryMechanism.edsServiceName)
|
||||||
|
.isEqualTo("backend-service-1.googleapis.com");
|
||||||
|
ClusterResolverConfig cluster2ResolverConfig =
|
||||||
|
(ClusterResolverConfig) childBalancers.get(1).config;
|
||||||
|
assertThat(cluster2ResolverConfig.discoveryMechanism.cluster)
|
||||||
|
.isEqualTo("cluster-02.googleapis.com");
|
||||||
|
assertThat(cluster2ResolverConfig.discoveryMechanism.type)
|
||||||
|
.isEqualTo(DiscoveryMechanism.Type.EDS);
|
||||||
|
assertThat(cluster2ResolverConfig.discoveryMechanism.edsServiceName)
|
||||||
|
.isEqualTo("backend-service-1.googleapis.com");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -500,6 +562,11 @@ public class CdsLoadBalancer2Test {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void aggregateCluster_noNonAggregateClusterExits_returnErrorPicker() {
|
public void aggregateCluster_noNonAggregateClusterExits_returnErrorPicker() {
|
||||||
|
lbRegistry.register(new PriorityLoadBalancerProvider());
|
||||||
|
CdsLoadBalancerProvider cdsLoadBalancerProvider = new CdsLoadBalancerProvider(lbRegistry);
|
||||||
|
lbRegistry.register(cdsLoadBalancerProvider);
|
||||||
|
loadBalancer = (CdsLoadBalancer2) cdsLoadBalancerProvider.newLoadBalancer(helper);
|
||||||
|
|
||||||
String cluster1 = "cluster-01.googleapis.com";
|
String cluster1 = "cluster-01.googleapis.com";
|
||||||
controlPlaneService.setXdsConfig(ADS_TYPE_URL_CDS, ImmutableMap.of(
|
controlPlaneService.setXdsConfig(ADS_TYPE_URL_CDS, ImmutableMap.of(
|
||||||
// CLUSTER (aggr.) -> [cluster1 (missing)]
|
// CLUSTER (aggr.) -> [cluster1 (missing)]
|
||||||
|
|
@ -550,8 +617,8 @@ public class CdsLoadBalancer2Test {
|
||||||
loadBalancer.handleNameResolutionError(Status.UNAVAILABLE.withDescription("unreachable"));
|
loadBalancer.handleNameResolutionError(Status.UNAVAILABLE.withDescription("unreachable"));
|
||||||
assertThat(childBalancer.upstreamError.getCode()).isEqualTo(Code.UNAVAILABLE);
|
assertThat(childBalancer.upstreamError.getCode()).isEqualTo(Code.UNAVAILABLE);
|
||||||
assertThat(childBalancer.upstreamError.getDescription()).isEqualTo("unreachable");
|
assertThat(childBalancer.upstreamError.getDescription()).isEqualTo("unreachable");
|
||||||
verify(helper, never()).updateBalancingState(
|
verify(helper).updateBalancingState(
|
||||||
any(ConnectivityState.class), any(SubchannelPicker.class));
|
eq(ConnectivityState.CONNECTING), any(SubchannelPicker.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,7 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
@Test
|
@Test
|
||||||
public void edsClustersWithRingHashEndpointLbPolicy() {
|
public void edsClustersWithRingHashEndpointLbPolicy() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Collections.singletonList(edsDiscoveryMechanism1), ringHash, false);
|
edsDiscoveryMechanism1, ringHash, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
||||||
assertThat(childBalancers).isEmpty();
|
assertThat(childBalancers).isEmpty();
|
||||||
|
|
@ -311,7 +311,7 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
@Test
|
@Test
|
||||||
public void edsClustersWithLeastRequestEndpointLbPolicy() {
|
public void edsClustersWithLeastRequestEndpointLbPolicy() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Collections.singletonList(edsDiscoveryMechanism1), leastRequest, false);
|
edsDiscoveryMechanism1, leastRequest, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
||||||
assertThat(childBalancers).isEmpty();
|
assertThat(childBalancers).isEmpty();
|
||||||
|
|
@ -358,7 +358,7 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
@Test
|
@Test
|
||||||
public void edsClustersEndpointHostname_addedToAddressAttribute() {
|
public void edsClustersEndpointHostname_addedToAddressAttribute() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Collections.singletonList(edsDiscoveryMechanismWithOutlierDetection), leastRequest, false);
|
edsDiscoveryMechanismWithOutlierDetection, leastRequest, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
||||||
assertThat(childBalancers).isEmpty();
|
assertThat(childBalancers).isEmpty();
|
||||||
|
|
@ -385,7 +385,7 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
@Test
|
@Test
|
||||||
public void endpointAddressRewritten_whenProxyMetadataIsInEndpointMetadata() {
|
public void endpointAddressRewritten_whenProxyMetadataIsInEndpointMetadata() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Collections.singletonList(edsDiscoveryMechanismWithOutlierDetection), leastRequest, true);
|
edsDiscoveryMechanismWithOutlierDetection, leastRequest, true);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
||||||
assertThat(childBalancers).isEmpty();
|
assertThat(childBalancers).isEmpty();
|
||||||
|
|
@ -404,7 +404,7 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
LocalityLbEndpoints localityLbEndpoints = LocalityLbEndpoints.create(
|
LocalityLbEndpoints localityLbEndpoints = LocalityLbEndpoints.create(
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
LbEndpoint.create(endpoint, 0 /* loadBalancingWeight */, true,
|
LbEndpoint.create(endpoint, 0 /* loadBalancingWeight */, true,
|
||||||
"hostname1", endpointMetadata)),
|
"hostname1", endpointMetadata)),
|
||||||
100 /* localityWeight */, 1 /* priority */, localityMetadata);
|
100 /* localityWeight */, 1 /* priority */, localityMetadata);
|
||||||
|
|
||||||
xdsClient.deliverClusterLoadAssignment(
|
xdsClient.deliverClusterLoadAssignment(
|
||||||
|
|
@ -432,7 +432,7 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
@Test
|
@Test
|
||||||
public void endpointAddressRewritten_whenProxyMetadataIsInLocalityMetadata() {
|
public void endpointAddressRewritten_whenProxyMetadataIsInLocalityMetadata() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Collections.singletonList(edsDiscoveryMechanismWithOutlierDetection), leastRequest, true);
|
edsDiscoveryMechanismWithOutlierDetection, leastRequest, true);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
||||||
assertThat(childBalancers).isEmpty();
|
assertThat(childBalancers).isEmpty();
|
||||||
|
|
@ -451,7 +451,7 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
LocalityLbEndpoints localityLbEndpoints = LocalityLbEndpoints.create(
|
LocalityLbEndpoints localityLbEndpoints = LocalityLbEndpoints.create(
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
LbEndpoint.create(endpoint, 0 /* loadBalancingWeight */, true,
|
LbEndpoint.create(endpoint, 0 /* loadBalancingWeight */, true,
|
||||||
"hostname2", endpointMetadata)),
|
"hostname2", endpointMetadata)),
|
||||||
100 /* localityWeight */, 1 /* priority */, localityMetadata);
|
100 /* localityWeight */, 1 /* priority */, localityMetadata);
|
||||||
|
|
||||||
xdsClient.deliverClusterLoadAssignment(
|
xdsClient.deliverClusterLoadAssignment(
|
||||||
|
|
@ -479,48 +479,36 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
@Test
|
@Test
|
||||||
public void onlyEdsClusters_receivedEndpoints() {
|
public void onlyEdsClusters_receivedEndpoints() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Arrays.asList(edsDiscoveryMechanism1, edsDiscoveryMechanism2), roundRobin, false);
|
edsDiscoveryMechanism2, roundRobin, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1, EDS_SERVICE_NAME2);
|
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME2);
|
||||||
assertThat(childBalancers).isEmpty();
|
assertThat(childBalancers).isEmpty();
|
||||||
// CLUSTER1 has priority 1 (priority3), which has locality 2, which has endpoint3.
|
// CLUSTER1 has priority 1 (priority3), which has locality 2, which has endpoint3.
|
||||||
// CLUSTER2 has priority 1 (priority1) and 2 (priority2); priority1 has locality1,
|
// CLUSTER2 has priority 1 (priority1) and 2 (priority2); priority1 has locality1,
|
||||||
// which has endpoint1 and endpoint2; priority2 has locality3, which has endpoint4.
|
// which has endpoint1 and endpoint2; priority2 has locality3, which has endpoint4.
|
||||||
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1");
|
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1");
|
||||||
EquivalentAddressGroup endpoint2 = makeAddress("endpoint-addr-2");
|
EquivalentAddressGroup endpoint2 = makeAddress("endpoint-addr-2");
|
||||||
EquivalentAddressGroup endpoint3 = makeAddress("endpoint-addr-3");
|
|
||||||
EquivalentAddressGroup endpoint4 = makeAddress("endpoint-addr-4");
|
EquivalentAddressGroup endpoint4 = makeAddress("endpoint-addr-4");
|
||||||
LocalityLbEndpoints localityLbEndpoints1 =
|
LocalityLbEndpoints localityLbEndpoints1 =
|
||||||
LocalityLbEndpoints.create(
|
LocalityLbEndpoints.create(
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
LbEndpoint.create(endpoint1, 100,
|
LbEndpoint.create(endpoint1, 100,
|
||||||
true, "hostname1", ImmutableMap.of()),
|
true, "hostname1", ImmutableMap.of()),
|
||||||
LbEndpoint.create(endpoint2, 100,
|
LbEndpoint.create(endpoint2, 100,
|
||||||
true, "hostname1", ImmutableMap.of())),
|
true, "hostname1", ImmutableMap.of())),
|
||||||
70 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
70 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
||||||
LocalityLbEndpoints localityLbEndpoints2 =
|
|
||||||
LocalityLbEndpoints.create(
|
|
||||||
Collections.singletonList(LbEndpoint.create(endpoint3, 100, true,
|
|
||||||
"hostname2", ImmutableMap.of())),
|
|
||||||
10 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
|
||||||
LocalityLbEndpoints localityLbEndpoints3 =
|
LocalityLbEndpoints localityLbEndpoints3 =
|
||||||
LocalityLbEndpoints.create(
|
LocalityLbEndpoints.create(
|
||||||
Collections.singletonList(LbEndpoint.create(endpoint4, 100, true,
|
Collections.singletonList(LbEndpoint.create(endpoint4, 100, true,
|
||||||
"hostname3", ImmutableMap.of())),
|
"hostname3", ImmutableMap.of())),
|
||||||
20 /* localityWeight */, 2 /* priority */, ImmutableMap.of());
|
20 /* localityWeight */, 2 /* priority */, ImmutableMap.of());
|
||||||
String priority1 = CLUSTER2 + "[child1]";
|
String priority1 = CLUSTER2 + "[child1]";
|
||||||
String priority2 = CLUSTER2 + "[child2]";
|
String priority2 = CLUSTER2 + "[child2]";
|
||||||
String priority3 = CLUSTER1 + "[child1]";
|
|
||||||
|
|
||||||
// CLUSTER2: locality1 with priority 1 and locality3 with priority 2.
|
// CLUSTER2: locality1 with priority 1 and locality3 with priority 2.
|
||||||
xdsClient.deliverClusterLoadAssignment(
|
xdsClient.deliverClusterLoadAssignment(
|
||||||
EDS_SERVICE_NAME2,
|
EDS_SERVICE_NAME2,
|
||||||
ImmutableMap.of(locality1, localityLbEndpoints1, locality3, localityLbEndpoints3));
|
ImmutableMap.of(locality1, localityLbEndpoints1, locality3, localityLbEndpoints3));
|
||||||
assertThat(childBalancers).isEmpty(); // not created until all clusters resolved
|
|
||||||
|
|
||||||
// CLUSTER1: locality2 with priority 1.
|
|
||||||
xdsClient.deliverClusterLoadAssignment(
|
|
||||||
EDS_SERVICE_NAME1, Collections.singletonMap(locality2, localityLbEndpoints2));
|
|
||||||
|
|
||||||
// Endpoints of all clusters have been resolved.
|
// Endpoints of all clusters have been resolved.
|
||||||
assertThat(childBalancers).hasSize(1);
|
assertThat(childBalancers).hasSize(1);
|
||||||
|
|
@ -528,12 +516,12 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
assertThat(childBalancer.name).isEqualTo(PRIORITY_POLICY_NAME);
|
assertThat(childBalancer.name).isEqualTo(PRIORITY_POLICY_NAME);
|
||||||
PriorityLbConfig priorityLbConfig = (PriorityLbConfig) childBalancer.config;
|
PriorityLbConfig priorityLbConfig = (PriorityLbConfig) childBalancer.config;
|
||||||
assertThat(priorityLbConfig.priorities)
|
assertThat(priorityLbConfig.priorities)
|
||||||
.containsExactly(priority3, priority1, priority2).inOrder();
|
.containsExactly(priority1, priority2).inOrder();
|
||||||
|
|
||||||
PriorityChildConfig priorityChildConfig1 = priorityLbConfig.childConfigs.get(priority1);
|
PriorityChildConfig priorityChildConfig1 = priorityLbConfig.childConfigs.get(priority1);
|
||||||
assertThat(priorityChildConfig1.ignoreReresolution).isTrue();
|
assertThat(priorityChildConfig1.ignoreReresolution).isTrue();
|
||||||
assertThat(GracefulSwitchLoadBalancerAccessor.getChildProvider(priorityChildConfig1.childConfig)
|
assertThat(GracefulSwitchLoadBalancerAccessor.getChildProvider(priorityChildConfig1.childConfig)
|
||||||
.getPolicyName())
|
.getPolicyName())
|
||||||
.isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
.isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
||||||
ClusterImplConfig clusterImplConfig1 = (ClusterImplConfig)
|
ClusterImplConfig clusterImplConfig1 = (ClusterImplConfig)
|
||||||
GracefulSwitchLoadBalancerAccessor.getChildConfig(priorityChildConfig1.childConfig);
|
GracefulSwitchLoadBalancerAccessor.getChildConfig(priorityChildConfig1.childConfig);
|
||||||
|
|
@ -548,7 +536,7 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
PriorityChildConfig priorityChildConfig2 = priorityLbConfig.childConfigs.get(priority2);
|
PriorityChildConfig priorityChildConfig2 = priorityLbConfig.childConfigs.get(priority2);
|
||||||
assertThat(priorityChildConfig2.ignoreReresolution).isTrue();
|
assertThat(priorityChildConfig2.ignoreReresolution).isTrue();
|
||||||
assertThat(GracefulSwitchLoadBalancerAccessor.getChildProvider(priorityChildConfig2.childConfig)
|
assertThat(GracefulSwitchLoadBalancerAccessor.getChildProvider(priorityChildConfig2.childConfig)
|
||||||
.getPolicyName())
|
.getPolicyName())
|
||||||
.isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
.isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
||||||
ClusterImplConfig clusterImplConfig2 = (ClusterImplConfig)
|
ClusterImplConfig clusterImplConfig2 = (ClusterImplConfig)
|
||||||
GracefulSwitchLoadBalancerAccessor.getChildConfig(priorityChildConfig2.childConfig);
|
GracefulSwitchLoadBalancerAccessor.getChildConfig(priorityChildConfig2.childConfig);
|
||||||
|
|
@ -560,15 +548,6 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
GracefulSwitchLoadBalancerAccessor.getChildProvider(wrrLocalityConfig2.childConfig);
|
GracefulSwitchLoadBalancerAccessor.getChildProvider(wrrLocalityConfig2.childConfig);
|
||||||
assertThat(childProvider2.getPolicyName()).isEqualTo("round_robin");
|
assertThat(childProvider2.getPolicyName()).isEqualTo("round_robin");
|
||||||
|
|
||||||
PriorityChildConfig priorityChildConfig3 = priorityLbConfig.childConfigs.get(priority3);
|
|
||||||
assertThat(priorityChildConfig3.ignoreReresolution).isTrue();
|
|
||||||
assertThat(GracefulSwitchLoadBalancerAccessor.getChildProvider(priorityChildConfig3.childConfig)
|
|
||||||
.getPolicyName())
|
|
||||||
.isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
|
||||||
ClusterImplConfig clusterImplConfig3 = (ClusterImplConfig)
|
|
||||||
GracefulSwitchLoadBalancerAccessor.getChildConfig(priorityChildConfig3.childConfig);
|
|
||||||
assertClusterImplConfig(clusterImplConfig3, CLUSTER1, EDS_SERVICE_NAME1, LRS_SERVER_INFO, 100L,
|
|
||||||
tlsContext, Collections.<DropOverload>emptyList(), WRR_LOCALITY_POLICY_NAME);
|
|
||||||
WrrLocalityConfig wrrLocalityConfig3 = (WrrLocalityConfig)
|
WrrLocalityConfig wrrLocalityConfig3 = (WrrLocalityConfig)
|
||||||
GracefulSwitchLoadBalancerAccessor.getChildConfig(clusterImplConfig1.childConfig);
|
GracefulSwitchLoadBalancerAccessor.getChildConfig(clusterImplConfig1.childConfig);
|
||||||
LoadBalancerProvider childProvider3 =
|
LoadBalancerProvider childProvider3 =
|
||||||
|
|
@ -595,7 +574,7 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
private void verifyEdsPriorityNames(List<String> want,
|
private void verifyEdsPriorityNames(List<String> want,
|
||||||
Map<Locality, LocalityLbEndpoints>... updates) {
|
Map<Locality, LocalityLbEndpoints>... updates) {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Arrays.asList(edsDiscoveryMechanism2), roundRobin, false);
|
edsDiscoveryMechanism2, roundRobin, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME2);
|
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME2);
|
||||||
assertThat(childBalancers).isEmpty();
|
assertThat(childBalancers).isEmpty();
|
||||||
|
|
@ -617,7 +596,7 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
public void edsUpdatePriorityName_twoPriorities() {
|
public void edsUpdatePriorityName_twoPriorities() {
|
||||||
verifyEdsPriorityNames(Arrays.asList(CLUSTER2 + "[child1]", CLUSTER2 + "[child2]"),
|
verifyEdsPriorityNames(Arrays.asList(CLUSTER2 + "[child1]", CLUSTER2 + "[child2]"),
|
||||||
ImmutableMap.of(locality1, createEndpoints(1),
|
ImmutableMap.of(locality1, createEndpoints(1),
|
||||||
locality2, createEndpoints(2)
|
locality2, createEndpoints(2)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -653,8 +632,8 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
locality3, createEndpoints(3),
|
locality3, createEndpoints(3),
|
||||||
locality2, createEndpoints(2)),
|
locality2, createEndpoints(2)),
|
||||||
ImmutableMap.of(locality1, createEndpoints(2),
|
ImmutableMap.of(locality1, createEndpoints(2),
|
||||||
locality3, createEndpoints(1),
|
locality3, createEndpoints(1),
|
||||||
locality2, createEndpoints(1)
|
locality2, createEndpoints(1)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -662,76 +641,64 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
return LocalityLbEndpoints.create(
|
return LocalityLbEndpoints.create(
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
LbEndpoint.create(makeAddress("endpoint-addr-1"), 100,
|
LbEndpoint.create(makeAddress("endpoint-addr-1"), 100,
|
||||||
true, "hostname1", ImmutableMap.of()),
|
true, "hostname1", ImmutableMap.of()),
|
||||||
LbEndpoint.create(makeAddress("endpoint-addr-2"), 100,
|
LbEndpoint.create(makeAddress("endpoint-addr-2"), 100,
|
||||||
true, "hostname2", ImmutableMap.of())),
|
true, "hostname2", ImmutableMap.of())),
|
||||||
70 /* localityWeight */, priority /* priority */, ImmutableMap.of());
|
70 /* localityWeight */, priority /* priority */, ImmutableMap.of());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onlyEdsClusters_resourceNeverExist_returnErrorPicker() {
|
public void onlyEdsClusters_resourceNeverExist_returnErrorPicker() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Arrays.asList(edsDiscoveryMechanism1, edsDiscoveryMechanism2), roundRobin, false);
|
edsDiscoveryMechanism1, roundRobin, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1, EDS_SERVICE_NAME2);
|
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
||||||
assertThat(childBalancers).isEmpty();
|
assertThat(childBalancers).isEmpty();
|
||||||
reset(helper);
|
reset(helper);
|
||||||
xdsClient.deliverResourceNotFound(EDS_SERVICE_NAME1);
|
xdsClient.deliverResourceNotFound(EDS_SERVICE_NAME1);
|
||||||
verify(helper, never()).updateBalancingState(
|
|
||||||
any(ConnectivityState.class), any(SubchannelPicker.class)); // wait for CLUSTER2's results
|
|
||||||
|
|
||||||
xdsClient.deliverResourceNotFound(EDS_SERVICE_NAME2);
|
|
||||||
verify(helper).updateBalancingState(
|
verify(helper).updateBalancingState(
|
||||||
eq(ConnectivityState.TRANSIENT_FAILURE), pickerCaptor.capture());
|
eq(ConnectivityState.TRANSIENT_FAILURE), pickerCaptor.capture());
|
||||||
assertPicker(
|
assertPicker(
|
||||||
pickerCaptor.getValue(),
|
pickerCaptor.getValue(),
|
||||||
Status.UNAVAILABLE.withDescription(
|
Status.UNAVAILABLE.withDescription(
|
||||||
"No usable endpoint from cluster(s): " + Arrays.asList(CLUSTER1, CLUSTER2)),
|
"No usable endpoint from cluster: " + CLUSTER1),
|
||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onlyEdsClusters_allResourcesRevoked_shutDownChildLbPolicy() {
|
public void edsCluster_resourcesRevoked_shutDownChildLbPolicy() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Arrays.asList(edsDiscoveryMechanism1, edsDiscoveryMechanism2), roundRobin, false);
|
edsDiscoveryMechanism1, roundRobin, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1, EDS_SERVICE_NAME2);
|
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
||||||
assertThat(childBalancers).isEmpty();
|
assertThat(childBalancers).isEmpty();
|
||||||
reset(helper);
|
reset(helper);
|
||||||
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1");
|
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1");
|
||||||
EquivalentAddressGroup endpoint2 = makeAddress("endpoint-addr-2");
|
|
||||||
LocalityLbEndpoints localityLbEndpoints1 =
|
LocalityLbEndpoints localityLbEndpoints1 =
|
||||||
LocalityLbEndpoints.create(
|
LocalityLbEndpoints.create(
|
||||||
Collections.singletonList(LbEndpoint.create(endpoint1, 100, true,
|
Collections.singletonList(LbEndpoint.create(endpoint1, 100, true,
|
||||||
"hostname1", ImmutableMap.of())),
|
"hostname1", ImmutableMap.of())),
|
||||||
10 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
10 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
||||||
LocalityLbEndpoints localityLbEndpoints2 =
|
|
||||||
LocalityLbEndpoints.create(
|
|
||||||
Collections.singletonList(LbEndpoint.create(endpoint2, 100, true,
|
|
||||||
"hostname2", ImmutableMap.of())),
|
|
||||||
20 /* localityWeight */, 2 /* priority */, ImmutableMap.of());
|
|
||||||
xdsClient.deliverClusterLoadAssignment(
|
xdsClient.deliverClusterLoadAssignment(
|
||||||
EDS_SERVICE_NAME1, Collections.singletonMap(locality1, localityLbEndpoints1));
|
EDS_SERVICE_NAME1, Collections.singletonMap(locality1, localityLbEndpoints1));
|
||||||
xdsClient.deliverClusterLoadAssignment(
|
|
||||||
EDS_SERVICE_NAME2, Collections.singletonMap(locality2, localityLbEndpoints2));
|
|
||||||
assertThat(childBalancers).hasSize(1); // child LB policy created
|
assertThat(childBalancers).hasSize(1); // child LB policy created
|
||||||
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
||||||
assertThat(((PriorityLbConfig) childBalancer.config).priorities).hasSize(2);
|
assertThat(((PriorityLbConfig) childBalancer.config).priorities).hasSize(1);
|
||||||
assertAddressesEqual(Arrays.asList(endpoint1, endpoint2), childBalancer.addresses);
|
assertAddressesEqual(Arrays.asList(endpoint1), childBalancer.addresses);
|
||||||
|
|
||||||
xdsClient.deliverResourceNotFound(EDS_SERVICE_NAME2);
|
|
||||||
xdsClient.deliverResourceNotFound(EDS_SERVICE_NAME1);
|
xdsClient.deliverResourceNotFound(EDS_SERVICE_NAME1);
|
||||||
verify(helper).updateBalancingState(
|
verify(helper).updateBalancingState(
|
||||||
eq(ConnectivityState.TRANSIENT_FAILURE), pickerCaptor.capture());
|
eq(ConnectivityState.TRANSIENT_FAILURE), pickerCaptor.capture());
|
||||||
Status expectedError = Status.UNAVAILABLE.withDescription(
|
Status expectedError = Status.UNAVAILABLE.withDescription(
|
||||||
"No usable endpoint from cluster(s): " + Arrays.asList(CLUSTER1, CLUSTER2));
|
"No usable endpoint from cluster: " + CLUSTER1);
|
||||||
assertPicker(pickerCaptor.getValue(), expectedError, null);
|
assertPicker(pickerCaptor.getValue(), expectedError, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void handleEdsResource_ignoreUnhealthyEndpoints() {
|
public void handleEdsResource_ignoreUnhealthyEndpoints() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Collections.singletonList(edsDiscoveryMechanism1), roundRobin, false);
|
edsDiscoveryMechanism1, roundRobin, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1");
|
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1");
|
||||||
EquivalentAddressGroup endpoint2 = makeAddress("endpoint-addr-2");
|
EquivalentAddressGroup endpoint2 = makeAddress("endpoint-addr-2");
|
||||||
|
|
@ -739,9 +706,9 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
LocalityLbEndpoints.create(
|
LocalityLbEndpoints.create(
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
LbEndpoint.create(endpoint1, 100, false /* isHealthy */,
|
LbEndpoint.create(endpoint1, 100, false /* isHealthy */,
|
||||||
"hostname1", ImmutableMap.of()),
|
"hostname1", ImmutableMap.of()),
|
||||||
LbEndpoint.create(endpoint2, 100, true /* isHealthy */,
|
LbEndpoint.create(endpoint2, 100, true /* isHealthy */,
|
||||||
"hostname2", ImmutableMap.of())),
|
"hostname2", ImmutableMap.of())),
|
||||||
10 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
10 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
||||||
xdsClient.deliverClusterLoadAssignment(
|
xdsClient.deliverClusterLoadAssignment(
|
||||||
EDS_SERVICE_NAME1, Collections.singletonMap(locality1, localityLbEndpoints));
|
EDS_SERVICE_NAME1, Collections.singletonMap(locality1, localityLbEndpoints));
|
||||||
|
|
@ -753,19 +720,19 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
@Test
|
@Test
|
||||||
public void handleEdsResource_ignoreLocalitiesWithNoHealthyEndpoints() {
|
public void handleEdsResource_ignoreLocalitiesWithNoHealthyEndpoints() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Collections.singletonList(edsDiscoveryMechanism1), roundRobin, false);
|
edsDiscoveryMechanism1, roundRobin, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1");
|
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1");
|
||||||
EquivalentAddressGroup endpoint2 = makeAddress("endpoint-addr-2");
|
EquivalentAddressGroup endpoint2 = makeAddress("endpoint-addr-2");
|
||||||
LocalityLbEndpoints localityLbEndpoints1 =
|
LocalityLbEndpoints localityLbEndpoints1 =
|
||||||
LocalityLbEndpoints.create(
|
LocalityLbEndpoints.create(
|
||||||
Collections.singletonList(LbEndpoint.create(endpoint1, 100, false /* isHealthy */,
|
Collections.singletonList(LbEndpoint.create(endpoint1, 100, false /* isHealthy */,
|
||||||
"hostname1", ImmutableMap.of())),
|
"hostname1", ImmutableMap.of())),
|
||||||
10 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
10 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
||||||
LocalityLbEndpoints localityLbEndpoints2 =
|
LocalityLbEndpoints localityLbEndpoints2 =
|
||||||
LocalityLbEndpoints.create(
|
LocalityLbEndpoints.create(
|
||||||
Collections.singletonList(LbEndpoint.create(endpoint2, 100, true /* isHealthy */,
|
Collections.singletonList(LbEndpoint.create(endpoint2, 100, true /* isHealthy */,
|
||||||
"hostname2", ImmutableMap.of())),
|
"hostname2", ImmutableMap.of())),
|
||||||
10 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
10 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
||||||
xdsClient.deliverClusterLoadAssignment(
|
xdsClient.deliverClusterLoadAssignment(
|
||||||
EDS_SERVICE_NAME1,
|
EDS_SERVICE_NAME1,
|
||||||
|
|
@ -780,20 +747,20 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
@Test
|
@Test
|
||||||
public void handleEdsResource_ignorePrioritiesWithNoHealthyEndpoints() {
|
public void handleEdsResource_ignorePrioritiesWithNoHealthyEndpoints() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Collections.singletonList(edsDiscoveryMechanism1), roundRobin, false);
|
edsDiscoveryMechanism1, roundRobin, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1");
|
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1");
|
||||||
EquivalentAddressGroup endpoint2 = makeAddress("endpoint-addr-2");
|
EquivalentAddressGroup endpoint2 = makeAddress("endpoint-addr-2");
|
||||||
LocalityLbEndpoints localityLbEndpoints1 =
|
LocalityLbEndpoints localityLbEndpoints1 =
|
||||||
LocalityLbEndpoints.create(
|
LocalityLbEndpoints.create(
|
||||||
Collections.singletonList(LbEndpoint.create(endpoint1, 100, false /* isHealthy */,
|
Collections.singletonList(LbEndpoint.create(endpoint1, 100, false /* isHealthy */,
|
||||||
"hostname1", ImmutableMap.of())),
|
"hostname1", ImmutableMap.of())),
|
||||||
10 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
10 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
||||||
LocalityLbEndpoints localityLbEndpoints2 =
|
LocalityLbEndpoints localityLbEndpoints2 =
|
||||||
LocalityLbEndpoints.create(
|
LocalityLbEndpoints.create(
|
||||||
Collections.singletonList(LbEndpoint.create(endpoint2, 200, true /* isHealthy */,
|
Collections.singletonList(LbEndpoint.create(endpoint2, 200, true /* isHealthy */,
|
||||||
"hostname2", ImmutableMap.of())),
|
"hostname2", ImmutableMap.of())),
|
||||||
10 /* localityWeight */, 2 /* priority */, ImmutableMap.of());
|
10 /* localityWeight */, 2 /* priority */, ImmutableMap.of());
|
||||||
String priority2 = CLUSTER1 + "[child2]";
|
String priority2 = CLUSTER1 + "[child2]";
|
||||||
xdsClient.deliverClusterLoadAssignment(
|
xdsClient.deliverClusterLoadAssignment(
|
||||||
EDS_SERVICE_NAME1,
|
EDS_SERVICE_NAME1,
|
||||||
|
|
@ -806,7 +773,7 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
@Test
|
@Test
|
||||||
public void handleEdsResource_noHealthyEndpoint() {
|
public void handleEdsResource_noHealthyEndpoint() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Collections.singletonList(edsDiscoveryMechanism1), roundRobin, false);
|
edsDiscoveryMechanism1, roundRobin, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
EquivalentAddressGroup endpoint = makeAddress("endpoint-addr-1");
|
EquivalentAddressGroup endpoint = makeAddress("endpoint-addr-1");
|
||||||
LocalityLbEndpoints localityLbEndpoints =
|
LocalityLbEndpoints localityLbEndpoints =
|
||||||
|
|
@ -823,7 +790,7 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
assertPicker(
|
assertPicker(
|
||||||
pickerCaptor.getValue(),
|
pickerCaptor.getValue(),
|
||||||
Status.UNAVAILABLE.withDescription(
|
Status.UNAVAILABLE.withDescription(
|
||||||
"No usable endpoint from cluster(s): " + Collections.singleton(CLUSTER1)),
|
"No usable endpoint from cluster: " + CLUSTER1),
|
||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -841,7 +808,7 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
|
|
||||||
void do_onlyLogicalDnsCluster_endpointsResolved() {
|
void do_onlyLogicalDnsCluster_endpointsResolved() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Collections.singletonList(logicalDnsDiscoveryMechanism), roundRobin, false);
|
logicalDnsDiscoveryMechanism, roundRobin, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
FakeNameResolver resolver = assertResolverCreated("/" + DNS_HOST_NAME);
|
FakeNameResolver resolver = assertResolverCreated("/" + DNS_HOST_NAME);
|
||||||
assertThat(childBalancers).isEmpty();
|
assertThat(childBalancers).isEmpty();
|
||||||
|
|
@ -857,7 +824,7 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
PriorityChildConfig priorityChildConfig = priorityLbConfig.childConfigs.get(priority);
|
PriorityChildConfig priorityChildConfig = priorityLbConfig.childConfigs.get(priority);
|
||||||
assertThat(priorityChildConfig.ignoreReresolution).isFalse();
|
assertThat(priorityChildConfig.ignoreReresolution).isFalse();
|
||||||
assertThat(GracefulSwitchLoadBalancerAccessor.getChildProvider(priorityChildConfig.childConfig)
|
assertThat(GracefulSwitchLoadBalancerAccessor.getChildProvider(priorityChildConfig.childConfig)
|
||||||
.getPolicyName())
|
.getPolicyName())
|
||||||
.isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
.isEqualTo(CLUSTER_IMPL_POLICY_NAME);
|
||||||
ClusterImplConfig clusterImplConfig = (ClusterImplConfig)
|
ClusterImplConfig clusterImplConfig = (ClusterImplConfig)
|
||||||
GracefulSwitchLoadBalancerAccessor.getChildConfig(priorityChildConfig.childConfig);
|
GracefulSwitchLoadBalancerAccessor.getChildConfig(priorityChildConfig.childConfig);
|
||||||
|
|
@ -873,7 +840,7 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
@Test
|
@Test
|
||||||
public void onlyLogicalDnsCluster_handleRefreshNameResolution() {
|
public void onlyLogicalDnsCluster_handleRefreshNameResolution() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Collections.singletonList(logicalDnsDiscoveryMechanism), roundRobin, false);
|
logicalDnsDiscoveryMechanism, roundRobin, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
FakeNameResolver resolver = assertResolverCreated("/" + DNS_HOST_NAME);
|
FakeNameResolver resolver = assertResolverCreated("/" + DNS_HOST_NAME);
|
||||||
assertThat(childBalancers).isEmpty();
|
assertThat(childBalancers).isEmpty();
|
||||||
|
|
@ -900,9 +867,9 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
|
|
||||||
void do_onlyLogicalDnsCluster_resolutionError_backoffAndRefresh() {
|
void do_onlyLogicalDnsCluster_resolutionError_backoffAndRefresh() {
|
||||||
InOrder inOrder = Mockito.inOrder(helper, backoffPolicyProvider,
|
InOrder inOrder = Mockito.inOrder(helper, backoffPolicyProvider,
|
||||||
backoffPolicy1, backoffPolicy2);
|
backoffPolicy1, backoffPolicy2);
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Collections.singletonList(logicalDnsDiscoveryMechanism), roundRobin, false);
|
logicalDnsDiscoveryMechanism, roundRobin, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
FakeNameResolver resolver = assertResolverCreated("/" + DNS_HOST_NAME);
|
FakeNameResolver resolver = assertResolverCreated("/" + DNS_HOST_NAME);
|
||||||
assertThat(childBalancers).isEmpty();
|
assertThat(childBalancers).isEmpty();
|
||||||
|
|
@ -948,7 +915,7 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
public void onlyLogicalDnsCluster_refreshNameResolutionRaceWithResolutionError() {
|
public void onlyLogicalDnsCluster_refreshNameResolutionRaceWithResolutionError() {
|
||||||
InOrder inOrder = Mockito.inOrder(backoffPolicyProvider, backoffPolicy1, backoffPolicy2);
|
InOrder inOrder = Mockito.inOrder(backoffPolicyProvider, backoffPolicy1, backoffPolicy2);
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Collections.singletonList(logicalDnsDiscoveryMechanism), roundRobin, false);
|
logicalDnsDiscoveryMechanism, roundRobin, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
FakeNameResolver resolver = assertResolverCreated("/" + DNS_HOST_NAME);
|
FakeNameResolver resolver = assertResolverCreated("/" + DNS_HOST_NAME);
|
||||||
assertThat(childBalancers).isEmpty();
|
assertThat(childBalancers).isEmpty();
|
||||||
|
|
@ -984,119 +951,22 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void edsClustersAndLogicalDnsCluster_receivedEndpoints() {
|
public void resolutionErrorAfterChildLbCreated_propagateError() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Arrays.asList(edsDiscoveryMechanism1, logicalDnsDiscoveryMechanism), roundRobin, false);
|
edsDiscoveryMechanism1, roundRobin, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
||||||
FakeNameResolver resolver = assertResolverCreated("/" + DNS_HOST_NAME);
|
|
||||||
assertThat(childBalancers).isEmpty();
|
|
||||||
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1"); // DNS endpoint
|
|
||||||
EquivalentAddressGroup endpoint2 = makeAddress("endpoint-addr-2"); // DNS endpoint
|
|
||||||
EquivalentAddressGroup endpoint3 = makeAddress("endpoint-addr-3"); // EDS endpoint
|
|
||||||
resolver.deliverEndpointAddresses(Arrays.asList(endpoint1, endpoint2));
|
|
||||||
LocalityLbEndpoints localityLbEndpoints =
|
|
||||||
LocalityLbEndpoints.create(
|
|
||||||
Collections.singletonList(LbEndpoint.create(endpoint3, 100, true,
|
|
||||||
"hostname3", ImmutableMap.of())),
|
|
||||||
10 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
|
||||||
xdsClient.deliverClusterLoadAssignment(
|
|
||||||
EDS_SERVICE_NAME1, Collections.singletonMap(locality1, localityLbEndpoints));
|
|
||||||
|
|
||||||
assertThat(childBalancers).hasSize(1);
|
|
||||||
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
|
||||||
assertThat(((PriorityLbConfig) childBalancer.config).priorities)
|
|
||||||
.containsExactly(CLUSTER1 + "[child1]", CLUSTER_DNS + "[child0]").inOrder();
|
|
||||||
assertAddressesEqual(Arrays.asList(endpoint3, endpoint1, endpoint2),
|
|
||||||
childBalancer.addresses); // ordered by cluster then addresses
|
|
||||||
assertAddressesEqual(AddressFilter.filter(AddressFilter.filter(
|
|
||||||
childBalancer.addresses, CLUSTER1 + "[child1]"),
|
|
||||||
"{region=\"test-region-1\", zone=\"test-zone-1\", sub_zone=\"test-subzone-1\"}"),
|
|
||||||
Collections.singletonList(endpoint3));
|
|
||||||
assertAddressesEqual(AddressFilter.filter(AddressFilter.filter(
|
|
||||||
childBalancer.addresses, CLUSTER_DNS + "[child0]"),
|
|
||||||
"{region=\"\", zone=\"\", sub_zone=\"\"}"),
|
|
||||||
Arrays.asList(endpoint1, endpoint2));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void noEdsResourceExists_useDnsResolutionResults() {
|
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
|
||||||
Arrays.asList(edsDiscoveryMechanism1, logicalDnsDiscoveryMechanism), roundRobin, false);
|
|
||||||
deliverLbConfig(config);
|
|
||||||
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
|
||||||
FakeNameResolver resolver = assertResolverCreated("/" + DNS_HOST_NAME);
|
|
||||||
assertThat(childBalancers).isEmpty();
|
|
||||||
reset(helper);
|
|
||||||
xdsClient.deliverResourceNotFound(EDS_SERVICE_NAME1);
|
|
||||||
verify(helper, never()).updateBalancingState(
|
|
||||||
any(ConnectivityState.class), any(SubchannelPicker.class)); // wait for DNS results
|
|
||||||
|
|
||||||
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1");
|
|
||||||
EquivalentAddressGroup endpoint2 = makeAddress("endpoint-addr-2");
|
|
||||||
resolver.deliverEndpointAddresses(Arrays.asList(endpoint1, endpoint2));
|
|
||||||
assertThat(childBalancers).hasSize(1);
|
|
||||||
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
|
||||||
String priority = Iterables.getOnlyElement(
|
|
||||||
((PriorityLbConfig) childBalancer.config).priorities);
|
|
||||||
assertThat(priority).isEqualTo(CLUSTER_DNS + "[child0]");
|
|
||||||
assertAddressesEqual(Arrays.asList(endpoint1, endpoint2), childBalancer.addresses);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void edsResourceRevoked_dnsResolutionError_shutDownChildLbPolicyAndReturnErrorPicker() {
|
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
|
||||||
Arrays.asList(edsDiscoveryMechanism1, logicalDnsDiscoveryMechanism), roundRobin, false);
|
|
||||||
deliverLbConfig(config);
|
|
||||||
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
|
||||||
FakeNameResolver resolver = assertResolverCreated("/" + DNS_HOST_NAME);
|
|
||||||
assertThat(childBalancers).isEmpty();
|
assertThat(childBalancers).isEmpty();
|
||||||
reset(helper);
|
reset(helper);
|
||||||
EquivalentAddressGroup endpoint = makeAddress("endpoint-addr-1");
|
EquivalentAddressGroup endpoint = makeAddress("endpoint-addr-1");
|
||||||
LocalityLbEndpoints localityLbEndpoints =
|
LocalityLbEndpoints localityLbEndpoints =
|
||||||
LocalityLbEndpoints.create(
|
LocalityLbEndpoints.create(
|
||||||
Collections.singletonList(LbEndpoint.create(endpoint, 100, true,
|
Collections.singletonList(LbEndpoint.create(endpoint, 100, true,
|
||||||
"hostname1", ImmutableMap.of())),
|
"hostname1", ImmutableMap.of())),
|
||||||
10 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
10 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
||||||
xdsClient.deliverClusterLoadAssignment(
|
xdsClient.deliverClusterLoadAssignment(
|
||||||
EDS_SERVICE_NAME1, Collections.singletonMap(locality1, localityLbEndpoints));
|
EDS_SERVICE_NAME1, Collections.singletonMap(locality1, localityLbEndpoints));
|
||||||
resolver.deliverError(Status.UNKNOWN.withDescription("I am lost"));
|
|
||||||
assertThat(childBalancers).hasSize(1);
|
|
||||||
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
|
||||||
assertThat(((PriorityLbConfig) childBalancer.config).priorities)
|
|
||||||
.containsExactly(CLUSTER1 + "[child1]");
|
|
||||||
assertAddressesEqual(Collections.singletonList(endpoint), childBalancer.addresses);
|
|
||||||
assertThat(childBalancer.shutdown).isFalse();
|
|
||||||
xdsClient.deliverResourceNotFound(EDS_SERVICE_NAME1);
|
|
||||||
assertThat(childBalancer.shutdown).isTrue();
|
|
||||||
verify(helper).updateBalancingState(
|
|
||||||
eq(ConnectivityState.TRANSIENT_FAILURE), pickerCaptor.capture());
|
|
||||||
assertPicker(pickerCaptor.getValue(),
|
|
||||||
Status.UNAVAILABLE.withDescription("I am lost"), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void resolutionErrorAfterChildLbCreated_propagateErrorIfAllClustersEncounterError() {
|
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
|
||||||
Arrays.asList(edsDiscoveryMechanism1, logicalDnsDiscoveryMechanism), roundRobin, false);
|
|
||||||
deliverLbConfig(config);
|
|
||||||
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
|
||||||
FakeNameResolver resolver = assertResolverCreated("/" + DNS_HOST_NAME);
|
|
||||||
assertThat(childBalancers).isEmpty();
|
|
||||||
reset(helper);
|
|
||||||
EquivalentAddressGroup endpoint = makeAddress("endpoint-addr-1");
|
|
||||||
LocalityLbEndpoints localityLbEndpoints =
|
|
||||||
LocalityLbEndpoints.create(
|
|
||||||
Collections.singletonList(LbEndpoint.create(endpoint, 100, true,
|
|
||||||
"hostname1", ImmutableMap.of())),
|
|
||||||
10 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
|
||||||
xdsClient.deliverClusterLoadAssignment(
|
|
||||||
EDS_SERVICE_NAME1, Collections.singletonMap(locality1, localityLbEndpoints));
|
|
||||||
assertThat(childBalancers).isEmpty(); // not created until all clusters resolved.
|
|
||||||
|
|
||||||
resolver.deliverError(Status.UNKNOWN.withDescription("I am lost"));
|
|
||||||
|
|
||||||
// DNS resolution failed, but there are EDS endpoints can be used.
|
|
||||||
assertThat(childBalancers).hasSize(1);
|
assertThat(childBalancers).hasSize(1);
|
||||||
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers); // child LB created
|
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers); // child LB created
|
||||||
assertThat(childBalancer.upstreamError).isNull(); // should not propagate error to child LB
|
assertThat(childBalancer.upstreamError).isNull(); // should not propagate error to child LB
|
||||||
|
|
@ -1104,40 +974,19 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
|
|
||||||
xdsClient.deliverError(Status.RESOURCE_EXHAUSTED.withDescription("out of memory"));
|
xdsClient.deliverError(Status.RESOURCE_EXHAUSTED.withDescription("out of memory"));
|
||||||
assertThat(childBalancer.upstreamError).isNotNull(); // last cluster's (DNS) error propagated
|
assertThat(childBalancer.upstreamError).isNotNull(); // last cluster's (DNS) error propagated
|
||||||
assertThat(childBalancer.upstreamError.getCode()).isEqualTo(Code.UNKNOWN);
|
assertThat(childBalancer.upstreamError.getCode()).isEqualTo(Code.UNAVAILABLE);
|
||||||
assertThat(childBalancer.upstreamError.getDescription()).isEqualTo("I am lost");
|
assertThat(childBalancer.upstreamError.getDescription())
|
||||||
|
.isEqualTo("Unable to load EDS backend-service-foo.googleapis.com. xDS server returned: "
|
||||||
|
+ "RESOURCE_EXHAUSTED: out of memory");
|
||||||
assertThat(childBalancer.shutdown).isFalse();
|
assertThat(childBalancer.shutdown).isFalse();
|
||||||
verify(helper, never()).updateBalancingState(
|
verify(helper, never()).updateBalancingState(
|
||||||
eq(ConnectivityState.TRANSIENT_FAILURE), any(SubchannelPicker.class));
|
eq(ConnectivityState.TRANSIENT_FAILURE), any(SubchannelPicker.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void resolutionErrorBeforeChildLbCreated_returnErrorPickerIfAllClustersEncounterError() {
|
public void resolutionErrorBeforeChildLbCreated_returnErrorPicker() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Arrays.asList(edsDiscoveryMechanism1, logicalDnsDiscoveryMechanism), roundRobin, false);
|
edsDiscoveryMechanism1, roundRobin, false);
|
||||||
deliverLbConfig(config);
|
|
||||||
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
|
||||||
FakeNameResolver resolver = assertResolverCreated("/" + DNS_HOST_NAME);
|
|
||||||
assertThat(childBalancers).isEmpty();
|
|
||||||
reset(helper);
|
|
||||||
xdsClient.deliverError(Status.UNIMPLEMENTED.withDescription("not found"));
|
|
||||||
assertThat(childBalancers).isEmpty();
|
|
||||||
verify(helper, never()).updateBalancingState(
|
|
||||||
eq(ConnectivityState.TRANSIENT_FAILURE), any(SubchannelPicker.class)); // wait for DNS
|
|
||||||
Status dnsError = Status.UNKNOWN.withDescription("I am lost");
|
|
||||||
resolver.deliverError(dnsError);
|
|
||||||
verify(helper).updateBalancingState(
|
|
||||||
eq(ConnectivityState.TRANSIENT_FAILURE), pickerCaptor.capture());
|
|
||||||
assertPicker(
|
|
||||||
pickerCaptor.getValue(),
|
|
||||||
Status.UNAVAILABLE.withDescription(dnsError.getDescription()),
|
|
||||||
null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void resolutionErrorBeforeChildLbCreated_edsOnly_returnErrorPicker() {
|
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
|
||||||
Arrays.asList(edsDiscoveryMechanism1), roundRobin, false);
|
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
||||||
assertThat(childBalancers).isEmpty();
|
assertThat(childBalancers).isEmpty();
|
||||||
|
|
@ -1153,11 +1002,25 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void handleNameResolutionErrorFromUpstream_beforeChildLbCreated_returnErrorPicker() {
|
public void handleNameResolutionErrorFromUpstream_eds_beforeChildLbCreated_returnErrorPicker() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Arrays.asList(edsDiscoveryMechanism1, logicalDnsDiscoveryMechanism), roundRobin, false);
|
edsDiscoveryMechanism1, roundRobin, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
||||||
|
assertThat(childBalancers).isEmpty();
|
||||||
|
reset(helper);
|
||||||
|
Status upstreamError = Status.UNAVAILABLE.withDescription("unreachable");
|
||||||
|
loadBalancer.handleNameResolutionError(upstreamError);
|
||||||
|
verify(helper).updateBalancingState(
|
||||||
|
eq(ConnectivityState.TRANSIENT_FAILURE), pickerCaptor.capture());
|
||||||
|
assertPicker(pickerCaptor.getValue(), upstreamError, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handleNameResolutionErrorFromUpstream_lDns_beforeChildLbCreated_returnErrorPicker() {
|
||||||
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
|
logicalDnsDiscoveryMechanism, roundRobin, false);
|
||||||
|
deliverLbConfig(config);
|
||||||
assertResolverCreated("/" + DNS_HOST_NAME);
|
assertResolverCreated("/" + DNS_HOST_NAME);
|
||||||
assertThat(childBalancers).isEmpty();
|
assertThat(childBalancers).isEmpty();
|
||||||
reset(helper);
|
reset(helper);
|
||||||
|
|
@ -1169,16 +1032,14 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void handleNameResolutionErrorFromUpstream_afterChildLbCreated_fallThrough() {
|
public void handleNameResolutionErrorFromUpstream_afterChildLbCreated_eds_fallThrough() {
|
||||||
ClusterResolverConfig config = new ClusterResolverConfig(
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
Arrays.asList(edsDiscoveryMechanism1, logicalDnsDiscoveryMechanism), roundRobin, false);
|
edsDiscoveryMechanism1, roundRobin, false);
|
||||||
deliverLbConfig(config);
|
deliverLbConfig(config);
|
||||||
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
|
||||||
FakeNameResolver resolver = assertResolverCreated("/" + DNS_HOST_NAME);
|
|
||||||
assertThat(childBalancers).isEmpty();
|
assertThat(childBalancers).isEmpty();
|
||||||
reset(helper);
|
reset(helper);
|
||||||
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1");
|
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1");
|
||||||
EquivalentAddressGroup endpoint2 = makeAddress("endpoint-addr-2");
|
|
||||||
LocalityLbEndpoints localityLbEndpoints =
|
LocalityLbEndpoints localityLbEndpoints =
|
||||||
LocalityLbEndpoints.create(
|
LocalityLbEndpoints.create(
|
||||||
Collections.singletonList(LbEndpoint.create(endpoint1, 100, true,
|
Collections.singletonList(LbEndpoint.create(endpoint1, 100, true,
|
||||||
|
|
@ -1186,12 +1047,34 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
10 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
10 /* localityWeight */, 1 /* priority */, ImmutableMap.of());
|
||||||
xdsClient.deliverClusterLoadAssignment(
|
xdsClient.deliverClusterLoadAssignment(
|
||||||
EDS_SERVICE_NAME1, Collections.singletonMap(locality1, localityLbEndpoints));
|
EDS_SERVICE_NAME1, Collections.singletonMap(locality1, localityLbEndpoints));
|
||||||
|
assertThat(childBalancers).hasSize(1);
|
||||||
|
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
||||||
|
assertThat(((PriorityLbConfig) childBalancer.config).priorities)
|
||||||
|
.containsExactly(CLUSTER1 + "[child1]");
|
||||||
|
assertAddressesEqual(Arrays.asList(endpoint1), childBalancer.addresses);
|
||||||
|
|
||||||
|
loadBalancer.handleNameResolutionError(Status.UNAVAILABLE.withDescription("unreachable"));
|
||||||
|
assertThat(childBalancer.upstreamError.getCode()).isEqualTo(Code.UNAVAILABLE);
|
||||||
|
assertThat(childBalancer.upstreamError.getDescription()).isEqualTo("unreachable");
|
||||||
|
verify(helper, never()).updateBalancingState(
|
||||||
|
any(ConnectivityState.class), any(SubchannelPicker.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handleNameResolutionErrorFromUpstream_afterChildLbCreated_logicalDns_fallThrough() {
|
||||||
|
ClusterResolverConfig config = new ClusterResolverConfig(
|
||||||
|
logicalDnsDiscoveryMechanism, roundRobin, false);
|
||||||
|
deliverLbConfig(config);
|
||||||
|
FakeNameResolver resolver = assertResolverCreated("/" + DNS_HOST_NAME);
|
||||||
|
assertThat(childBalancers).isEmpty();
|
||||||
|
reset(helper);
|
||||||
|
EquivalentAddressGroup endpoint2 = makeAddress("endpoint-addr-2");
|
||||||
resolver.deliverEndpointAddresses(Collections.singletonList(endpoint2));
|
resolver.deliverEndpointAddresses(Collections.singletonList(endpoint2));
|
||||||
assertThat(childBalancers).hasSize(1);
|
assertThat(childBalancers).hasSize(1);
|
||||||
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
|
||||||
assertThat(((PriorityLbConfig) childBalancer.config).priorities)
|
assertThat(((PriorityLbConfig) childBalancer.config).priorities)
|
||||||
.containsExactly(CLUSTER1 + "[child1]", CLUSTER_DNS + "[child0]");
|
.containsExactly(CLUSTER_DNS + "[child0]");
|
||||||
assertAddressesEqual(Arrays.asList(endpoint1, endpoint2), childBalancer.addresses);
|
assertAddressesEqual(Arrays.asList(endpoint2), childBalancer.addresses);
|
||||||
|
|
||||||
loadBalancer.handleNameResolutionError(Status.UNAVAILABLE.withDescription("unreachable"));
|
loadBalancer.handleNameResolutionError(Status.UNAVAILABLE.withDescription("unreachable"));
|
||||||
assertThat(childBalancer.upstreamError.getCode()).isEqualTo(Code.UNAVAILABLE);
|
assertThat(childBalancer.upstreamError.getCode()).isEqualTo(Code.UNAVAILABLE);
|
||||||
|
|
@ -1205,19 +1088,17 @@ public class ClusterResolverLoadBalancerTest {
|
||||||
new EqualsTester()
|
new EqualsTester()
|
||||||
.addEqualityGroup(
|
.addEqualityGroup(
|
||||||
new ClusterResolverConfig(
|
new ClusterResolverConfig(
|
||||||
Collections.singletonList(edsDiscoveryMechanism1), leastRequest, false),
|
edsDiscoveryMechanism1, leastRequest, false),
|
||||||
new ClusterResolverConfig(
|
new ClusterResolverConfig(
|
||||||
Collections.singletonList(edsDiscoveryMechanism1), leastRequest, false))
|
edsDiscoveryMechanism1, leastRequest, false))
|
||||||
.addEqualityGroup(new ClusterResolverConfig(
|
.addEqualityGroup(new ClusterResolverConfig(
|
||||||
Collections.singletonList(edsDiscoveryMechanism1), roundRobin, false))
|
edsDiscoveryMechanism1, roundRobin, false))
|
||||||
.addEqualityGroup(new ClusterResolverConfig(
|
.addEqualityGroup(new ClusterResolverConfig(
|
||||||
Collections.singletonList(edsDiscoveryMechanism1), leastRequest, true))
|
edsDiscoveryMechanism1, leastRequest, true))
|
||||||
.addEqualityGroup(new ClusterResolverConfig(
|
.addEqualityGroup(new ClusterResolverConfig(
|
||||||
Collections.singletonList(edsDiscoveryMechanismWithOutlierDetection),
|
edsDiscoveryMechanismWithOutlierDetection,
|
||||||
leastRequest,
|
leastRequest,
|
||||||
false))
|
false))
|
||||||
.addEqualityGroup(new ClusterResolverConfig(
|
|
||||||
Arrays.asList(edsDiscoveryMechanism1, edsDiscoveryMechanism2), leastRequest, false))
|
|
||||||
.testEquals();
|
.testEquals();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue