Skip to content

Commit 6d3ffc7

Browse files
authored
all: refactor select lb policy from a list of raw configs
Refactor to reuse `PolicySelection` and the implementation in `AutoConfiguredLoadBalancerFactory.parseLoadBalancerPolicy()`.
1 parent ec25beb commit 6d3ffc7

File tree

6 files changed

+117
-156
lines changed

6 files changed

+117
-156
lines changed

core/src/main/java/io/grpc/internal/AutoConfiguredLoadBalancerFactory.java

Lines changed: 2 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
import com.google.common.annotations.VisibleForTesting;
2323
import com.google.common.base.MoreObjects;
24-
import com.google.common.base.Objects;
2524
import io.grpc.Attributes;
2625
import io.grpc.ChannelLogger;
2726
import io.grpc.ChannelLogger.ChannelLogLevel;
@@ -40,7 +39,7 @@
4039
import io.grpc.NameResolver.ConfigOrError;
4140
import io.grpc.Status;
4241
import io.grpc.internal.ServiceConfigUtil.LbConfig;
43-
import java.util.ArrayList;
42+
import io.grpc.internal.ServiceConfigUtil.PolicySelection;
4443
import java.util.List;
4544
import java.util.Map;
4645
import javax.annotation.Nullable;
@@ -247,31 +246,7 @@ ConfigOrError parseLoadBalancerPolicy(Map<String, ?> serviceConfig, ChannelLogge
247246
loadBalancerConfigs = ServiceConfigUtil.unwrapLoadBalancingConfigList(rawLbConfigs);
248247
}
249248
if (loadBalancerConfigs != null && !loadBalancerConfigs.isEmpty()) {
250-
List<String> policiesTried = new ArrayList<>();
251-
for (LbConfig lbConfig : loadBalancerConfigs) {
252-
String policy = lbConfig.getPolicyName();
253-
LoadBalancerProvider provider = registry.getProvider(policy);
254-
if (provider == null) {
255-
policiesTried.add(policy);
256-
} else {
257-
if (!policiesTried.isEmpty()) {
258-
channelLogger.log(
259-
ChannelLogLevel.DEBUG,
260-
"{0} specified by Service Config are not available", policiesTried);
261-
}
262-
ConfigOrError parsedLbPolicyConfig =
263-
provider.parseLoadBalancingPolicyConfig(lbConfig.getRawConfigValue());
264-
if (parsedLbPolicyConfig.getError() != null) {
265-
return parsedLbPolicyConfig;
266-
}
267-
return ConfigOrError.fromConfig(
268-
new PolicySelection(
269-
provider, lbConfig.getRawConfigValue(), parsedLbPolicyConfig.getConfig()));
270-
}
271-
}
272-
return ConfigOrError.fromError(
273-
Status.UNKNOWN.withDescription(
274-
"None of " + policiesTried + " specified by Service Config are available."));
249+
return ServiceConfigUtil.selectLbPolicyFromList(loadBalancerConfigs, registry);
275250
}
276251
return null;
277252
} catch (RuntimeException e) {
@@ -289,50 +264,6 @@ private PolicyException(String msg) {
289264
}
290265
}
291266

292-
@VisibleForTesting
293-
static final class PolicySelection {
294-
final LoadBalancerProvider provider;
295-
@Nullable final Map<String, ?> rawConfig;
296-
@Nullable final Object config;
297-
298-
PolicySelection(
299-
LoadBalancerProvider provider,
300-
@Nullable Map<String, ?> rawConfig,
301-
@Nullable Object config) {
302-
this.provider = checkNotNull(provider, "provider");
303-
this.rawConfig = rawConfig;
304-
this.config = config;
305-
}
306-
307-
@Override
308-
public boolean equals(Object o) {
309-
if (this == o) {
310-
return true;
311-
}
312-
if (o == null || getClass() != o.getClass()) {
313-
return false;
314-
}
315-
PolicySelection that = (PolicySelection) o;
316-
return Objects.equal(provider, that.provider)
317-
&& Objects.equal(rawConfig, that.rawConfig)
318-
&& Objects.equal(config, that.config);
319-
}
320-
321-
@Override
322-
public int hashCode() {
323-
return Objects.hashCode(provider, rawConfig, config);
324-
}
325-
326-
@Override
327-
public String toString() {
328-
return MoreObjects.toStringHelper(this)
329-
.add("provider", provider)
330-
.add("rawConfig", rawConfig)
331-
.add("config", config)
332-
.toString();
333-
}
334-
}
335-
336267
private static final class EmptyPicker extends SubchannelPicker {
337268

338269
@Override

core/src/main/java/io/grpc/internal/ServiceConfigUtil.java

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
import com.google.common.base.MoreObjects;
2525
import com.google.common.base.Objects;
2626
import com.google.common.base.VerifyException;
27+
import io.grpc.LoadBalancerProvider;
28+
import io.grpc.LoadBalancerRegistry;
29+
import io.grpc.NameResolver.ConfigOrError;
2730
import io.grpc.Status;
2831
import io.grpc.internal.RetriableStream.Throttle;
2932
import java.util.ArrayList;
@@ -33,6 +36,8 @@
3336
import java.util.Locale;
3437
import java.util.Map;
3538
import java.util.Set;
39+
import java.util.logging.Level;
40+
import java.util.logging.Logger;
3641
import javax.annotation.Nullable;
3742

3843
/**
@@ -323,6 +328,39 @@ public static List<LbConfig> unwrapLoadBalancingConfigList(List<Map<String, ?>>
323328
return Collections.unmodifiableList(result);
324329
}
325330

331+
/**
332+
* Parses and selects a load balancing policy from a non-empty list of raw configs. If selection
333+
* is successful, the returned ConfigOrError object will include a {@link
334+
* ServiceConfigUtil.PolicySelection} as its config value.
335+
*/
336+
public static ConfigOrError selectLbPolicyFromList(
337+
List<LbConfig> lbConfigs, LoadBalancerRegistry lbRegistry) {
338+
List<String> policiesTried = new ArrayList<>();
339+
for (LbConfig lbConfig : lbConfigs) {
340+
String policy = lbConfig.getPolicyName();
341+
LoadBalancerProvider provider = lbRegistry.getProvider(policy);
342+
if (provider == null) {
343+
policiesTried.add(policy);
344+
} else {
345+
if (!policiesTried.isEmpty()) {
346+
Logger.getLogger(ServiceConfigUtil.class.getName()).log(
347+
Level.FINEST,
348+
"{0} specified by Service Config are not available", policiesTried);
349+
}
350+
ConfigOrError parsedLbPolicyConfig =
351+
provider.parseLoadBalancingPolicyConfig(lbConfig.getRawConfigValue());
352+
if (parsedLbPolicyConfig.getError() != null) {
353+
return parsedLbPolicyConfig;
354+
}
355+
return ConfigOrError.fromConfig(new PolicySelection(
356+
provider, lbConfig.rawConfigValue, parsedLbPolicyConfig.getConfig()));
357+
}
358+
}
359+
return ConfigOrError.fromError(
360+
Status.UNKNOWN.withDescription(
361+
"None of " + policiesTried + " specified by Service Config are available."));
362+
}
363+
326364
/**
327365
* A LoadBalancingConfig that includes the policy name (the key) and its raw config value (parsed
328366
* JSON).
@@ -367,4 +405,61 @@ public String toString() {
367405
.toString();
368406
}
369407
}
408+
409+
public static final class PolicySelection {
410+
final LoadBalancerProvider provider;
411+
@Deprecated
412+
@Nullable
413+
final Map<String, ?> rawConfig;
414+
@Nullable
415+
final Object config;
416+
417+
/** Constructs a PolicySelection with selected LB provider, a copy of raw config and the deeply
418+
* parsed LB config. */
419+
public PolicySelection(
420+
LoadBalancerProvider provider,
421+
@Nullable Map<String, ?> rawConfig,
422+
@Nullable Object config) {
423+
this.provider = checkNotNull(provider, "provider");
424+
this.rawConfig = rawConfig;
425+
this.config = config;
426+
}
427+
428+
public LoadBalancerProvider getProvider() {
429+
return provider;
430+
}
431+
432+
@Nullable
433+
public Object getConfig() {
434+
return config;
435+
}
436+
437+
@Override
438+
public boolean equals(Object o) {
439+
if (this == o) {
440+
return true;
441+
}
442+
if (o == null || getClass() != o.getClass()) {
443+
return false;
444+
}
445+
PolicySelection that = (PolicySelection) o;
446+
return Objects.equal(provider, that.provider)
447+
&& Objects.equal(rawConfig, that.rawConfig)
448+
&& Objects.equal(config, that.config);
449+
}
450+
451+
@Override
452+
public int hashCode() {
453+
return Objects.hashCode(provider, rawConfig, config);
454+
}
455+
456+
@Override
457+
public String toString() {
458+
return MoreObjects.toStringHelper(this)
459+
.add("provider", provider)
460+
.add("rawConfig", rawConfig)
461+
.add("config", config)
462+
.toString();
463+
}
464+
}
370465
}

