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

grpc / grpc-java / #20015

13 Oct 2025 07:57AM UTC coverage: 88.57% (+0.02%) from 88.552%
#20015

push

github

web-flow
xds: ORCA to LRS propagation changes (#12203)

Implements gRFC A85 (https://github.com/grpc/proposal/pull/454).

34925 of 39432 relevant lines covered (88.57%)

0.89 hits per line

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

96.0
/../xds/src/main/java/io/grpc/xds/ClusterResolverLoadBalancerProvider.java
1
/*
2
 * Copyright 2020 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.checkNotNull;
20

21
import com.google.common.base.MoreObjects;
22
import com.google.common.collect.ImmutableMap;
23
import com.google.protobuf.Struct;
24
import io.grpc.Internal;
25
import io.grpc.LoadBalancer;
26
import io.grpc.LoadBalancer.Helper;
27
import io.grpc.LoadBalancerProvider;
28
import io.grpc.LoadBalancerRegistry;
29
import io.grpc.NameResolver.ConfigOrError;
30
import io.grpc.Status;
31
import io.grpc.xds.EnvoyServerProtoData.OutlierDetection;
32
import io.grpc.xds.EnvoyServerProtoData.UpstreamTlsContext;
33
import io.grpc.xds.client.BackendMetricPropagation;
34
import io.grpc.xds.client.Bootstrapper.ServerInfo;
35
import java.util.Map;
36
import java.util.Objects;
37
import javax.annotation.Nullable;
38

39
/**
40
 * The provider for the cluster_resolver load balancing policy. This class should not be directly
41
 * referenced in code.  The policy should be accessed through
42
 * {@link io.grpc.LoadBalancerRegistry#getProvider} with the name "cluster_resolver_experimental".
43
 */
44
@Internal
45
public final class ClusterResolverLoadBalancerProvider extends LoadBalancerProvider {
46
  private final LoadBalancerRegistry lbRegistry;
47

48
  public ClusterResolverLoadBalancerProvider() {
1✔
49
    this.lbRegistry = null;
1✔
50
  }
1✔
51

52
  ClusterResolverLoadBalancerProvider(LoadBalancerRegistry lbRegistry) {
1✔
53
    this.lbRegistry = checkNotNull(lbRegistry, "lbRegistry");
1✔
54
  }
1✔
55

56
  @Override
57
  public boolean isAvailable() {
58
    return true;
1✔
59
  }
60

61
  @Override
62
  public int getPriority() {
63
    return 5;
1✔
64
  }
65

66
  @Override
67
  public String getPolicyName() {
68
    return XdsLbPolicies.CLUSTER_RESOLVER_POLICY_NAME;
1✔
69
  }
70

71
  @Override
72
  public ConfigOrError parseLoadBalancingPolicyConfig(Map<String, ?> rawLoadBalancingPolicyConfig) {
73
    return ConfigOrError.fromError(
×
74
        Status.INTERNAL.withDescription(getPolicyName() + " cannot be used from service config"));
×
75
  }
76

77
  @Override
78
  public LoadBalancer newLoadBalancer(Helper helper) {
79
    LoadBalancerRegistry lbRegistry = this.lbRegistry;
1✔
80
    if (lbRegistry == null) {
1✔
81
      lbRegistry = LoadBalancerRegistry.getDefaultRegistry();
1✔
82
    }
83
    return new ClusterResolverLoadBalancer(helper, lbRegistry);
1✔
84
  }
85

86
  static final class ClusterResolverConfig {
87
    // Cluster to be resolved.
88
    final DiscoveryMechanism discoveryMechanism;
89
    // GracefulSwitch configuration
90
    final Object lbConfig;
91
    private final boolean isHttp11ProxyAvailable;
92

93
    ClusterResolverConfig(DiscoveryMechanism discoveryMechanism, Object lbConfig,
94
        boolean isHttp11ProxyAvailable) {
1✔
95
      this.discoveryMechanism = checkNotNull(discoveryMechanism, "discoveryMechanism");
1✔
96
      this.lbConfig = checkNotNull(lbConfig, "lbConfig");
1✔
97
      this.isHttp11ProxyAvailable = isHttp11ProxyAvailable;
1✔
98
    }
1✔
99

100
    boolean isHttp11ProxyAvailable() {
101
      return isHttp11ProxyAvailable;
1✔
102
    }
103

104
    @Override
105
    public int hashCode() {
106
      return Objects.hash(discoveryMechanism, lbConfig, isHttp11ProxyAvailable);
1✔
107
    }
108

109
    @Override
110
    public boolean equals(Object o) {
111
      if (this == o) {
1✔
112
        return true;
1✔
113
      }
114
      if (o == null || getClass() != o.getClass()) {
1✔
115
        return false;
1✔
116
      }
117
      ClusterResolverConfig that = (ClusterResolverConfig) o;
1✔
118
      return discoveryMechanism.equals(that.discoveryMechanism)
1✔
119
          && lbConfig.equals(that.lbConfig)
1✔
120
          && isHttp11ProxyAvailable == that.isHttp11ProxyAvailable;
121
    }
122

123
    @Override
124
    public String toString() {
125
      return MoreObjects.toStringHelper(this)
1✔
126
          .add("discoveryMechanism", discoveryMechanism)
1✔
127
          .add("lbConfig", lbConfig)
1✔
128
          .add("isHttp11ProxyAvailable", isHttp11ProxyAvailable)
1✔
129
          .toString();
1✔
130
    }
131

132
    // Describes the mechanism for a specific cluster.
133
    static final class DiscoveryMechanism {
134
      // Name of the cluster to resolve.
135
      final String cluster;
136
      // Type of the cluster.
137
      final Type type;
138
      // Load reporting server info. Null if not enabled.
139
      @Nullable
140
      final ServerInfo lrsServerInfo;
141
      // Cluster-level max concurrent request threshold. Null if not specified.
142
      @Nullable
143
      final Long maxConcurrentRequests;
144
      // TLS context for connections to endpoints in the cluster.
145
      @Nullable
146
      final UpstreamTlsContext tlsContext;
147
      // Resource name for resolving endpoints via EDS. Only valid for EDS clusters.
148
      @Nullable
149
      final String edsServiceName;
150
      // Hostname for resolving endpoints via DNS. Only valid for LOGICAL_DNS clusters.
151
      @Nullable
152
      final String dnsHostName;
153
      @Nullable
154
      final OutlierDetection outlierDetection;
155
      final Map<String, Struct> filterMetadata;
156
      @Nullable
157
      final BackendMetricPropagation backendMetricPropagation;
158

159
      enum Type {
1✔
160
        EDS,
1✔
161
        LOGICAL_DNS,
1✔
162
      }
163

164
      private DiscoveryMechanism(String cluster, Type type, @Nullable String edsServiceName,
165
          @Nullable String dnsHostName, @Nullable ServerInfo lrsServerInfo,
166
          @Nullable Long maxConcurrentRequests, @Nullable UpstreamTlsContext tlsContext,
167
          Map<String, Struct> filterMetadata, @Nullable OutlierDetection outlierDetection,
168
          @Nullable BackendMetricPropagation backendMetricPropagation) {
1✔
169
        this.cluster = checkNotNull(cluster, "cluster");
1✔
170
        this.type = checkNotNull(type, "type");
1✔
171
        this.edsServiceName = edsServiceName;
1✔
172
        this.dnsHostName = dnsHostName;
1✔
173
        this.lrsServerInfo = lrsServerInfo;
1✔
174
        this.maxConcurrentRequests = maxConcurrentRequests;
1✔
175
        this.tlsContext = tlsContext;
1✔
176
        this.filterMetadata = ImmutableMap.copyOf(checkNotNull(filterMetadata, "filterMetadata"));
1✔
177
        this.outlierDetection = outlierDetection;
1✔
178
        this.backendMetricPropagation = backendMetricPropagation;
1✔
179
      }
1✔
180

181
      static DiscoveryMechanism forEds(String cluster, @Nullable String edsServiceName,
182
          @Nullable ServerInfo lrsServerInfo, @Nullable Long maxConcurrentRequests,
183
          @Nullable UpstreamTlsContext tlsContext, Map<String, Struct> filterMetadata,
184
          OutlierDetection outlierDetection,
185
          @Nullable BackendMetricPropagation backendMetricPropagation) {
186
        return new DiscoveryMechanism(cluster, Type.EDS, edsServiceName,
1✔
187
            null, lrsServerInfo, maxConcurrentRequests, tlsContext,
188
            filterMetadata, outlierDetection, backendMetricPropagation);
189
      }
190

191
      static DiscoveryMechanism forLogicalDns(String cluster, String dnsHostName,
192
          @Nullable ServerInfo lrsServerInfo, @Nullable Long maxConcurrentRequests,
193
          @Nullable UpstreamTlsContext tlsContext, Map<String, Struct> filterMetadata,
194
          @Nullable BackendMetricPropagation backendMetricPropagation) {
195
        return new DiscoveryMechanism(cluster, Type.LOGICAL_DNS, null, dnsHostName,
1✔
196
            lrsServerInfo, maxConcurrentRequests, tlsContext, filterMetadata, null,
197
            backendMetricPropagation);
198
      }
199

200
      @Override
201
      public int hashCode() {
202
        return Objects.hash(cluster, type, lrsServerInfo, maxConcurrentRequests, tlsContext,
1✔
203
            edsServiceName, dnsHostName, filterMetadata,
204
            outlierDetection, backendMetricPropagation);
205
      }
206

207
      @Override
208
      public boolean equals(Object o) {
209
        if (this == o) {
1✔
210
          return true;
1✔
211
        }
212
        if (o == null || getClass() != o.getClass()) {
1✔
213
          return false;
×
214
        }
215
        DiscoveryMechanism that = (DiscoveryMechanism) o;
1✔
216
        return cluster.equals(that.cluster)
1✔
217
            && type == that.type
218
            && Objects.equals(edsServiceName, that.edsServiceName)
1✔
219
            && Objects.equals(dnsHostName, that.dnsHostName)
1✔
220
            && Objects.equals(lrsServerInfo, that.lrsServerInfo)
1✔
221
            && Objects.equals(maxConcurrentRequests, that.maxConcurrentRequests)
1✔
222
            && Objects.equals(tlsContext, that.tlsContext)
1✔
223
            && Objects.equals(filterMetadata, that.filterMetadata)
1✔
224
            && Objects.equals(outlierDetection, that.outlierDetection);
1✔
225
      }
226

227
      @Override
228
      public String toString() {
229
        MoreObjects.ToStringHelper toStringHelper =
1✔
230
            MoreObjects.toStringHelper(this)
1✔
231
                .add("cluster", cluster)
1✔
232
                .add("type", type)
1✔
233
                .add("edsServiceName", edsServiceName)
1✔
234
                .add("dnsHostName", dnsHostName)
1✔
235
                .add("lrsServerInfo", lrsServerInfo)
1✔
236
                // Exclude tlsContext as its string representation is cumbersome.
237
                .add("maxConcurrentRequests", maxConcurrentRequests)
1✔
238
                .add("filterMetadata", filterMetadata)
1✔
239
                // Exclude outlierDetection as its string representation is long.
240
                ;
241
        return toStringHelper.toString();
1✔
242
      }
243
    }
244
  }
245
}
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

© 2025 Coveralls, Inc