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  }