diff options
Diffstat (limited to 'vendor/google.golang.org/grpc/resolver')
| -rw-r--r-- | vendor/google.golang.org/grpc/resolver/map.go | 138 | ||||
| -rw-r--r-- | vendor/google.golang.org/grpc/resolver/resolver.go | 308 | 
2 files changed, 446 insertions, 0 deletions
| diff --git a/vendor/google.golang.org/grpc/resolver/map.go b/vendor/google.golang.org/grpc/resolver/map.go new file mode 100644 index 000000000..efcb7f3ef --- /dev/null +++ b/vendor/google.golang.org/grpc/resolver/map.go @@ -0,0 +1,138 @@ +/* + * + * Copyright 2021 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *     http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package resolver + +type addressMapEntry struct { +	addr  Address +	value interface{} +} + +// AddressMap is a map of addresses to arbitrary values taking into account +// Attributes.  BalancerAttributes are ignored, as are Metadata and Type. +// Multiple accesses may not be performed concurrently.  Must be created via +// NewAddressMap; do not construct directly. +type AddressMap struct { +	// The underlying map is keyed by an Address with fields that we don't care +	// about being set to their zero values. The only fields that we care about +	// are `Addr`, `ServerName` and `Attributes`. Since we need to be able to +	// distinguish between addresses with same `Addr` and `ServerName`, but +	// different `Attributes`, we cannot store the `Attributes` in the map key. +	// +	// The comparison operation for structs work as follows: +	//  Struct values are comparable if all their fields are comparable. Two +	//  struct values are equal if their corresponding non-blank fields are equal. +	// +	// The value type of the map contains a slice of addresses which match the key +	// in their `Addr` and `ServerName` fields and contain the corresponding value +	// associated with them. +	m map[Address]addressMapEntryList +} + +func toMapKey(addr *Address) Address { +	return Address{Addr: addr.Addr, ServerName: addr.ServerName} +} + +type addressMapEntryList []*addressMapEntry + +// NewAddressMap creates a new AddressMap. +func NewAddressMap() *AddressMap { +	return &AddressMap{m: make(map[Address]addressMapEntryList)} +} + +// find returns the index of addr in the addressMapEntry slice, or -1 if not +// present. +func (l addressMapEntryList) find(addr Address) int { +	for i, entry := range l { +		// Attributes are the only thing to match on here, since `Addr` and +		// `ServerName` are already equal. +		if entry.addr.Attributes.Equal(addr.Attributes) { +			return i +		} +	} +	return -1 +} + +// Get returns the value for the address in the map, if present. +func (a *AddressMap) Get(addr Address) (value interface{}, ok bool) { +	addrKey := toMapKey(&addr) +	entryList := a.m[addrKey] +	if entry := entryList.find(addr); entry != -1 { +		return entryList[entry].value, true +	} +	return nil, false +} + +// Set updates or adds the value to the address in the map. +func (a *AddressMap) Set(addr Address, value interface{}) { +	addrKey := toMapKey(&addr) +	entryList := a.m[addrKey] +	if entry := entryList.find(addr); entry != -1 { +		entryList[entry].value = value +		return +	} +	a.m[addrKey] = append(entryList, &addressMapEntry{addr: addr, value: value}) +} + +// Delete removes addr from the map. +func (a *AddressMap) Delete(addr Address) { +	addrKey := toMapKey(&addr) +	entryList := a.m[addrKey] +	entry := entryList.find(addr) +	if entry == -1 { +		return +	} +	if len(entryList) == 1 { +		entryList = nil +	} else { +		copy(entryList[entry:], entryList[entry+1:]) +		entryList = entryList[:len(entryList)-1] +	} +	a.m[addrKey] = entryList +} + +// Len returns the number of entries in the map. +func (a *AddressMap) Len() int { +	ret := 0 +	for _, entryList := range a.m { +		ret += len(entryList) +	} +	return ret +} + +// Keys returns a slice of all current map keys. +func (a *AddressMap) Keys() []Address { +	ret := make([]Address, 0, a.Len()) +	for _, entryList := range a.m { +		for _, entry := range entryList { +			ret = append(ret, entry.addr) +		} +	} +	return ret +} + +// Values returns a slice of all current map values. +func (a *AddressMap) Values() []interface{} { +	ret := make([]interface{}, 0, a.Len()) +	for _, entryList := range a.m { +		for _, entry := range entryList { +			ret = append(ret, entry.value) +		} +	} +	return ret +} diff --git a/vendor/google.golang.org/grpc/resolver/resolver.go b/vendor/google.golang.org/grpc/resolver/resolver.go new file mode 100644 index 000000000..654e9ce69 --- /dev/null +++ b/vendor/google.golang.org/grpc/resolver/resolver.go @@ -0,0 +1,308 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *     http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package resolver defines APIs for name resolution in gRPC. +// All APIs in this package are experimental. +package resolver + +import ( +	"context" +	"net" +	"net/url" +	"strings" + +	"google.golang.org/grpc/attributes" +	"google.golang.org/grpc/credentials" +	"google.golang.org/grpc/internal/pretty" +	"google.golang.org/grpc/serviceconfig" +) + +var ( +	// m is a map from scheme to resolver builder. +	m = make(map[string]Builder) +	// defaultScheme is the default scheme to use. +	defaultScheme = "passthrough" +) + +// TODO(bar) install dns resolver in init(){}. + +// Register registers the resolver builder to the resolver map. b.Scheme will be +// used as the scheme registered with this builder. +// +// NOTE: this function must only be called during initialization time (i.e. in +// an init() function), and is not thread-safe. If multiple Resolvers are +// registered with the same name, the one registered last will take effect. +func Register(b Builder) { +	m[b.Scheme()] = b +} + +// Get returns the resolver builder registered with the given scheme. +// +// If no builder is register with the scheme, nil will be returned. +func Get(scheme string) Builder { +	if b, ok := m[scheme]; ok { +		return b +	} +	return nil +} + +// SetDefaultScheme sets the default scheme that will be used. The default +// default scheme is "passthrough". +// +// NOTE: this function must only be called during initialization time (i.e. in +// an init() function), and is not thread-safe. The scheme set last overrides +// previously set values. +func SetDefaultScheme(scheme string) { +	defaultScheme = scheme +} + +// GetDefaultScheme gets the default scheme that will be used. +func GetDefaultScheme() string { +	return defaultScheme +} + +// AddressType indicates the address type returned by name resolution. +// +// Deprecated: use Attributes in Address instead. +type AddressType uint8 + +const ( +	// Backend indicates the address is for a backend server. +	// +	// Deprecated: use Attributes in Address instead. +	Backend AddressType = iota +	// GRPCLB indicates the address is for a grpclb load balancer. +	// +	// Deprecated: to select the GRPCLB load balancing policy, use a service +	// config with a corresponding loadBalancingConfig.  To supply balancer +	// addresses to the GRPCLB load balancing policy, set State.Attributes +	// using balancer/grpclb/state.Set. +	GRPCLB +) + +// Address represents a server the client connects to. +// +// # Experimental +// +// Notice: This type is EXPERIMENTAL and may be changed or removed in a +// later release. +type Address struct { +	// Addr is the server address on which a connection will be established. +	Addr string + +	// ServerName is the name of this address. +	// If non-empty, the ServerName is used as the transport certification authority for +	// the address, instead of the hostname from the Dial target string. In most cases, +	// this should not be set. +	// +	// If Type is GRPCLB, ServerName should be the name of the remote load +	// balancer, not the name of the backend. +	// +	// WARNING: ServerName must only be populated with trusted values. It +	// is insecure to populate it with data from untrusted inputs since untrusted +	// values could be used to bypass the authority checks performed by TLS. +	ServerName string + +	// Attributes contains arbitrary data about this address intended for +	// consumption by the SubConn. +	Attributes *attributes.Attributes + +	// BalancerAttributes contains arbitrary data about this address intended +	// for consumption by the LB policy.  These attribes do not affect SubConn +	// creation, connection establishment, handshaking, etc. +	BalancerAttributes *attributes.Attributes + +	// Type is the type of this address. +	// +	// Deprecated: use Attributes instead. +	Type AddressType + +	// Metadata is the information associated with Addr, which may be used +	// to make load balancing decision. +	// +	// Deprecated: use Attributes instead. +	Metadata interface{} +} + +// Equal returns whether a and o are identical.  Metadata is compared directly, +// not with any recursive introspection. +func (a Address) Equal(o Address) bool { +	return a.Addr == o.Addr && a.ServerName == o.ServerName && +		a.Attributes.Equal(o.Attributes) && +		a.BalancerAttributes.Equal(o.BalancerAttributes) && +		a.Type == o.Type && a.Metadata == o.Metadata +} + +// String returns JSON formatted string representation of the address. +func (a Address) String() string { +	return pretty.ToJSON(a) +} + +// BuildOptions includes additional information for the builder to create +// the resolver. +type BuildOptions struct { +	// DisableServiceConfig indicates whether a resolver implementation should +	// fetch service config data. +	DisableServiceConfig bool +	// DialCreds is the transport credentials used by the ClientConn for +	// communicating with the target gRPC service (set via +	// WithTransportCredentials). In cases where a name resolution service +	// requires the same credentials, the resolver may use this field. In most +	// cases though, it is not appropriate, and this field may be ignored. +	DialCreds credentials.TransportCredentials +	// CredsBundle is the credentials bundle used by the ClientConn for +	// communicating with the target gRPC service (set via +	// WithCredentialsBundle). In cases where a name resolution service +	// requires the same credentials, the resolver may use this field. In most +	// cases though, it is not appropriate, and this field may be ignored. +	CredsBundle credentials.Bundle +	// Dialer is the custom dialer used by the ClientConn for dialling the +	// target gRPC service (set via WithDialer). In cases where a name +	// resolution service requires the same dialer, the resolver may use this +	// field. In most cases though, it is not appropriate, and this field may +	// be ignored. +	Dialer func(context.Context, string) (net.Conn, error) +} + +// State contains the current Resolver state relevant to the ClientConn. +type State struct { +	// Addresses is the latest set of resolved addresses for the target. +	Addresses []Address + +	// ServiceConfig contains the result from parsing the latest service +	// config.  If it is nil, it indicates no service config is present or the +	// resolver does not provide service configs. +	ServiceConfig *serviceconfig.ParseResult + +	// Attributes contains arbitrary data about the resolver intended for +	// consumption by the load balancing policy. +	Attributes *attributes.Attributes +} + +// ClientConn contains the callbacks for resolver to notify any updates +// to the gRPC ClientConn. +// +// This interface is to be implemented by gRPC. Users should not need a +// brand new implementation of this interface. For the situations like +// testing, the new implementation should embed this interface. This allows +// gRPC to add new methods to this interface. +type ClientConn interface { +	// UpdateState updates the state of the ClientConn appropriately. +	UpdateState(State) error +	// ReportError notifies the ClientConn that the Resolver encountered an +	// error.  The ClientConn will notify the load balancer and begin calling +	// ResolveNow on the Resolver with exponential backoff. +	ReportError(error) +	// NewAddress is called by resolver to notify ClientConn a new list +	// of resolved addresses. +	// The address list should be the complete list of resolved addresses. +	// +	// Deprecated: Use UpdateState instead. +	NewAddress(addresses []Address) +	// NewServiceConfig is called by resolver to notify ClientConn a new +	// service config. The service config should be provided as a json string. +	// +	// Deprecated: Use UpdateState instead. +	NewServiceConfig(serviceConfig string) +	// ParseServiceConfig parses the provided service config and returns an +	// object that provides the parsed config. +	ParseServiceConfig(serviceConfigJSON string) *serviceconfig.ParseResult +} + +// Target represents a target for gRPC, as specified in: +// https://github.com/grpc/grpc/blob/master/doc/naming.md. +// It is parsed from the target string that gets passed into Dial or DialContext +// by the user. And gRPC passes it to the resolver and the balancer. +// +// If the target follows the naming spec, and the parsed scheme is registered +// with gRPC, we will parse the target string according to the spec. If the +// target does not contain a scheme or if the parsed scheme is not registered +// (i.e. no corresponding resolver available to resolve the endpoint), we will +// apply the default scheme, and will attempt to reparse it. +// +// Examples: +// +//   - "dns://some_authority/foo.bar" +//     Target{Scheme: "dns", Authority: "some_authority", Endpoint: "foo.bar"} +//   - "foo.bar" +//     Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "foo.bar"} +//   - "unknown_scheme://authority/endpoint" +//     Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "unknown_scheme://authority/endpoint"} +type Target struct { +	// Deprecated: use URL.Scheme instead. +	Scheme string +	// Deprecated: use URL.Host instead. +	Authority string +	// URL contains the parsed dial target with an optional default scheme added +	// to it if the original dial target contained no scheme or contained an +	// unregistered scheme. Any query params specified in the original dial +	// target can be accessed from here. +	URL url.URL +} + +// Endpoint retrieves endpoint without leading "/" from either `URL.Path` +// or `URL.Opaque`. The latter is used when the former is empty. +func (t Target) Endpoint() string { +	endpoint := t.URL.Path +	if endpoint == "" { +		endpoint = t.URL.Opaque +	} +	// For targets of the form "[scheme]://[authority]/endpoint, the endpoint +	// value returned from url.Parse() contains a leading "/". Although this is +	// in accordance with RFC 3986, we do not want to break existing resolver +	// implementations which expect the endpoint without the leading "/". So, we +	// end up stripping the leading "/" here. But this will result in an +	// incorrect parsing for something like "unix:///path/to/socket". Since we +	// own the "unix" resolver, we can workaround in the unix resolver by using +	// the `URL` field. +	return strings.TrimPrefix(endpoint, "/") +} + +// Builder creates a resolver that will be used to watch name resolution updates. +type Builder interface { +	// Build creates a new resolver for the given target. +	// +	// gRPC dial calls Build synchronously, and fails if the returned error is +	// not nil. +	Build(target Target, cc ClientConn, opts BuildOptions) (Resolver, error) +	// Scheme returns the scheme supported by this resolver. +	// Scheme is defined at https://github.com/grpc/grpc/blob/master/doc/naming.md. +	Scheme() string +} + +// ResolveNowOptions includes additional information for ResolveNow. +type ResolveNowOptions struct{} + +// Resolver watches for the updates on the specified target. +// Updates include address updates and service config updates. +type Resolver interface { +	// ResolveNow will be called by gRPC to try to resolve the target name +	// again. It's just a hint, resolver can ignore this if it's not necessary. +	// +	// It could be called multiple times concurrently. +	ResolveNow(ResolveNowOptions) +	// Close closes the resolver. +	Close() +} + +// UnregisterForTesting removes the resolver builder with the given scheme from the +// resolver map. +// This function is for testing only. +func UnregisterForTesting(scheme string) { +	delete(m, scheme) +} | 
