• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 io.grpc.Internal;
23 import io.grpc.LoadBalancer;
24 import io.grpc.LoadBalancer.Helper;
25 import io.grpc.LoadBalancerProvider;
26 import io.grpc.NameResolver.ConfigOrError;
27 import io.grpc.Status;
28 import io.grpc.internal.ServiceConfigUtil.PolicySelection;
29 import io.grpc.xds.Bootstrapper.ServerInfo;
30 import io.grpc.xds.EnvoyServerProtoData.OutlierDetection;
31 import io.grpc.xds.EnvoyServerProtoData.UpstreamTlsContext;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Objects;
35 import javax.annotation.Nullable;
36 
37 /**
38  * The provider for the cluster_resolver load balancing policy. This class should not be directly
39  * referenced in code.  The policy should be accessed through
40  * {@link io.grpc.LoadBalancerRegistry#getProvider} with the name "cluster_resolver_experimental".
41  */
42 @Internal
43 public final class ClusterResolverLoadBalancerProvider extends LoadBalancerProvider {
44 
45   @Override
isAvailable()46   public boolean isAvailable() {
47     return true;
48   }
49 
50   @Override
getPriority()51   public int getPriority() {
52     return 5;
53   }
54 
55   @Override
getPolicyName()56   public String getPolicyName() {
57     return XdsLbPolicies.CLUSTER_RESOLVER_POLICY_NAME;
58   }
59 
60   @Override
parseLoadBalancingPolicyConfig(Map<String, ?> rawLoadBalancingPolicyConfig)61   public ConfigOrError parseLoadBalancingPolicyConfig(Map<String, ?> rawLoadBalancingPolicyConfig) {
62     return ConfigOrError.fromError(
63         Status.INTERNAL.withDescription(getPolicyName() + " cannot be used from service config"));
64   }
65 
66   @Override
newLoadBalancer(Helper helper)67   public LoadBalancer newLoadBalancer(Helper helper) {
68     return new ClusterResolverLoadBalancer(helper);
69   }
70 
71   static final class ClusterResolverConfig {
72     // Ordered list of clusters to be resolved.
73     final List<DiscoveryMechanism> discoveryMechanisms;
74     // Endpoint-level load balancing policy with config
75     // (round_robin, least_request_experimental or ring_hash_experimental).
76     final PolicySelection lbPolicy;
77 
ClusterResolverConfig(List<DiscoveryMechanism> discoveryMechanisms, PolicySelection lbPolicy)78     ClusterResolverConfig(List<DiscoveryMechanism> discoveryMechanisms, PolicySelection lbPolicy) {
79       this.discoveryMechanisms = checkNotNull(discoveryMechanisms, "discoveryMechanisms");
80       this.lbPolicy = checkNotNull(lbPolicy, "lbPolicy");
81     }
82 
83     @Override
hashCode()84     public int hashCode() {
85       return Objects.hash(discoveryMechanisms, lbPolicy);
86     }
87 
88     @Override
equals(Object o)89     public boolean equals(Object o) {
90       if (this == o) {
91         return true;
92       }
93       if (o == null || getClass() != o.getClass()) {
94         return false;
95       }
96       ClusterResolverConfig that = (ClusterResolverConfig) o;
97       return discoveryMechanisms.equals(that.discoveryMechanisms)
98           && lbPolicy.equals(that.lbPolicy);
99     }
100 
101     @Override
toString()102     public String toString() {
103       return MoreObjects.toStringHelper(this)
104           .add("discoveryMechanisms", discoveryMechanisms)
105           .add("lbPolicy", lbPolicy)
106           .toString();
107     }
108 
109     // Describes the mechanism for a specific cluster.
110     static final class DiscoveryMechanism {
111       // Name of the cluster to resolve.
112       final String cluster;
113       // Type of the cluster.
114       final Type type;
115       // Load reporting server info. Null if not enabled.
116       @Nullable
117       final ServerInfo lrsServerInfo;
118       // Cluster-level max concurrent request threshold. Null if not specified.
119       @Nullable
120       final Long maxConcurrentRequests;
121       // TLS context for connections to endpoints in the cluster.
122       @Nullable
123       final UpstreamTlsContext tlsContext;
124       // Resource name for resolving endpoints via EDS. Only valid for EDS clusters.
125       @Nullable
126       final String edsServiceName;
127       // Hostname for resolving endpoints via DNS. Only valid for LOGICAL_DNS clusters.
128       @Nullable
129       final String dnsHostName;
130       @Nullable
131       final OutlierDetection outlierDetection;
132 
133       enum Type {
134         EDS,
135         LOGICAL_DNS,
136       }
137 
DiscoveryMechanism(String cluster, Type type, @Nullable String edsServiceName, @Nullable String dnsHostName, @Nullable ServerInfo lrsServerInfo, @Nullable Long maxConcurrentRequests, @Nullable UpstreamTlsContext tlsContext, @Nullable OutlierDetection outlierDetection)138       private DiscoveryMechanism(String cluster, Type type, @Nullable String edsServiceName,
139           @Nullable String dnsHostName, @Nullable ServerInfo lrsServerInfo,
140           @Nullable Long maxConcurrentRequests, @Nullable UpstreamTlsContext tlsContext,
141           @Nullable OutlierDetection outlierDetection) {
142         this.cluster = checkNotNull(cluster, "cluster");
143         this.type = checkNotNull(type, "type");
144         this.edsServiceName = edsServiceName;
145         this.dnsHostName = dnsHostName;
146         this.lrsServerInfo = lrsServerInfo;
147         this.maxConcurrentRequests = maxConcurrentRequests;
148         this.tlsContext = tlsContext;
149         this.outlierDetection = outlierDetection;
150       }
151 
forEds(String cluster, @Nullable String edsServiceName, @Nullable ServerInfo lrsServerInfo, @Nullable Long maxConcurrentRequests, @Nullable UpstreamTlsContext tlsContext, OutlierDetection outlierDetection)152       static DiscoveryMechanism forEds(String cluster, @Nullable String edsServiceName,
153           @Nullable ServerInfo lrsServerInfo, @Nullable Long maxConcurrentRequests,
154           @Nullable UpstreamTlsContext tlsContext,
155           OutlierDetection outlierDetection) {
156         return new DiscoveryMechanism(cluster, Type.EDS, edsServiceName, null, lrsServerInfo,
157             maxConcurrentRequests, tlsContext, outlierDetection);
158       }
159 
forLogicalDns(String cluster, String dnsHostName, @Nullable ServerInfo lrsServerInfo, @Nullable Long maxConcurrentRequests, @Nullable UpstreamTlsContext tlsContext)160       static DiscoveryMechanism forLogicalDns(String cluster, String dnsHostName,
161           @Nullable ServerInfo lrsServerInfo, @Nullable Long maxConcurrentRequests,
162           @Nullable UpstreamTlsContext tlsContext) {
163         return new DiscoveryMechanism(cluster, Type.LOGICAL_DNS, null, dnsHostName,
164             lrsServerInfo, maxConcurrentRequests, tlsContext, null);
165       }
166 
167       @Override
hashCode()168       public int hashCode() {
169         return Objects.hash(cluster, type, lrsServerInfo, maxConcurrentRequests, tlsContext,
170             edsServiceName, dnsHostName);
171       }
172 
173       @Override
equals(Object o)174       public boolean equals(Object o) {
175         if (this == o) {
176           return true;
177         }
178         if (o == null || getClass() != o.getClass()) {
179           return false;
180         }
181         DiscoveryMechanism that = (DiscoveryMechanism) o;
182         return cluster.equals(that.cluster)
183             && type == that.type
184             && Objects.equals(edsServiceName, that.edsServiceName)
185             && Objects.equals(dnsHostName, that.dnsHostName)
186             && Objects.equals(lrsServerInfo, that.lrsServerInfo)
187             && Objects.equals(maxConcurrentRequests, that.maxConcurrentRequests)
188             && Objects.equals(tlsContext, that.tlsContext);
189       }
190 
191       @Override
toString()192       public String toString() {
193         MoreObjects.ToStringHelper toStringHelper =
194             MoreObjects.toStringHelper(this)
195                 .add("cluster", cluster)
196                 .add("type", type)
197                 .add("edsServiceName", edsServiceName)
198                 .add("dnsHostName", dnsHostName)
199                 .add("lrsServerInfo", lrsServerInfo)
200                 // Exclude tlsContext as its string representation is cumbersome.
201                 .add("maxConcurrentRequests", maxConcurrentRequests);
202         return toStringHelper.toString();
203       }
204     }
205   }
206 }
207