google.golang.org/grpc@v1.62.1/resolver/resolver.go (about) 1 /* 2 * 3 * Copyright 2017 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 // Package resolver defines APIs for name resolution in gRPC. 20 // All APIs in this package are experimental. 21 package resolver 22 23 import ( 24 "context" 25 "fmt" 26 "net" 27 "net/url" 28 "strings" 29 30 "google.golang.org/grpc/attributes" 31 "google.golang.org/grpc/credentials" 32 "google.golang.org/grpc/serviceconfig" 33 ) 34 35 var ( 36 // m is a map from scheme to resolver builder. 37 m = make(map[string]Builder) 38 // defaultScheme is the default scheme to use. 39 defaultScheme = "passthrough" 40 ) 41 42 // TODO(bar) install dns resolver in init(){}. 43 44 // Register registers the resolver builder to the resolver map. b.Scheme will 45 // be used as the scheme registered with this builder. The registry is case 46 // sensitive, and schemes should not contain any uppercase characters. 47 // 48 // NOTE: this function must only be called during initialization time (i.e. in 49 // an init() function), and is not thread-safe. If multiple Resolvers are 50 // registered with the same name, the one registered last will take effect. 51 func Register(b Builder) { 52 m[b.Scheme()] = b 53 } 54 55 // Get returns the resolver builder registered with the given scheme. 56 // 57 // If no builder is register with the scheme, nil will be returned. 58 func Get(scheme string) Builder { 59 if b, ok := m[scheme]; ok { 60 return b 61 } 62 return nil 63 } 64 65 // SetDefaultScheme sets the default scheme that will be used. The default 66 // default scheme is "passthrough". 67 // 68 // NOTE: this function must only be called during initialization time (i.e. in 69 // an init() function), and is not thread-safe. The scheme set last overrides 70 // previously set values. 71 func SetDefaultScheme(scheme string) { 72 defaultScheme = scheme 73 } 74 75 // GetDefaultScheme gets the default scheme that will be used. 76 func GetDefaultScheme() string { 77 return defaultScheme 78 } 79 80 // Address represents a server the client connects to. 81 // 82 // # Experimental 83 // 84 // Notice: This type is EXPERIMENTAL and may be changed or removed in a 85 // later release. 86 type Address struct { 87 // Addr is the server address on which a connection will be established. 88 Addr string 89 90 // ServerName is the name of this address. 91 // If non-empty, the ServerName is used as the transport certification authority for 92 // the address, instead of the hostname from the Dial target string. In most cases, 93 // this should not be set. 94 // 95 // WARNING: ServerName must only be populated with trusted values. It 96 // is insecure to populate it with data from untrusted inputs since untrusted 97 // values could be used to bypass the authority checks performed by TLS. 98 ServerName string 99 100 // Attributes contains arbitrary data about this address intended for 101 // consumption by the SubConn. 102 Attributes *attributes.Attributes 103 104 // BalancerAttributes contains arbitrary data about this address intended 105 // for consumption by the LB policy. These attributes do not affect SubConn 106 // creation, connection establishment, handshaking, etc. 107 // 108 // Deprecated: when an Address is inside an Endpoint, this field should not 109 // be used, and it will eventually be removed entirely. 110 BalancerAttributes *attributes.Attributes 111 112 // Metadata is the information associated with Addr, which may be used 113 // to make load balancing decision. 114 // 115 // Deprecated: use Attributes instead. 116 Metadata any 117 } 118 119 // Equal returns whether a and o are identical. Metadata is compared directly, 120 // not with any recursive introspection. 121 // 122 // This method compares all fields of the address. When used to tell apart 123 // addresses during subchannel creation or connection establishment, it might be 124 // more appropriate for the caller to implement custom equality logic. 125 func (a Address) Equal(o Address) bool { 126 return a.Addr == o.Addr && a.ServerName == o.ServerName && 127 a.Attributes.Equal(o.Attributes) && 128 a.BalancerAttributes.Equal(o.BalancerAttributes) && 129 a.Metadata == o.Metadata 130 } 131 132 // String returns JSON formatted string representation of the address. 133 func (a Address) String() string { 134 var sb strings.Builder 135 sb.WriteString(fmt.Sprintf("{Addr: %q, ", a.Addr)) 136 sb.WriteString(fmt.Sprintf("ServerName: %q, ", a.ServerName)) 137 if a.Attributes != nil { 138 sb.WriteString(fmt.Sprintf("Attributes: %v, ", a.Attributes.String())) 139 } 140 if a.BalancerAttributes != nil { 141 sb.WriteString(fmt.Sprintf("BalancerAttributes: %v", a.BalancerAttributes.String())) 142 } 143 sb.WriteString("}") 144 return sb.String() 145 } 146 147 // BuildOptions includes additional information for the builder to create 148 // the resolver. 149 type BuildOptions struct { 150 // DisableServiceConfig indicates whether a resolver implementation should 151 // fetch service config data. 152 DisableServiceConfig bool 153 // DialCreds is the transport credentials used by the ClientConn for 154 // communicating with the target gRPC service (set via 155 // WithTransportCredentials). In cases where a name resolution service 156 // requires the same credentials, the resolver may use this field. In most 157 // cases though, it is not appropriate, and this field may be ignored. 158 DialCreds credentials.TransportCredentials 159 // CredsBundle is the credentials bundle used by the ClientConn for 160 // communicating with the target gRPC service (set via 161 // WithCredentialsBundle). In cases where a name resolution service 162 // requires the same credentials, the resolver may use this field. In most 163 // cases though, it is not appropriate, and this field may be ignored. 164 CredsBundle credentials.Bundle 165 // Dialer is the custom dialer used by the ClientConn for dialling the 166 // target gRPC service (set via WithDialer). In cases where a name 167 // resolution service requires the same dialer, the resolver may use this 168 // field. In most cases though, it is not appropriate, and this field may 169 // be ignored. 170 Dialer func(context.Context, string) (net.Conn, error) 171 // Authority is the effective authority of the clientconn for which the 172 // resolver is built. 173 Authority string 174 } 175 176 // An Endpoint is one network endpoint, or server, which may have multiple 177 // addresses with which it can be accessed. 178 type Endpoint struct { 179 // Addresses contains a list of addresses used to access this endpoint. 180 Addresses []Address 181 182 // Attributes contains arbitrary data about this endpoint intended for 183 // consumption by the LB policy. 184 Attributes *attributes.Attributes 185 } 186 187 // State contains the current Resolver state relevant to the ClientConn. 188 type State struct { 189 // Addresses is the latest set of resolved addresses for the target. 190 // 191 // If a resolver sets Addresses but does not set Endpoints, one Endpoint 192 // will be created for each Address before the State is passed to the LB 193 // policy. The BalancerAttributes of each entry in Addresses will be set 194 // in Endpoints.Attributes, and be cleared in the Endpoint's Address's 195 // BalancerAttributes. 196 // 197 // Soon, Addresses will be deprecated and replaced fully by Endpoints. 198 Addresses []Address 199 200 // Endpoints is the latest set of resolved endpoints for the target. 201 // 202 // If a resolver produces a State containing Endpoints but not Addresses, 203 // it must take care to ensure the LB policies it selects will support 204 // Endpoints. 205 Endpoints []Endpoint 206 207 // ServiceConfig contains the result from parsing the latest service 208 // config. If it is nil, it indicates no service config is present or the 209 // resolver does not provide service configs. 210 ServiceConfig *serviceconfig.ParseResult 211 212 // Attributes contains arbitrary data about the resolver intended for 213 // consumption by the load balancing policy. 214 Attributes *attributes.Attributes 215 } 216 217 // ClientConn contains the callbacks for resolver to notify any updates 218 // to the gRPC ClientConn. 219 // 220 // This interface is to be implemented by gRPC. Users should not need a 221 // brand new implementation of this interface. For the situations like 222 // testing, the new implementation should embed this interface. This allows 223 // gRPC to add new methods to this interface. 224 type ClientConn interface { 225 // UpdateState updates the state of the ClientConn appropriately. 226 // 227 // If an error is returned, the resolver should try to resolve the 228 // target again. The resolver should use a backoff timer to prevent 229 // overloading the server with requests. If a resolver is certain that 230 // reresolving will not change the result, e.g. because it is 231 // a watch-based resolver, returned errors can be ignored. 232 // 233 // If the resolved State is the same as the last reported one, calling 234 // UpdateState can be omitted. 235 UpdateState(State) error 236 // ReportError notifies the ClientConn that the Resolver encountered an 237 // error. The ClientConn will notify the load balancer and begin calling 238 // ResolveNow on the Resolver with exponential backoff. 239 ReportError(error) 240 // NewAddress is called by resolver to notify ClientConn a new list 241 // of resolved addresses. 242 // The address list should be the complete list of resolved addresses. 243 // 244 // Deprecated: Use UpdateState instead. 245 NewAddress(addresses []Address) 246 // ParseServiceConfig parses the provided service config and returns an 247 // object that provides the parsed config. 248 ParseServiceConfig(serviceConfigJSON string) *serviceconfig.ParseResult 249 } 250 251 // Target represents a target for gRPC, as specified in: 252 // https://github.com/grpc/grpc/blob/master/doc/naming.md. 253 // It is parsed from the target string that gets passed into Dial or DialContext 254 // by the user. And gRPC passes it to the resolver and the balancer. 255 // 256 // If the target follows the naming spec, and the parsed scheme is registered 257 // with gRPC, we will parse the target string according to the spec. If the 258 // target does not contain a scheme or if the parsed scheme is not registered 259 // (i.e. no corresponding resolver available to resolve the endpoint), we will 260 // apply the default scheme, and will attempt to reparse it. 261 type Target struct { 262 // URL contains the parsed dial target with an optional default scheme added 263 // to it if the original dial target contained no scheme or contained an 264 // unregistered scheme. Any query params specified in the original dial 265 // target can be accessed from here. 266 URL url.URL 267 } 268 269 // Endpoint retrieves endpoint without leading "/" from either `URL.Path` 270 // or `URL.Opaque`. The latter is used when the former is empty. 271 func (t Target) Endpoint() string { 272 endpoint := t.URL.Path 273 if endpoint == "" { 274 endpoint = t.URL.Opaque 275 } 276 // For targets of the form "[scheme]://[authority]/endpoint, the endpoint 277 // value returned from url.Parse() contains a leading "/". Although this is 278 // in accordance with RFC 3986, we do not want to break existing resolver 279 // implementations which expect the endpoint without the leading "/". So, we 280 // end up stripping the leading "/" here. But this will result in an 281 // incorrect parsing for something like "unix:///path/to/socket". Since we 282 // own the "unix" resolver, we can workaround in the unix resolver by using 283 // the `URL` field. 284 return strings.TrimPrefix(endpoint, "/") 285 } 286 287 // String returns a string representation of Target. 288 func (t Target) String() string { 289 return t.URL.String() 290 } 291 292 // Builder creates a resolver that will be used to watch name resolution updates. 293 type Builder interface { 294 // Build creates a new resolver for the given target. 295 // 296 // gRPC dial calls Build synchronously, and fails if the returned error is 297 // not nil. 298 Build(target Target, cc ClientConn, opts BuildOptions) (Resolver, error) 299 // Scheme returns the scheme supported by this resolver. Scheme is defined 300 // at https://github.com/grpc/grpc/blob/master/doc/naming.md. The returned 301 // string should not contain uppercase characters, as they will not match 302 // the parsed target's scheme as defined in RFC 3986. 303 Scheme() string 304 } 305 306 // ResolveNowOptions includes additional information for ResolveNow. 307 type ResolveNowOptions struct{} 308 309 // Resolver watches for the updates on the specified target. 310 // Updates include address updates and service config updates. 311 type Resolver interface { 312 // ResolveNow will be called by gRPC to try to resolve the target name 313 // again. It's just a hint, resolver can ignore this if it's not necessary. 314 // 315 // It could be called multiple times concurrently. 316 ResolveNow(ResolveNowOptions) 317 // Close closes the resolver. 318 Close() 319 } 320 321 // AuthorityOverrider is implemented by Builders that wish to override the 322 // default authority for the ClientConn. 323 // By default, the authority used is target.Endpoint(). 324 type AuthorityOverrider interface { 325 // OverrideAuthority returns the authority to use for a ClientConn with the 326 // given target. The implementation must generate it without blocking, 327 // typically in line, and must keep it unchanged. 328 OverrideAuthority(Target) string 329 }