gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/grpc/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 "net" 26 "net/url" 27 "strings" 28 29 "gitee.com/ks-custle/core-gm/grpc/attributes" 30 "gitee.com/ks-custle/core-gm/grpc/credentials" 31 "gitee.com/ks-custle/core-gm/grpc/serviceconfig" 32 ) 33 34 var ( 35 // m is a map from scheme to resolver builder. 36 m = make(map[string]Builder) 37 // defaultScheme is the default scheme to use. 38 defaultScheme = "passthrough" 39 ) 40 41 // TODO(bar) install dns resolver in init(){}. 42 43 // Register registers the resolver builder to the resolver map. b.Scheme will be 44 // used as the scheme registered with this builder. 45 // 46 // NOTE: this function must only be called during initialization time (i.e. in 47 // an init() function), and is not thread-safe. If multiple Resolvers are 48 // registered with the same name, the one registered last will take effect. 49 func Register(b Builder) { 50 m[b.Scheme()] = b 51 } 52 53 // Get returns the resolver builder registered with the given scheme. 54 // 55 // If no builder is register with the scheme, nil will be returned. 56 func Get(scheme string) Builder { 57 if b, ok := m[scheme]; ok { 58 return b 59 } 60 return nil 61 } 62 63 // SetDefaultScheme sets the default scheme that will be used. The default 64 // default scheme is "passthrough". 65 // 66 // NOTE: this function must only be called during initialization time (i.e. in 67 // an init() function), and is not thread-safe. The scheme set last overrides 68 // previously set values. 69 func SetDefaultScheme(scheme string) { 70 defaultScheme = scheme 71 } 72 73 // GetDefaultScheme gets the default scheme that will be used. 74 func GetDefaultScheme() string { 75 return defaultScheme 76 } 77 78 // AddressType indicates the address type returned by name resolution. 79 // 80 // Deprecated: use Attributes in Address instead. 81 type AddressType uint8 82 83 const ( 84 // Backend indicates the address is for a backend server. 85 // 86 // Deprecated: use Attributes in Address instead. 87 Backend AddressType = iota 88 // GRPCLB indicates the address is for a grpclb load balancer. 89 // 90 // Deprecated: to select the GRPCLB load balancing policy, use a service 91 // config with a corresponding loadBalancingConfig. To supply balancer 92 // addresses to the GRPCLB load balancing policy, set State.Attributes 93 // using balancer/grpclb/state.Set. 94 GRPCLB 95 ) 96 97 // Address represents a server the client connects to. 98 // 99 // # Experimental 100 // 101 // Notice: This type is EXPERIMENTAL and may be changed or removed in a 102 // later release. 103 type Address struct { 104 // Addr is the server address on which a connection will be established. 105 Addr string 106 107 // ServerName is the name of this address. 108 // If non-empty, the ServerName is used as the transport certification authority for 109 // the address, instead of the hostname from the Dial target string. In most cases, 110 // this should not be set. 111 // 112 // If Type is GRPCLB, ServerName should be the name of the remote load 113 // balancer, not the name of the backend. 114 // 115 // WARNING: ServerName must only be populated with trusted values. It 116 // is insecure to populate it with data from untrusted inputs since untrusted 117 // values could be used to bypass the authority checks performed by TLS. 118 ServerName string 119 120 // Attributes contains arbitrary data about this address intended for 121 // consumption by the SubConn. 122 Attributes *attributes.Attributes 123 124 // BalancerAttributes contains arbitrary data about this address intended 125 // for consumption by the LB policy. These attribes do not affect SubConn 126 // creation, connection establishment, handshaking, etc. 127 BalancerAttributes *attributes.Attributes 128 129 // Type is the type of this address. 130 // 131 // Deprecated: use Attributes instead. 132 Type AddressType 133 134 // Metadata is the information associated with Addr, which may be used 135 // to make load balancing decision. 136 // 137 // Deprecated: use Attributes instead. 138 Metadata interface{} 139 } 140 141 // Equal returns whether a and o are identical. Metadata is compared directly, 142 // not with any recursive introspection. 143 func (a *Address) Equal(o Address) bool { 144 return a.Addr == o.Addr && a.ServerName == o.ServerName && 145 a.Attributes.Equal(o.Attributes) && 146 a.BalancerAttributes.Equal(o.BalancerAttributes) && 147 a.Type == o.Type && a.Metadata == o.Metadata 148 } 149 150 // BuildOptions includes additional information for the builder to create 151 // the resolver. 152 type BuildOptions struct { 153 // DisableServiceConfig indicates whether a resolver implementation should 154 // fetch service config data. 155 DisableServiceConfig bool 156 // DialCreds is the transport credentials used by the ClientConn for 157 // communicating with the target gRPC service (set via 158 // WithTransportCredentials). In cases where a name resolution service 159 // requires the same credentials, the resolver may use this field. In most 160 // cases though, it is not appropriate, and this field may be ignored. 161 DialCreds credentials.TransportCredentials 162 // CredsBundle is the credentials bundle used by the ClientConn for 163 // communicating with the target gRPC service (set via 164 // WithCredentialsBundle). In cases where a name resolution service 165 // requires the same credentials, the resolver may use this field. In most 166 // cases though, it is not appropriate, and this field may be ignored. 167 CredsBundle credentials.Bundle 168 // Dialer is the custom dialer used by the ClientConn for dialling the 169 // target gRPC service (set via WithDialer). In cases where a name 170 // resolution service requires the same dialer, the resolver may use this 171 // field. In most cases though, it is not appropriate, and this field may 172 // be ignored. 173 Dialer func(context.Context, string) (net.Conn, error) 174 } 175 176 // State contains the current Resolver state relevant to the ClientConn. 177 type State struct { 178 // Addresses is the latest set of resolved addresses for the target. 179 Addresses []Address 180 181 // ServiceConfig contains the result from parsing the latest service 182 // config. If it is nil, it indicates no service config is present or the 183 // resolver does not provide service configs. 184 ServiceConfig *serviceconfig.ParseResult 185 186 // Attributes contains arbitrary data about the resolver intended for 187 // consumption by the load balancing policy. 188 Attributes *attributes.Attributes 189 } 190 191 // ClientConn contains the callbacks for resolver to notify any updates 192 // to the gRPC ClientConn. 193 // 194 // This interface is to be implemented by gRPC. Users should not need a 195 // brand new implementation of this interface. For the situations like 196 // testing, the new implementation should embed this interface. This allows 197 // gRPC to add new methods to this interface. 198 type ClientConn interface { 199 // UpdateState updates the state of the ClientConn appropriately. 200 UpdateState(State) error 201 // ReportError notifies the ClientConn that the Resolver encountered an 202 // error. The ClientConn will notify the load balancer and begin calling 203 // ResolveNow on the Resolver with exponential backoff. 204 ReportError(error) 205 // NewAddress is called by resolver to notify ClientConn a new list 206 // of resolved addresses. 207 // The address list should be the complete list of resolved addresses. 208 // 209 // Deprecated: Use UpdateState instead. 210 NewAddress(addresses []Address) 211 // NewServiceConfig is called by resolver to notify ClientConn a new 212 // service config. The service config should be provided as a json string. 213 // 214 // Deprecated: Use UpdateState instead. 215 NewServiceConfig(serviceConfig string) 216 // ParseServiceConfig parses the provided service config and returns an 217 // object that provides the parsed config. 218 ParseServiceConfig(serviceConfigJSON string) *serviceconfig.ParseResult 219 } 220 221 // Target represents a target for gRPC, as specified in: 222 // https://github.com/grpc/grpc/blob/master/doc/naming.md. 223 // It is parsed from the target string that gets passed into Dial or DialContext 224 // by the user. And gRPC passes it to the resolver and the balancer. 225 // 226 // If the target follows the naming spec, and the parsed scheme is registered 227 // with gRPC, we will parse the target string according to the spec. If the 228 // target does not contain a scheme or if the parsed scheme is not registered 229 // (i.e. no corresponding resolver available to resolve the endpoint), we will 230 // apply the default scheme, and will attempt to reparse it. 231 // 232 // Examples: 233 // 234 // - "dns://some_authority/foo.bar" 235 // Target{Scheme: "dns", Authority: "some_authority", Endpoint: "foo.bar"} 236 // - "foo.bar" 237 // Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "foo.bar"} 238 // - "unknown_scheme://authority/endpoint" 239 // Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "unknown_scheme://authority/endpoint"} 240 type Target struct { 241 // Deprecated: use URL.Scheme instead. 使用`target.GetScheme()`代替。 242 Scheme string 243 // Deprecated: use URL.Host instead. 使用`target.GetAuthority()`代替。 244 Authority string 245 // Deprecated: use URL.Path or URL.Opaque instead. The latter is set when 246 // the former is empty. 247 // 使用`target.GetEndpoint()`代替。 248 Endpoint string 249 // URL contains the parsed dial target with an optional default scheme added 250 // to it if the original dial target contained no scheme or contained an 251 // unregistered scheme. Any query params specified in the original dial 252 // target can be accessed from here. 253 URL url.URL 254 } 255 256 // GetScheme 获取Target的scheme: t.URL.Scheme 257 // 258 // `t.Scheme`已弃用,使用该方法获取`t.URL.Scheme`代替。 259 // 优先使用t.URL.Scheme,如果为空,则使用t.Scheme 260 func (t Target) GetScheme() string { 261 if t.URL.Scheme != "" { 262 return t.URL.Scheme 263 } 264 //goland:noinspection GoDeprecation 265 return t.Scheme 266 } 267 268 // GetAuthority 获取Target的authority: t.URL.Host 269 // 270 // `t.Authority`已弃用,使用该方法获取`t.URL.Host`代替。 271 // 优先使用t.URL.Host,如果为空,则使用t.Authority 272 func (t Target) GetAuthority() string { 273 if t.URL.Host != "" { 274 return t.URL.Host 275 } 276 //goland:noinspection GoDeprecation 277 return t.Authority 278 } 279 280 // GetEndpoint 获取Target的endpoint: t.URL.Path or t.URL.Opaque 281 // 282 // `t.Endpoint`已弃用,使用该方法获取`t.URL.Path`或`t.URL.Opaque`代替。 283 // 优先使用`t.URL.Path`,如果为空,则使用`t.URL.Opaque`, 284 // `t.URL.Opaque`也为空,则使用`t.Endpoint` 285 func (t Target) GetEndpoint() string { 286 endpoint := t.URL.Path 287 if endpoint == "" { 288 endpoint = t.URL.Opaque 289 } 290 endpoint = strings.TrimPrefix(endpoint, "/") 291 if endpoint != "" { 292 return endpoint 293 } 294 //goland:noinspection GoDeprecation 295 return t.Endpoint 296 } 297 298 // Builder creates a resolver that will be used to watch name resolution updates. 299 type Builder interface { 300 // Build creates a new resolver for the given target. 301 // 302 // gRPC dial calls Build synchronously, and fails if the returned error is 303 // not nil. 304 Build(target Target, cc ClientConn, opts BuildOptions) (Resolver, error) 305 // Scheme returns the scheme supported by this resolver. 306 // Scheme is defined at https://github.com/grpc/grpc/blob/master/doc/naming.md. 307 Scheme() string 308 } 309 310 // ResolveNowOptions includes additional information for ResolveNow. 311 type ResolveNowOptions struct{} 312 313 // Resolver watches for the updates on the specified target. 314 // Updates include address updates and service config updates. 315 type Resolver interface { 316 // ResolveNow will be called by gRPC to try to resolve the target name 317 // again. It's just a hint, resolver can ignore this if it's not necessary. 318 // 319 // It could be called multiple times concurrently. 320 ResolveNow(ResolveNowOptions) 321 // Close closes the resolver. 322 Close() 323 } 324 325 // UnregisterForTesting removes the resolver builder with the given scheme from the 326 // resolver map. 327 // This function is for testing only. 328 func UnregisterForTesting(scheme string) { 329 delete(m, scheme) 330 }