gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

resolver.go (12484B)


      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 	"google.golang.org/grpc/attributes"
     30 	"google.golang.org/grpc/credentials"
     31 	"google.golang.org/grpc/internal/pretty"
     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 // AddressType indicates the address type returned by name resolution.
     81 //
     82 // Deprecated: use Attributes in Address instead.
     83 type AddressType uint8
     84 
     85 const (
     86 	// Backend indicates the address is for a backend server.
     87 	//
     88 	// Deprecated: use Attributes in Address instead.
     89 	Backend AddressType = iota
     90 	// GRPCLB indicates the address is for a grpclb load balancer.
     91 	//
     92 	// Deprecated: to select the GRPCLB load balancing policy, use a service
     93 	// config with a corresponding loadBalancingConfig.  To supply balancer
     94 	// addresses to the GRPCLB load balancing policy, set State.Attributes
     95 	// using balancer/grpclb/state.Set.
     96 	GRPCLB
     97 )
     98 
     99 // Address represents a server the client connects to.
    100 //
    101 // # Experimental
    102 //
    103 // Notice: This type is EXPERIMENTAL and may be changed or removed in a
    104 // later release.
    105 type Address struct {
    106 	// Addr is the server address on which a connection will be established.
    107 	Addr string
    108 
    109 	// ServerName is the name of this address.
    110 	// If non-empty, the ServerName is used as the transport certification authority for
    111 	// the address, instead of the hostname from the Dial target string. In most cases,
    112 	// this should not be set.
    113 	//
    114 	// If Type is GRPCLB, ServerName should be the name of the remote load
    115 	// balancer, not the name of the backend.
    116 	//
    117 	// WARNING: ServerName must only be populated with trusted values. It
    118 	// is insecure to populate it with data from untrusted inputs since untrusted
    119 	// values could be used to bypass the authority checks performed by TLS.
    120 	ServerName string
    121 
    122 	// Attributes contains arbitrary data about this address intended for
    123 	// consumption by the SubConn.
    124 	Attributes *attributes.Attributes
    125 
    126 	// BalancerAttributes contains arbitrary data about this address intended
    127 	// for consumption by the LB policy.  These attribes do not affect SubConn
    128 	// creation, connection establishment, handshaking, etc.
    129 	BalancerAttributes *attributes.Attributes
    130 
    131 	// Type is the type of this address.
    132 	//
    133 	// Deprecated: use Attributes instead.
    134 	Type AddressType
    135 
    136 	// Metadata is the information associated with Addr, which may be used
    137 	// to make load balancing decision.
    138 	//
    139 	// Deprecated: use Attributes instead.
    140 	Metadata interface{}
    141 }
    142 
    143 // Equal returns whether a and o are identical.  Metadata is compared directly,
    144 // not with any recursive introspection.
    145 func (a Address) Equal(o Address) bool {
    146 	return a.Addr == o.Addr && a.ServerName == o.ServerName &&
    147 		a.Attributes.Equal(o.Attributes) &&
    148 		a.BalancerAttributes.Equal(o.BalancerAttributes) &&
    149 		a.Type == o.Type && a.Metadata == o.Metadata
    150 }
    151 
    152 // String returns JSON formatted string representation of the address.
    153 func (a Address) String() string {
    154 	return pretty.ToJSON(a)
    155 }
    156 
    157 // BuildOptions includes additional information for the builder to create
    158 // the resolver.
    159 type BuildOptions struct {
    160 	// DisableServiceConfig indicates whether a resolver implementation should
    161 	// fetch service config data.
    162 	DisableServiceConfig bool
    163 	// DialCreds is the transport credentials used by the ClientConn for
    164 	// communicating with the target gRPC service (set via
    165 	// WithTransportCredentials). In cases where a name resolution service
    166 	// requires the same credentials, the resolver may use this field. In most
    167 	// cases though, it is not appropriate, and this field may be ignored.
    168 	DialCreds credentials.TransportCredentials
    169 	// CredsBundle is the credentials bundle used by the ClientConn for
    170 	// communicating with the target gRPC service (set via
    171 	// WithCredentialsBundle). In cases where a name resolution service
    172 	// requires the same credentials, the resolver may use this field. In most
    173 	// cases though, it is not appropriate, and this field may be ignored.
    174 	CredsBundle credentials.Bundle
    175 	// Dialer is the custom dialer used by the ClientConn for dialling the
    176 	// target gRPC service (set via WithDialer). In cases where a name
    177 	// resolution service requires the same dialer, the resolver may use this
    178 	// field. In most cases though, it is not appropriate, and this field may
    179 	// be ignored.
    180 	Dialer func(context.Context, string) (net.Conn, error)
    181 }
    182 
    183 // State contains the current Resolver state relevant to the ClientConn.
    184 type State struct {
    185 	// Addresses is the latest set of resolved addresses for the target.
    186 	Addresses []Address
    187 
    188 	// ServiceConfig contains the result from parsing the latest service
    189 	// config.  If it is nil, it indicates no service config is present or the
    190 	// resolver does not provide service configs.
    191 	ServiceConfig *serviceconfig.ParseResult
    192 
    193 	// Attributes contains arbitrary data about the resolver intended for
    194 	// consumption by the load balancing policy.
    195 	Attributes *attributes.Attributes
    196 }
    197 
    198 // ClientConn contains the callbacks for resolver to notify any updates
    199 // to the gRPC ClientConn.
    200 //
    201 // This interface is to be implemented by gRPC. Users should not need a
    202 // brand new implementation of this interface. For the situations like
    203 // testing, the new implementation should embed this interface. This allows
    204 // gRPC to add new methods to this interface.
    205 type ClientConn interface {
    206 	// UpdateState updates the state of the ClientConn appropriately.
    207 	//
    208 	// If an error is returned, the resolver should try to resolve the
    209 	// target again. The resolver should use a backoff timer to prevent
    210 	// overloading the server with requests. If a resolver is certain that
    211 	// reresolving will not change the result, e.g. because it is
    212 	// a watch-based resolver, returned errors can be ignored.
    213 	//
    214 	// If the resolved State is the same as the last reported one, calling
    215 	// UpdateState can be omitted.
    216 	UpdateState(State) error
    217 	// ReportError notifies the ClientConn that the Resolver encountered an
    218 	// error.  The ClientConn will notify the load balancer and begin calling
    219 	// ResolveNow on the Resolver with exponential backoff.
    220 	ReportError(error)
    221 	// NewAddress is called by resolver to notify ClientConn a new list
    222 	// of resolved addresses.
    223 	// The address list should be the complete list of resolved addresses.
    224 	//
    225 	// Deprecated: Use UpdateState instead.
    226 	NewAddress(addresses []Address)
    227 	// NewServiceConfig is called by resolver to notify ClientConn a new
    228 	// service config. The service config should be provided as a json string.
    229 	//
    230 	// Deprecated: Use UpdateState instead.
    231 	NewServiceConfig(serviceConfig string)
    232 	// ParseServiceConfig parses the provided service config and returns an
    233 	// object that provides the parsed config.
    234 	ParseServiceConfig(serviceConfigJSON string) *serviceconfig.ParseResult
    235 }
    236 
    237 // Target represents a target for gRPC, as specified in:
    238 // https://github.com/grpc/grpc/blob/master/doc/naming.md.
    239 // It is parsed from the target string that gets passed into Dial or DialContext
    240 // by the user. And gRPC passes it to the resolver and the balancer.
    241 //
    242 // If the target follows the naming spec, and the parsed scheme is registered
    243 // with gRPC, we will parse the target string according to the spec. If the
    244 // target does not contain a scheme or if the parsed scheme is not registered
    245 // (i.e. no corresponding resolver available to resolve the endpoint), we will
    246 // apply the default scheme, and will attempt to reparse it.
    247 //
    248 // Examples:
    249 //
    250 //   - "dns://some_authority/foo.bar"
    251 //     Target{Scheme: "dns", Authority: "some_authority", Endpoint: "foo.bar"}
    252 //   - "foo.bar"
    253 //     Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "foo.bar"}
    254 //   - "unknown_scheme://authority/endpoint"
    255 //     Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "unknown_scheme://authority/endpoint"}
    256 type Target struct {
    257 	// Deprecated: use URL.Scheme instead.
    258 	Scheme string
    259 	// Deprecated: use URL.Host instead.
    260 	Authority string
    261 	// URL contains the parsed dial target with an optional default scheme added
    262 	// to it if the original dial target contained no scheme or contained an
    263 	// unregistered scheme. Any query params specified in the original dial
    264 	// target can be accessed from here.
    265 	URL url.URL
    266 }
    267 
    268 // Endpoint retrieves endpoint without leading "/" from either `URL.Path`
    269 // or `URL.Opaque`. The latter is used when the former is empty.
    270 func (t Target) Endpoint() string {
    271 	endpoint := t.URL.Path
    272 	if endpoint == "" {
    273 		endpoint = t.URL.Opaque
    274 	}
    275 	// For targets of the form "[scheme]://[authority]/endpoint, the endpoint
    276 	// value returned from url.Parse() contains a leading "/". Although this is
    277 	// in accordance with RFC 3986, we do not want to break existing resolver
    278 	// implementations which expect the endpoint without the leading "/". So, we
    279 	// end up stripping the leading "/" here. But this will result in an
    280 	// incorrect parsing for something like "unix:///path/to/socket". Since we
    281 	// own the "unix" resolver, we can workaround in the unix resolver by using
    282 	// the `URL` field.
    283 	return strings.TrimPrefix(endpoint, "/")
    284 }
    285 
    286 // Builder creates a resolver that will be used to watch name resolution updates.
    287 type Builder interface {
    288 	// Build creates a new resolver for the given target.
    289 	//
    290 	// gRPC dial calls Build synchronously, and fails if the returned error is
    291 	// not nil.
    292 	Build(target Target, cc ClientConn, opts BuildOptions) (Resolver, error)
    293 	// Scheme returns the scheme supported by this resolver.  Scheme is defined
    294 	// at https://github.com/grpc/grpc/blob/master/doc/naming.md.  The returned
    295 	// string should not contain uppercase characters, as they will not match
    296 	// the parsed target's scheme as defined in RFC 3986.
    297 	Scheme() string
    298 }
    299 
    300 // ResolveNowOptions includes additional information for ResolveNow.
    301 type ResolveNowOptions struct{}
    302 
    303 // Resolver watches for the updates on the specified target.
    304 // Updates include address updates and service config updates.
    305 type Resolver interface {
    306 	// ResolveNow will be called by gRPC to try to resolve the target name
    307 	// again. It's just a hint, resolver can ignore this if it's not necessary.
    308 	//
    309 	// It could be called multiple times concurrently.
    310 	ResolveNow(ResolveNowOptions)
    311 	// Close closes the resolver.
    312 	Close()
    313 }
    314 
    315 // UnregisterForTesting removes the resolver builder with the given scheme from the
    316 // resolver map.
    317 // This function is for testing only.
    318 func UnregisterForTesting(scheme string) {
    319 	delete(m, scheme)
    320 }