core/src/test/java/io/grpc/internal/AutoConfiguredLoadBalancerFactoryTest.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,10 @@
5151
import io.grpc.Status;
5252
import io.grpc.grpclb.GrpclbLoadBalancerProvider;
5353
import io.grpc.internal.AutoConfiguredLoadBalancerFactory.AutoConfiguredLoadBalancer;
54-
import io.grpc.internal.AutoConfiguredLoadBalancerFactory.PolicySelection;
54+
import io.grpc.internal.ServiceConfigUtil.PolicySelection;
5555
import io.grpc.util.ForwardingLoadBalancerHelper;
5656
import java.net.InetSocketAddress;
5757
import java.net.SocketAddress;
58-
import java.util.ArrayList;
5958
import java.util.Collections;
6059
import java.util.List;
6160
import java.util.Map;
@@ -620,10 +619,6 @@ public void parseLoadBalancerConfig_someProvidesAreNotAvailable() throws Excepti
620619
assertThat(parsed).isNotNull();
621620
assertThat(parsed.getConfig()).isNotNull();
622621
assertThat(((PolicySelection) parsed.getConfig()).config).isNotNull();
623-
verify(channelLogger).log(
624-
eq(ChannelLogLevel.DEBUG),
625-
eq("{0} specified by Service Config are not available"),
626-
eq(new ArrayList<>(Collections.singletonList("magic_balancer"))));
627622
}
628623

629624
@Test

core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,10 @@
102102
import io.grpc.Status;
103103
import io.grpc.Status.Code;
104104
import io.grpc.StringMarshaller;
105-
import io.grpc.internal.AutoConfiguredLoadBalancerFactory.PolicySelection;
106105
import io.grpc.internal.ClientTransportFactory.ClientTransportOptions;
107106
import io.grpc.internal.InternalSubchannel.TransportLogger;
108107
import io.grpc.internal.ManagedChannelImpl.ScParser;
108+
import io.grpc.internal.ServiceConfigUtil.PolicySelection;
109109
import io.grpc.internal.TestUtils.MockClientTransportInfo;
110110
import io.grpc.stub.ClientCalls;
111111
import io.grpc.testing.TestMethodDescriptors;

xds/src/main/java/io/grpc/xds/XdsRoutingLoadBalancerProvider.java

Lines changed: 11 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,14 @@
3030
import io.grpc.internal.JsonUtil;
3131
import io.grpc.internal.ServiceConfigUtil;
3232
import io.grpc.internal.ServiceConfigUtil.LbConfig;
33+
import io.grpc.internal.ServiceConfigUtil.PolicySelection;
3334
import java.util.ArrayList;
3435
import java.util.HashSet;
3536
import java.util.LinkedHashMap;
3637
import java.util.List;
3738
import java.util.Map;
3839
import java.util.Objects;
3940
import java.util.Set;
40-
import java.util.logging.Level;
41-
import java.util.logging.Logger;
4241
import javax.annotation.Nullable;
4342

4443
/**
@@ -50,8 +49,6 @@
5049
public final class XdsRoutingLoadBalancerProvider extends LoadBalancerProvider {
5150

5251
static final String XDS_ROUTING_POLICY_NAME = "xds_routing_experimental";
53-
private static final Logger logger =
54-
Logger.getLogger(XdsRoutingLoadBalancerProvider.class.getName());
5552

5653
@Nullable
5754
private final LoadBalancerRegistry lbRegistry;
@@ -100,7 +97,7 @@ public ConfigOrError parseLoadBalancingPolicyConfig(Map<String, ?> rawConfig) {
10097
return ConfigOrError.fromError(Status.INTERNAL.withDescription(
10198
"No actions provided for xds_routing LB policy: " + rawConfig));
10299
}
103-
Map<String, ChildConfig> parsedActions = new LinkedHashMap<>();
100+
Map<String, PolicySelection> parsedActions = new LinkedHashMap<>();
104101
for (String name : actions.keySet()) {
105102
Map<String, ?> rawAction = JsonUtil.getObject(actions, name);
106103
if (rawAction == null) {
@@ -114,36 +111,14 @@ public ConfigOrError parseLoadBalancingPolicyConfig(Map<String, ?> rawConfig) {
114111
"No child policy for action " + name + " in xds_routing LB policy: "
115112
+ rawConfig));
116113
}
117-
boolean targetParsingSucceeded = false;
118-
for (LbConfig lbConfig : childConfigCandidates) {
119-
String policyName = lbConfig.getPolicyName();
120-
LoadBalancerProvider lbProvider = loadBalancerRegistry().getProvider(policyName);
121-
if (lbProvider == null) {
122-
logger.log(
123-
Level.FINEST,
124-
"The policy for {0} is not available in xds_routing LB policy: {1}",
125-
new Object[]{policyName, rawConfig});
126-
} else {
127-
ConfigOrError parsedLbPolicyConfig = lbProvider
128-
.parseLoadBalancingPolicyConfig(lbConfig.getRawConfigValue());
129-
if (parsedLbPolicyConfig.getError() != null) {
130-
// Based on service config error-handling spec, if the chosen config is found invalid
131-
// while other configs that come later were valid, the gRPC config would still be
132-
// considered invalid as a whole.
133-
return parsedLbPolicyConfig;
134-
}
135-
parsedActions.put(
136-
name,
137-
new ChildConfig(policyName, parsedLbPolicyConfig.getConfig()));
138-
targetParsingSucceeded = true;
139-
break;
140-
}
141-
}
142-
if (!targetParsingSucceeded) {
143-
return ConfigOrError.fromError(Status.INTERNAL.withDescription(
144-
"No child policy available for action " + name + " in xds_routing LB policy: "
145-
+ rawConfig));
114+
115+
ConfigOrError selectedConfigOrError =
116+
ServiceConfigUtil.selectLbPolicyFromList(childConfigCandidates, loadBalancerRegistry());
117+
if (selectedConfigOrError.getError() != null) {
118+
return selectedConfigOrError;
146119
}
120+
121+
parsedActions.put(name, (PolicySelection) selectedConfigOrError.getConfig());
147122
}
148123

149124
List<Map<String, ?>> routes = JsonUtil.getListOfObjects(rawConfig, "route");
@@ -204,15 +179,14 @@ public ConfigOrError parseLoadBalancingPolicyConfig(Map<String, ?> rawConfig) {
204179
static final class XdsRoutingConfig {
205180

206181
final List<Route> routes;
207-
final Map<String, ChildConfig> actions;
182+
final Map<String, PolicySelection> actions;
208183

209184
/**
210185
* Constructs a deeply parsed xds_routing config with the given non-empty list of routes, the
211186
* action of each of which is provided by the given map of actions.
212187
*/
213188
@VisibleForTesting
214-
XdsRoutingConfig(List<Route> routes,
215-
Map<String, ChildConfig> actions) {
189+
XdsRoutingConfig(List<Route> routes, Map<String, PolicySelection> actions) {
216190
this.routes = ImmutableList.copyOf(routes);
217191
this.actions = ImmutableMap.copyOf(actions);
218192
}
@@ -323,42 +297,4 @@ public String toString() {
323297
.toString();
324298
}
325299
}
326-
327-
static final class ChildConfig {
328-
329-
final String policyName;
330-
final Object config; // Parsed config.
331-
332-
@VisibleForTesting
333-
ChildConfig(String policyName, Object config) {
334-
this.policyName = policyName;
335-
this.config = config;
336-
}
337-
338-
@Override
339-
public boolean equals(Object o) {
340-
if (this == o) {
341-
return true;
342-
}
343-
if (o == null || getClass() != o.getClass()) {
344-
return false;
345-
}
346-
ChildConfig that = (ChildConfig) o;
347-
return Objects.equals(policyName, that.policyName)
348-
&& Objects.equals(config, that.config);
349-
}
350-
351-
@Override
352-
public int hashCode() {
353-
return Objects.hash(policyName, config);
354-
}
355-
356-
@Override
357-
public String toString() {
358-
return MoreObjects.toStringHelper(this)
359-
.add("policyName", policyName)
360-
.add("config", config)
361-
.toString();
362-
}
363-
}
364300
}

0 commit comments

Comments
 (0)