• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

grpc / grpc-java / #19928

29 Jul 2025 12:36PM UTC coverage: 88.586% (-0.01%) from 88.599%
#19928

push

github

web-flow
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.

34654 of 39119 relevant lines covered (88.59%)

0.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.79
/../xds/src/main/java/io/grpc/xds/CdsLoadBalancerProvider.java
1
/*
2
 * Copyright 2019 The gRPC Authors
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

17
package io.grpc.xds;
18

19
import static com.google.common.base.Preconditions.checkArgument;
20

21
import com.google.common.base.MoreObjects;
22
import io.grpc.Internal;
23
import io.grpc.LoadBalancer;
24
import io.grpc.LoadBalancer.Helper;
25
import io.grpc.LoadBalancerProvider;
26
import io.grpc.LoadBalancerRegistry;
27
import io.grpc.NameResolver.ConfigOrError;
28
import io.grpc.Status;
29
import io.grpc.internal.JsonUtil;
30
import java.util.Map;
31

32
/**
33
 * The provider for the "cds" balancing policy.  This class should not be directly referenced in
34
 * code.  The policy should be accessed through {@link io.grpc.LoadBalancerRegistry#getProvider}
35
 * with the name "cds" (currently "cds_experimental").
36
 */
37
@Internal
38
public class CdsLoadBalancerProvider extends LoadBalancerProvider {
39

40
  @Override
41
  public boolean isAvailable() {
42
    return true;
1✔
43
  }
44

45
  @Override
46
  public int getPriority() {
47
    return 5;
1✔
48
  }
49

50
  @Override
51
  public String getPolicyName() {
52
    return XdsLbPolicies.CDS_POLICY_NAME;
1✔
53
  }
54

55
  private final LoadBalancerRegistry loadBalancerRegistry;
56

57
  public CdsLoadBalancerProvider() {
1✔
58
    this.loadBalancerRegistry = null;
1✔
59
  }
1✔
60

61
  public CdsLoadBalancerProvider(LoadBalancerRegistry loadBalancerRegistry) {
1✔
62
    this.loadBalancerRegistry = loadBalancerRegistry;
1✔
63
  }
1✔
64

65
  @Override
66
  public LoadBalancer newLoadBalancer(Helper helper) {
67
    LoadBalancerRegistry loadBalancerRegistry = this.loadBalancerRegistry;
1✔
68
    if (loadBalancerRegistry == null) {
1✔
69
      loadBalancerRegistry = LoadBalancerRegistry.getDefaultRegistry();
1✔
70
    }
71

72
    return new CdsLoadBalancer2(helper, loadBalancerRegistry);
1✔
73
  }
74

75
  @Override
76
  public ConfigOrError parseLoadBalancingPolicyConfig(
77
      Map<String, ?> rawLoadBalancingPolicyConfig) {
78
    return parseLoadBalancingConfigPolicy(rawLoadBalancingPolicyConfig);
1✔
79
  }
80

81
  /**
82
   * Parses raw load balancing config and returns a {@link ConfigOrError} that contains a
83
   * {@link CdsConfig} if parsing is successful.
84
   */
85
  static ConfigOrError parseLoadBalancingConfigPolicy(Map<String, ?> rawLoadBalancingPolicyConfig) {
86
    try {
87
      String cluster = JsonUtil.getString(rawLoadBalancingPolicyConfig, "cluster");
1✔
88
      Boolean isDynamic = JsonUtil.getBoolean(rawLoadBalancingPolicyConfig, "is_dynamic");
1✔
89
      if (isDynamic == null) {
1✔
90
        isDynamic = Boolean.FALSE;
1✔
91
      }
92
      return ConfigOrError.fromConfig(new CdsConfig(cluster, isDynamic));
1✔
93
    } catch (RuntimeException e) {
×
94
      return ConfigOrError.fromError(
×
95
          Status.UNAVAILABLE.withCause(e).withDescription(
×
96
              "Failed to parse CDS LB config: " + rawLoadBalancingPolicyConfig));
97
    }
98
  }
99

100
  /**
101
   * Represents a successfully parsed and validated LoadBalancingConfig for CDS.
102
   */
103
  static final class CdsConfig {
104

105
    /**
106
     * Name of cluster to query CDS for.
107
     */
108
    final String name;
109
    /**
110
     * Whether this cluster was dynamically chosen, so the XdsDependencyManager may be unaware of
111
     * it without an explicit cluster subscription.
112
     */
113
    final boolean isDynamic;
114

115
    CdsConfig(String name) {
116
      this(name, false);
1✔
117
    }
1✔
118

119
    CdsConfig(String name, boolean isDynamic) {
1✔
120
      checkArgument(name != null && !name.isEmpty(), "name is null or empty");
1✔
121
      this.name = name;
1✔
122
      this.isDynamic = isDynamic;
1✔
123
    }
1✔
124

125
    @Override
126
    public String toString() {
127
      return MoreObjects.toStringHelper(this)
×
128
          .add("name", name)
×
129
          .add("isDynamic", isDynamic)
×
130
          .toString();
×
131
    }
132
  }
133
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc