mirror of https://github.com/grpc/grpc-java.git
core: do not fail RPCs if balancer address exists but grpclb is unavailable (#5129)
When service owner turns on grpclb through service config, it shouldn't break existing clients that don't have grpclb in their classpath. Resolves #4602
This commit is contained in:
parent
8ff92a4a7d
commit
0cc0f2d170
|
|
@ -20,7 +20,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import io.grpc.Attributes;
|
||||
import io.grpc.ChannelLogger;
|
||||
import io.grpc.ChannelLogger.ChannelLogLevel;
|
||||
import io.grpc.ConnectivityState;
|
||||
import io.grpc.ConnectivityStateInfo;
|
||||
|
|
@ -33,17 +32,31 @@ import io.grpc.LoadBalancer.SubchannelPicker;
|
|||
import io.grpc.LoadBalancerProvider;
|
||||
import io.grpc.LoadBalancerRegistry;
|
||||
import io.grpc.Status;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@VisibleForTesting
|
||||
public final class AutoConfiguredLoadBalancerFactory extends LoadBalancer.Factory {
|
||||
private static final String DEFAULT_POLICY = "pick_first";
|
||||
private static final Logger logger =
|
||||
Logger.getLogger(AutoConfiguredLoadBalancerFactory.class.getName());
|
||||
|
||||
private static final LoadBalancerRegistry registry = LoadBalancerRegistry.getDefaultRegistry();
|
||||
private final LoadBalancerRegistry registry;
|
||||
|
||||
public AutoConfiguredLoadBalancerFactory() {
|
||||
this(LoadBalancerRegistry.getDefaultRegistry());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
AutoConfiguredLoadBalancerFactory(LoadBalancerRegistry registry) {
|
||||
this.registry = checkNotNull(registry, "registry");
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoadBalancer newLoadBalancer(Helper helper) {
|
||||
|
|
@ -65,12 +78,12 @@ public final class AutoConfiguredLoadBalancerFactory extends LoadBalancer.Factor
|
|||
public void shutdown() {}
|
||||
}
|
||||
|
||||
|
||||
@VisibleForTesting
|
||||
public static final class AutoConfiguredLoadBalancer extends LoadBalancer {
|
||||
public final class AutoConfiguredLoadBalancer extends LoadBalancer {
|
||||
private final Helper helper;
|
||||
private LoadBalancer delegate;
|
||||
private LoadBalancerProvider delegateProvider;
|
||||
private boolean roundRobinDueToGrpclbDepMissing;
|
||||
|
||||
AutoConfiguredLoadBalancer(Helper helper) {
|
||||
this.helper = helper;
|
||||
|
|
@ -94,7 +107,7 @@ public final class AutoConfiguredLoadBalancerFactory extends LoadBalancer.Factor
|
|||
Map<String, Object> configMap = attributes.get(GrpcAttributes.NAME_RESOLVER_SERVICE_CONFIG);
|
||||
PolicySelection selection;
|
||||
try {
|
||||
selection = decideLoadBalancerProvider(servers, configMap, helper.getChannelLogger());
|
||||
selection = decideLoadBalancerProvider(servers, configMap);
|
||||
} catch (PolicyException e) {
|
||||
Status s = Status.INTERNAL.withDescription(e.getMessage());
|
||||
helper.updateBalancingState(ConnectivityState.TRANSIENT_FAILURE, new FailingPicker(s));
|
||||
|
|
@ -122,7 +135,7 @@ public final class AutoConfiguredLoadBalancerFactory extends LoadBalancer.Factor
|
|||
attributes =
|
||||
attributes.toBuilder().set(ATTR_LOAD_BALANCING_CONFIG, selection.config).build();
|
||||
}
|
||||
getDelegate().handleResolvedAddressGroups(servers, attributes);
|
||||
getDelegate().handleResolvedAddressGroups(selection.serverList, attributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -155,7 +168,6 @@ public final class AutoConfiguredLoadBalancerFactory extends LoadBalancer.Factor
|
|||
LoadBalancerProvider getDelegateProvider() {
|
||||
return delegateProvider;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Picks a load balancer based on given criteria. In order of preference:
|
||||
|
|
@ -172,23 +184,43 @@ public final class AutoConfiguredLoadBalancerFactory extends LoadBalancer.Factor
|
|||
* @return the new load balancer factory, never null
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static PolicySelection decideLoadBalancerProvider(
|
||||
List<EquivalentAddressGroup> servers, @Nullable Map<String, Object> config,
|
||||
ChannelLogger channelLogger) throws PolicyException {
|
||||
PolicySelection decideLoadBalancerProvider(
|
||||
List<EquivalentAddressGroup> servers, @Nullable Map<String, Object> config)
|
||||
throws PolicyException {
|
||||
// Check for balancer addresses
|
||||
boolean haveBalancerAddress = false;
|
||||
List<EquivalentAddressGroup> backendAddrs = new ArrayList<EquivalentAddressGroup>();
|
||||
for (EquivalentAddressGroup s : servers) {
|
||||
if (s.getAttributes().get(GrpcAttributes.ATTR_LB_ADDR_AUTHORITY) != null) {
|
||||
haveBalancerAddress = true;
|
||||
break;
|
||||
} else {
|
||||
backendAddrs.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
if (haveBalancerAddress) {
|
||||
LoadBalancerProvider provider =
|
||||
getProviderOrThrow("grpclb", "NameResolver has returned balancer addresses");
|
||||
return new PolicySelection(provider, null);
|
||||
LoadBalancerProvider grpclbProvider = registry.getProvider("grpclb");
|
||||
if (grpclbProvider == null) {
|
||||
if (backendAddrs.isEmpty()) {
|
||||
throw new PolicyException(
|
||||
"Received ONLY balancer addresses but grpclb runtime is missing");
|
||||
}
|
||||
if (!roundRobinDueToGrpclbDepMissing) {
|
||||
roundRobinDueToGrpclbDepMissing = true;
|
||||
String errorMsg = "Found balancer addresses but grpclb runtime is missing."
|
||||
+ " Will use round_robin. Please include grpc-grpclb in your runtime depedencies.";
|
||||
helper.getChannelLogger().log(ChannelLogLevel.ERROR, errorMsg);
|
||||
logger.warning(errorMsg);
|
||||
}
|
||||
return new PolicySelection(
|
||||
getProviderOrThrow(
|
||||
"round_robin", "received balancer addresses but grpclb runtime is missing"),
|
||||
backendAddrs, null);
|
||||
} else {
|
||||
return new PolicySelection(grpclbProvider, servers, null);
|
||||
}
|
||||
}
|
||||
roundRobinDueToGrpclbDepMissing = false;
|
||||
|
||||
if (config != null) {
|
||||
List<Map<String, Object>> lbConfigs =
|
||||
|
|
@ -206,11 +238,11 @@ public final class AutoConfiguredLoadBalancerFactory extends LoadBalancer.Factor
|
|||
LoadBalancerProvider provider = registry.getProvider(policy);
|
||||
if (provider != null) {
|
||||
if (!policiesTried.isEmpty()) {
|
||||
channelLogger.log(
|
||||
helper.getChannelLogger().log(
|
||||
ChannelLogLevel.DEBUG,
|
||||
"{0} specified by Service Config are not available", policiesTried);
|
||||
}
|
||||
return new PolicySelection(provider, (Map) entry.getValue());
|
||||
return new PolicySelection(provider, servers, (Map) entry.getValue());
|
||||
}
|
||||
policiesTried.add(policy);
|
||||
}
|
||||
|
|
@ -218,10 +250,11 @@ public final class AutoConfiguredLoadBalancerFactory extends LoadBalancer.Factor
|
|||
"None of " + policiesTried + " specified by Service Config are available.");
|
||||
}
|
||||
return new PolicySelection(
|
||||
getProviderOrThrow(DEFAULT_POLICY, "using default policy"), null);
|
||||
getProviderOrThrow(DEFAULT_POLICY, "using default policy"), servers, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static LoadBalancerProvider getProviderOrThrow(String policy, String choiceReason)
|
||||
private LoadBalancerProvider getProviderOrThrow(String policy, String choiceReason)
|
||||
throws PolicyException {
|
||||
LoadBalancerProvider provider = registry.getProvider(policy);
|
||||
if (provider == null) {
|
||||
|
|
@ -243,11 +276,15 @@ public final class AutoConfiguredLoadBalancerFactory extends LoadBalancer.Factor
|
|||
@VisibleForTesting
|
||||
static final class PolicySelection {
|
||||
final LoadBalancerProvider provider;
|
||||
final List<EquivalentAddressGroup> serverList;
|
||||
@Nullable final Map<String, Object> config;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
PolicySelection(LoadBalancerProvider provider, @Nullable Map<?, ?> config) {
|
||||
PolicySelection(
|
||||
LoadBalancerProvider provider, List<EquivalentAddressGroup> serverList,
|
||||
@Nullable Map<?, ?> config) {
|
||||
this.provider = checkNotNull(provider, "provider");
|
||||
this.serverList = Collections.unmodifiableList(checkNotNull(serverList, "serverList"));
|
||||
this.config = (Map<String, Object>) config;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import static org.mockito.AdditionalAnswers.delegatesTo;
|
|||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.same;
|
||||
import static org.mockito.Matchers.startsWith;
|
||||
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
|
|
@ -145,8 +146,7 @@ public class AutoConfiguredLoadBalancerFactoryTest {
|
|||
@Test
|
||||
public void handleResolvedAddressGroups_keepOldBalancer() {
|
||||
final List<EquivalentAddressGroup> servers =
|
||||
Collections.singletonList(
|
||||
new EquivalentAddressGroup(new SocketAddress(){}, Attributes.EMPTY));
|
||||
Collections.singletonList(new EquivalentAddressGroup(new SocketAddress(){}));
|
||||
Helper helper = new TestHelper() {
|
||||
@Override
|
||||
public Subchannel createSubchannel(List<EquivalentAddressGroup> addrs, Attributes attrs) {
|
||||
|
|
@ -177,10 +177,7 @@ public class AutoConfiguredLoadBalancerFactoryTest {
|
|||
.set(GrpcAttributes.NAME_RESOLVER_SERVICE_CONFIG, serviceConfig)
|
||||
.build();
|
||||
final List<EquivalentAddressGroup> servers =
|
||||
Collections.singletonList(
|
||||
new EquivalentAddressGroup(
|
||||
new SocketAddress(){},
|
||||
Attributes.EMPTY));
|
||||
Collections.singletonList(new EquivalentAddressGroup(new SocketAddress(){}));
|
||||
Helper helper = new TestHelper() {
|
||||
@Override
|
||||
public Subchannel createSubchannel(List<EquivalentAddressGroup> addrs, Attributes attrs) {
|
||||
|
|
@ -231,10 +228,7 @@ public class AutoConfiguredLoadBalancerFactoryTest {
|
|||
.set(GrpcAttributes.NAME_RESOLVER_SERVICE_CONFIG, serviceConfig)
|
||||
.build();
|
||||
final List<EquivalentAddressGroup> servers =
|
||||
Collections.singletonList(
|
||||
new EquivalentAddressGroup(
|
||||
new SocketAddress(){},
|
||||
Attributes.EMPTY));
|
||||
Collections.singletonList(new EquivalentAddressGroup(new SocketAddress(){}));
|
||||
Helper helper = new TestHelper() {
|
||||
@Override
|
||||
public void updateBalancingState(ConnectivityState newState, SubchannelPicker newPicker) {
|
||||
|
|
@ -249,7 +243,7 @@ public class AutoConfiguredLoadBalancerFactoryTest {
|
|||
verify(testLbBalancerProvider).newLoadBalancer(same(helper));
|
||||
assertThat(lb.getDelegate()).isSameAs(testLbBalancer);
|
||||
ArgumentCaptor<Attributes> attrsCaptor = ArgumentCaptor.forClass(null);
|
||||
verify(testLbBalancer).handleResolvedAddressGroups(same(servers), attrsCaptor.capture());
|
||||
verify(testLbBalancer).handleResolvedAddressGroups(eq(servers), attrsCaptor.capture());
|
||||
assertThat(attrsCaptor.getValue().get(ATTR_LOAD_BALANCING_CONFIG))
|
||||
.isEqualTo(Collections.singletonMap("setting1", "high"));
|
||||
verifyNoMoreInteractions(testLbBalancer);
|
||||
|
|
@ -263,7 +257,7 @@ public class AutoConfiguredLoadBalancerFactoryTest {
|
|||
lb.handleResolvedAddressGroups(servers, serviceConfigAttrs);
|
||||
|
||||
verify(testLbBalancer, times(2))
|
||||
.handleResolvedAddressGroups(same(servers), attrsCaptor.capture());
|
||||
.handleResolvedAddressGroups(eq(servers), attrsCaptor.capture());
|
||||
// But the balancer config is changed.
|
||||
assertThat(attrsCaptor.getValue().get(ATTR_LOAD_BALANCING_CONFIG))
|
||||
.isEqualTo(Collections.singletonMap("setting1", "low"));
|
||||
|
|
@ -272,40 +266,74 @@ public class AutoConfiguredLoadBalancerFactoryTest {
|
|||
verify(testLbBalancerProvider).newLoadBalancer(any(Helper.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleResolvedAddressGroups_propagateOnlyBackendAddrsToDelegate() throws Exception {
|
||||
// This case only happens when grpclb is missing. We will use a local registry
|
||||
LoadBalancerRegistry registry = new LoadBalancerRegistry();
|
||||
registry.register(new PickFirstLoadBalancerProvider());
|
||||
registry.register(new FakeRoundRobinLoadBalancerProvider());
|
||||
|
||||
final List<EquivalentAddressGroup> servers =
|
||||
Arrays.asList(
|
||||
new EquivalentAddressGroup(new SocketAddress(){}),
|
||||
new EquivalentAddressGroup(
|
||||
new SocketAddress(){},
|
||||
Attributes.newBuilder().set(GrpcAttributes.ATTR_LB_ADDR_AUTHORITY, "ok").build()));
|
||||
Helper helper = new TestHelper() {
|
||||
@Override
|
||||
public void updateBalancingState(ConnectivityState newState, SubchannelPicker newPicker) {
|
||||
// noop
|
||||
}
|
||||
};
|
||||
AutoConfiguredLoadBalancer lb =
|
||||
(AutoConfiguredLoadBalancer) new AutoConfiguredLoadBalancerFactory(registry)
|
||||
.newLoadBalancer(helper);
|
||||
|
||||
lb.handleResolvedAddressGroups(servers, Attributes.EMPTY);
|
||||
|
||||
assertThat(lb.getDelegate()).isSameAs(testLbBalancer);
|
||||
verify(testLbBalancer).handleResolvedAddressGroups(
|
||||
eq(Collections.singletonList(servers.get(0))), any(Attributes.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decideLoadBalancerProvider_noBalancerAddresses_noServiceConfig_pickFirst()
|
||||
throws Exception {
|
||||
AutoConfiguredLoadBalancer lb =
|
||||
(AutoConfiguredLoadBalancer) lbf.newLoadBalancer(new TestHelper());
|
||||
Map<String, Object> serviceConfig = null;
|
||||
List<EquivalentAddressGroup> servers =
|
||||
Collections.singletonList(
|
||||
new EquivalentAddressGroup(new SocketAddress(){}, Attributes.EMPTY));
|
||||
PolicySelection selection =
|
||||
AutoConfiguredLoadBalancerFactory.decideLoadBalancerProvider(
|
||||
servers, serviceConfig, channelLogger);
|
||||
Collections.singletonList(new EquivalentAddressGroup(new SocketAddress(){}));
|
||||
PolicySelection selection = lb.decideLoadBalancerProvider(servers, serviceConfig);
|
||||
|
||||
assertThat(selection.provider).isInstanceOf(PickFirstLoadBalancerProvider.class);
|
||||
assertThat(selection.serverList).isEqualTo(servers);
|
||||
assertThat(selection.config).isNull();
|
||||
verifyZeroInteractions(channelLogger);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decideLoadBalancerProvider_oneBalancer_noServiceConfig_grpclb() throws Exception {
|
||||
AutoConfiguredLoadBalancer lb =
|
||||
(AutoConfiguredLoadBalancer) lbf.newLoadBalancer(new TestHelper());
|
||||
Map<String, Object> serviceConfig = null;
|
||||
List<EquivalentAddressGroup> servers =
|
||||
Collections.singletonList(
|
||||
new EquivalentAddressGroup(
|
||||
new SocketAddress(){},
|
||||
Attributes.newBuilder().set(GrpcAttributes.ATTR_LB_ADDR_AUTHORITY, "ok").build()));
|
||||
PolicySelection selection = AutoConfiguredLoadBalancerFactory.decideLoadBalancerProvider(
|
||||
servers, serviceConfig, channelLogger);
|
||||
PolicySelection selection = lb.decideLoadBalancerProvider(servers, serviceConfig);
|
||||
|
||||
assertThat(selection.provider).isInstanceOf(GrpclbLoadBalancerProvider.class);
|
||||
assertThat(selection.serverList).isEqualTo(servers);
|
||||
assertThat(selection.config).isNull();
|
||||
verifyZeroInteractions(channelLogger);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decideLoadBalancerProvider_grpclbOverridesServiceConfigLbPolicy() throws Exception {
|
||||
AutoConfiguredLoadBalancer lb =
|
||||
(AutoConfiguredLoadBalancer) lbf.newLoadBalancer(new TestHelper());
|
||||
Map<String, Object> serviceConfig = new HashMap<String, Object>();
|
||||
serviceConfig.put("loadBalancingPolicy", "round_robin");
|
||||
List<EquivalentAddressGroup> servers =
|
||||
|
|
@ -313,10 +341,10 @@ public class AutoConfiguredLoadBalancerFactoryTest {
|
|||
new EquivalentAddressGroup(
|
||||
new SocketAddress(){},
|
||||
Attributes.newBuilder().set(GrpcAttributes.ATTR_LB_ADDR_AUTHORITY, "ok").build()));
|
||||
PolicySelection selection = AutoConfiguredLoadBalancerFactory.decideLoadBalancerProvider(
|
||||
servers, serviceConfig, channelLogger);
|
||||
PolicySelection selection = lb.decideLoadBalancerProvider(servers, serviceConfig);
|
||||
|
||||
assertThat(selection.provider).isInstanceOf(GrpclbLoadBalancerProvider.class);
|
||||
assertThat(selection.serverList).isEqualTo(servers);
|
||||
assertThat(selection.config).isNull();
|
||||
verifyZeroInteractions(channelLogger);
|
||||
}
|
||||
|
|
@ -324,6 +352,8 @@ public class AutoConfiguredLoadBalancerFactoryTest {
|
|||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void decideLoadBalancerProvider_grpclbOverridesServiceConfigLbConfig() throws Exception {
|
||||
AutoConfiguredLoadBalancer lb =
|
||||
(AutoConfiguredLoadBalancer) lbf.newLoadBalancer(new TestHelper());
|
||||
Map<String, Object> serviceConfig =
|
||||
parseConfig("{\"loadBalancingConfig\": [ {\"round_robin\": {} } ] }");
|
||||
List<EquivalentAddressGroup> servers =
|
||||
|
|
@ -331,25 +361,83 @@ public class AutoConfiguredLoadBalancerFactoryTest {
|
|||
new EquivalentAddressGroup(
|
||||
new SocketAddress(){},
|
||||
Attributes.newBuilder().set(GrpcAttributes.ATTR_LB_ADDR_AUTHORITY, "ok").build()));
|
||||
PolicySelection selection = AutoConfiguredLoadBalancerFactory.decideLoadBalancerProvider(
|
||||
servers, serviceConfig, channelLogger);
|
||||
PolicySelection selection = lb.decideLoadBalancerProvider(servers, serviceConfig);
|
||||
|
||||
assertThat(selection.provider).isInstanceOf(GrpclbLoadBalancerProvider.class);
|
||||
assertThat(selection.serverList).isEqualTo(servers);
|
||||
assertThat(selection.config).isNull();
|
||||
verifyZeroInteractions(channelLogger);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decideLoadBalancerProvider_serviceConfigLbPolicyOverridesDefault() throws Exception {
|
||||
Map<String, Object> serviceConfig = new HashMap<String, Object>();
|
||||
serviceConfig.put("loadBalancingPolicy", "round_robin");
|
||||
public void decideLoadBalancerProvider_grpclbProviderNotFound_fallbackToRoundRobin()
|
||||
throws Exception {
|
||||
LoadBalancerRegistry registry = new LoadBalancerRegistry();
|
||||
registry.register(new PickFirstLoadBalancerProvider());
|
||||
registry.register(new FakeRoundRobinLoadBalancerProvider());
|
||||
AutoConfiguredLoadBalancer lb =
|
||||
(AutoConfiguredLoadBalancer) new AutoConfiguredLoadBalancerFactory(registry)
|
||||
.newLoadBalancer(new TestHelper());
|
||||
Map<String, Object> serviceConfig =
|
||||
parseConfig("{\"loadBalancingConfig\": [ {\"round_robin\": {} } ] }");
|
||||
List<EquivalentAddressGroup> servers =
|
||||
Arrays.asList(
|
||||
new EquivalentAddressGroup(
|
||||
new SocketAddress(){},
|
||||
Attributes.newBuilder().set(GrpcAttributes.ATTR_LB_ADDR_AUTHORITY, "ok").build()),
|
||||
new EquivalentAddressGroup(new SocketAddress(){}));
|
||||
PolicySelection selection = lb.decideLoadBalancerProvider(servers, serviceConfig);
|
||||
|
||||
assertThat(selection.provider).isInstanceOf(FakeRoundRobinLoadBalancerProvider.class);
|
||||
assertThat(selection.config).isNull();
|
||||
verify(channelLogger).log(
|
||||
eq(ChannelLogLevel.ERROR),
|
||||
startsWith("Found balancer addresses but grpclb runtime is missing"));
|
||||
|
||||
// Called for the second time, the warning is only logged once
|
||||
selection = lb.decideLoadBalancerProvider(servers, serviceConfig);
|
||||
|
||||
assertThat(selection.provider).isInstanceOf(FakeRoundRobinLoadBalancerProvider.class);
|
||||
// Balancer addresses are filtered out in the server list passed to round_robin
|
||||
assertThat(selection.serverList).isEqualTo(Collections.singletonList(servers.get(1)));
|
||||
assertThat(selection.config).isNull();
|
||||
verifyNoMoreInteractions(channelLogger);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decideLoadBalancerProvider_grpclbProviderNotFound_noBackendAddress()
|
||||
throws Exception {
|
||||
LoadBalancerRegistry registry = new LoadBalancerRegistry();
|
||||
registry.register(new PickFirstLoadBalancerProvider());
|
||||
registry.register(new FakeRoundRobinLoadBalancerProvider());
|
||||
AutoConfiguredLoadBalancer lb =
|
||||
(AutoConfiguredLoadBalancer) new AutoConfiguredLoadBalancerFactory(registry)
|
||||
.newLoadBalancer(new TestHelper());
|
||||
Map<String, Object> serviceConfig =
|
||||
parseConfig("{\"loadBalancingConfig\": [ {\"round_robin\": {} } ] }");
|
||||
List<EquivalentAddressGroup> servers =
|
||||
Collections.singletonList(
|
||||
new EquivalentAddressGroup(
|
||||
new SocketAddress(){},
|
||||
Attributes.EMPTY));
|
||||
PolicySelection selection = AutoConfiguredLoadBalancerFactory.decideLoadBalancerProvider(
|
||||
servers, serviceConfig, channelLogger);
|
||||
Attributes.newBuilder().set(GrpcAttributes.ATTR_LB_ADDR_AUTHORITY, "ok").build()));
|
||||
try {
|
||||
lb.decideLoadBalancerProvider(servers, serviceConfig);
|
||||
fail("Should throw");
|
||||
} catch (PolicyException e) {
|
||||
assertThat(e.getMessage())
|
||||
.isEqualTo("Received ONLY balancer addresses but grpclb runtime is missing");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decideLoadBalancerProvider_serviceConfigLbPolicyOverridesDefault() throws Exception {
|
||||
AutoConfiguredLoadBalancer lb =
|
||||
(AutoConfiguredLoadBalancer) lbf.newLoadBalancer(new TestHelper());
|
||||
Map<String, Object> serviceConfig = new HashMap<String, Object>();
|
||||
serviceConfig.put("loadBalancingPolicy", "round_robin");
|
||||
List<EquivalentAddressGroup> servers =
|
||||
Collections.singletonList(new EquivalentAddressGroup(new SocketAddress(){}));
|
||||
PolicySelection selection = lb.decideLoadBalancerProvider(servers, serviceConfig);
|
||||
|
||||
assertThat(selection.provider.getClass().getName()).isEqualTo(
|
||||
"io.grpc.util.SecretRoundRobinLoadBalancerProvider$Provider");
|
||||
|
|
@ -359,34 +447,31 @@ public class AutoConfiguredLoadBalancerFactoryTest {
|
|||
|
||||
@Test
|
||||
public void decideLoadBalancerProvider_serviceConfigLbConfigOverridesDefault() throws Exception {
|
||||
AutoConfiguredLoadBalancer lb =
|
||||
(AutoConfiguredLoadBalancer) lbf.newLoadBalancer(new TestHelper());
|
||||
Map<String, Object> serviceConfig =
|
||||
parseConfig("{\"loadBalancingConfig\": [ {\"round_robin\": {\"setting1\": \"high\"} } ] }");
|
||||
List<EquivalentAddressGroup> servers =
|
||||
Collections.singletonList(
|
||||
new EquivalentAddressGroup(
|
||||
new SocketAddress(){},
|
||||
Attributes.EMPTY));
|
||||
PolicySelection selection = AutoConfiguredLoadBalancerFactory.decideLoadBalancerProvider(
|
||||
servers, serviceConfig, channelLogger);
|
||||
Collections.singletonList(new EquivalentAddressGroup(new SocketAddress(){}));
|
||||
PolicySelection selection = lb.decideLoadBalancerProvider(servers, serviceConfig);
|
||||
|
||||
assertThat(selection.provider.getClass().getName()).isEqualTo(
|
||||
"io.grpc.util.SecretRoundRobinLoadBalancerProvider$Provider");
|
||||
assertThat(selection.serverList).isEqualTo(servers);
|
||||
assertThat(selection.config).isEqualTo(Collections.singletonMap("setting1", "high"));
|
||||
verifyZeroInteractions(channelLogger);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decideLoadBalancerProvider_serviceConfigLbPolicyFailsOnUnknown() {
|
||||
AutoConfiguredLoadBalancer lb =
|
||||
(AutoConfiguredLoadBalancer) lbf.newLoadBalancer(new TestHelper());
|
||||
Map<String, Object> serviceConfig = new HashMap<String, Object>();
|
||||
serviceConfig.put("loadBalancingPolicy", "MAGIC_BALANCER");
|
||||
List<EquivalentAddressGroup> servers =
|
||||
Collections.singletonList(
|
||||
new EquivalentAddressGroup(
|
||||
new SocketAddress(){},
|
||||
Attributes.EMPTY));
|
||||
Collections.singletonList(new EquivalentAddressGroup(new SocketAddress(){}));
|
||||
try {
|
||||
AutoConfiguredLoadBalancerFactory.decideLoadBalancerProvider(
|
||||
servers, serviceConfig, channelLogger);
|
||||
lb.decideLoadBalancerProvider(servers, serviceConfig);
|
||||
fail();
|
||||
} catch (PolicyException e) {
|
||||
assertThat(e.getMessage()).isEqualTo(
|
||||
|
|
@ -396,16 +481,14 @@ public class AutoConfiguredLoadBalancerFactoryTest {
|
|||
|
||||
@Test
|
||||
public void decideLoadBalancerProvider_serviceConfigLbConfigFailsOnUnknown() throws Exception {
|
||||
AutoConfiguredLoadBalancer lb =
|
||||
(AutoConfiguredLoadBalancer) lbf.newLoadBalancer(new TestHelper());
|
||||
Map<String, Object> serviceConfig =
|
||||
parseConfig("{\"loadBalancingConfig\": [ {\"magic_balancer\": {} } ] }");
|
||||
List<EquivalentAddressGroup> servers =
|
||||
Collections.singletonList(
|
||||
new EquivalentAddressGroup(
|
||||
new SocketAddress(){},
|
||||
Attributes.EMPTY));
|
||||
Collections.singletonList(new EquivalentAddressGroup(new SocketAddress(){}));
|
||||
try {
|
||||
AutoConfiguredLoadBalancerFactory.decideLoadBalancerProvider(
|
||||
servers, serviceConfig, channelLogger);
|
||||
lb.decideLoadBalancerProvider(servers, serviceConfig);
|
||||
fail();
|
||||
} catch (PolicyException e) {
|
||||
assertThat(e.getMessage()).isEqualTo(
|
||||
|
|
@ -415,19 +498,18 @@ public class AutoConfiguredLoadBalancerFactoryTest {
|
|||
|
||||
@Test
|
||||
public void decideLoadBalancerProvider_serviceConfigLbConfigSkipUnknown() throws Exception {
|
||||
AutoConfiguredLoadBalancer lb =
|
||||
(AutoConfiguredLoadBalancer) lbf.newLoadBalancer(new TestHelper());
|
||||
Map<String, Object> serviceConfig =
|
||||
parseConfig(
|
||||
"{\"loadBalancingConfig\": [ {\"magic_balancer\": {} }, {\"round_robin\": {} } ] }");
|
||||
List<EquivalentAddressGroup> servers =
|
||||
Collections.singletonList(
|
||||
new EquivalentAddressGroup(
|
||||
new SocketAddress(){},
|
||||
Attributes.EMPTY));
|
||||
PolicySelection selection = AutoConfiguredLoadBalancerFactory.decideLoadBalancerProvider(
|
||||
servers, serviceConfig, channelLogger);
|
||||
Collections.singletonList(new EquivalentAddressGroup(new SocketAddress(){}));
|
||||
PolicySelection selection = lb.decideLoadBalancerProvider(servers, serviceConfig);
|
||||
|
||||
assertThat(selection.provider.getClass().getName()).isEqualTo(
|
||||
"io.grpc.util.SecretRoundRobinLoadBalancerProvider$Provider");
|
||||
assertThat(selection.serverList).isEqualTo(servers);
|
||||
assertThat(selection.config).isEqualTo(Collections.emptyMap());
|
||||
verify(channelLogger).log(
|
||||
eq(ChannelLogLevel.DEBUG),
|
||||
|
|
@ -439,8 +521,7 @@ public class AutoConfiguredLoadBalancerFactoryTest {
|
|||
public void channelTracing_lbPolicyChanged() {
|
||||
final FakeClock clock = new FakeClock();
|
||||
List<EquivalentAddressGroup> servers =
|
||||
Collections.singletonList(
|
||||
new EquivalentAddressGroup(new SocketAddress(){}, Attributes.EMPTY));
|
||||
Collections.singletonList(new EquivalentAddressGroup(new SocketAddress(){}));
|
||||
Helper helper = new TestHelper() {
|
||||
@Override
|
||||
public Subchannel createSubchannel(List<EquivalentAddressGroup> addrs, Attributes attrs) {
|
||||
|
|
@ -630,4 +711,28 @@ public class AutoConfiguredLoadBalancerFactoryTest {
|
|||
return testLbBalancer;
|
||||
}
|
||||
}
|
||||
|
||||
private final class FakeRoundRobinLoadBalancerProvider extends LoadBalancerProvider {
|
||||
static final String POLICY_NAME = "round_robin";
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPolicyName() {
|
||||
return POLICY_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoadBalancer newLoadBalancer(Helper helper) {
|
||||
return testLbBalancer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue