blob: 6a9d234a597a36149dade1bbcbeec5ab7eaae321 [file] [log] [blame]
khenaidoo5fc5cea2021-08-11 17:39:16 -04001/*
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.
21package resolver
22
23import (
24 "context"
25 "net"
26
27 "google.golang.org/grpc/attributes"
28 "google.golang.org/grpc/credentials"
29 "google.golang.org/grpc/serviceconfig"
30)
31
32var (
33 // m is a map from scheme to resolver builder.
34 m = make(map[string]Builder)
35 // defaultScheme is the default scheme to use.
36 defaultScheme = "passthrough"
37)
38
39// TODO(bar) install dns resolver in init(){}.
40
41// Register registers the resolver builder to the resolver map. b.Scheme will be
42// used as the scheme registered with this builder.
43//
44// NOTE: this function must only be called during initialization time (i.e. in
45// an init() function), and is not thread-safe. If multiple Resolvers are
46// registered with the same name, the one registered last will take effect.
47func Register(b Builder) {
48 m[b.Scheme()] = b
49}
50
51// Get returns the resolver builder registered with the given scheme.
52//
53// If no builder is register with the scheme, nil will be returned.
54func Get(scheme string) Builder {
55 if b, ok := m[scheme]; ok {
56 return b
57 }
58 return nil
59}
60
61// SetDefaultScheme sets the default scheme that will be used. The default
62// default scheme is "passthrough".
63//
64// NOTE: this function must only be called during initialization time (i.e. in
65// an init() function), and is not thread-safe. The scheme set last overrides
66// previously set values.
67func SetDefaultScheme(scheme string) {
68 defaultScheme = scheme
69}
70
71// GetDefaultScheme gets the default scheme that will be used.
72func GetDefaultScheme() string {
73 return defaultScheme
74}
75
76// AddressType indicates the address type returned by name resolution.
77//
78// Deprecated: use Attributes in Address instead.
79type AddressType uint8
80
81const (
82 // Backend indicates the address is for a backend server.
83 //
84 // Deprecated: use Attributes in Address instead.
85 Backend AddressType = iota
86 // GRPCLB indicates the address is for a grpclb load balancer.
87 //
88 // Deprecated: to select the GRPCLB load balancing policy, use a service
89 // config with a corresponding loadBalancingConfig. To supply balancer
90 // addresses to the GRPCLB load balancing policy, set State.Attributes
91 // using balancer/grpclb/state.Set.
92 GRPCLB
93)
94
95// Address represents a server the client connects to.
96//
97// Experimental
98//
99// Notice: This type is EXPERIMENTAL and may be changed or removed in a
100// later release.
101type Address struct {
102 // Addr is the server address on which a connection will be established.
103 Addr string
104
105 // ServerName is the name of this address.
106 // If non-empty, the ServerName is used as the transport certification authority for
107 // the address, instead of the hostname from the Dial target string. In most cases,
108 // this should not be set.
109 //
110 // If Type is GRPCLB, ServerName should be the name of the remote load
111 // balancer, not the name of the backend.
112 //
113 // WARNING: ServerName must only be populated with trusted values. It
114 // is insecure to populate it with data from untrusted inputs since untrusted
115 // values could be used to bypass the authority checks performed by TLS.
116 ServerName string
117
118 // Attributes contains arbitrary data about this address intended for
119 // consumption by the load balancing policy.
120 Attributes *attributes.Attributes
121
122 // Type is the type of this address.
123 //
124 // Deprecated: use Attributes instead.
125 Type AddressType
126
127 // Metadata is the information associated with Addr, which may be used
128 // to make load balancing decision.
129 //
130 // Deprecated: use Attributes instead.
131 Metadata interface{}
132}
133
134// BuildOptions includes additional information for the builder to create
135// the resolver.
136type BuildOptions struct {
137 // DisableServiceConfig indicates whether a resolver implementation should
138 // fetch service config data.
139 DisableServiceConfig bool
140 // DialCreds is the transport credentials used by the ClientConn for
141 // communicating with the target gRPC service (set via
142 // WithTransportCredentials). In cases where a name resolution service
143 // requires the same credentials, the resolver may use this field. In most
144 // cases though, it is not appropriate, and this field may be ignored.
145 DialCreds credentials.TransportCredentials
146 // CredsBundle is the credentials bundle used by the ClientConn for
147 // communicating with the target gRPC service (set via
148 // WithCredentialsBundle). In cases where a name resolution service
149 // requires the same credentials, the resolver may use this field. In most
150 // cases though, it is not appropriate, and this field may be ignored.
151 CredsBundle credentials.Bundle
152 // Dialer is the custom dialer used by the ClientConn for dialling the
153 // target gRPC service (set via WithDialer). In cases where a name
154 // resolution service requires the same dialer, the resolver may use this
155 // field. In most cases though, it is not appropriate, and this field may
156 // be ignored.
157 Dialer func(context.Context, string) (net.Conn, error)
158}
159
160// State contains the current Resolver state relevant to the ClientConn.
161type State struct {
162 // Addresses is the latest set of resolved addresses for the target.
163 Addresses []Address
164
165 // ServiceConfig contains the result from parsing the latest service
166 // config. If it is nil, it indicates no service config is present or the
167 // resolver does not provide service configs.
168 ServiceConfig *serviceconfig.ParseResult
169
170 // Attributes contains arbitrary data about the resolver intended for
171 // consumption by the load balancing policy.
172 Attributes *attributes.Attributes
173}
174
175// ClientConn contains the callbacks for resolver to notify any updates
176// to the gRPC ClientConn.
177//
178// This interface is to be implemented by gRPC. Users should not need a
179// brand new implementation of this interface. For the situations like
180// testing, the new implementation should embed this interface. This allows
181// gRPC to add new methods to this interface.
182type ClientConn interface {
183 // UpdateState updates the state of the ClientConn appropriately.
184 UpdateState(State) error
185 // ReportError notifies the ClientConn that the Resolver encountered an
186 // error. The ClientConn will notify the load balancer and begin calling
187 // ResolveNow on the Resolver with exponential backoff.
188 ReportError(error)
189 // NewAddress is called by resolver to notify ClientConn a new list
190 // of resolved addresses.
191 // The address list should be the complete list of resolved addresses.
192 //
193 // Deprecated: Use UpdateState instead.
194 NewAddress(addresses []Address)
195 // NewServiceConfig is called by resolver to notify ClientConn a new
196 // service config. The service config should be provided as a json string.
197 //
198 // Deprecated: Use UpdateState instead.
199 NewServiceConfig(serviceConfig string)
200 // ParseServiceConfig parses the provided service config and returns an
201 // object that provides the parsed config.
202 ParseServiceConfig(serviceConfigJSON string) *serviceconfig.ParseResult
203}
204
205// Target represents a target for gRPC, as specified in:
206// https://github.com/grpc/grpc/blob/master/doc/naming.md.
207// It is parsed from the target string that gets passed into Dial or DialContext by the user. And
208// grpc passes it to the resolver and the balancer.
209//
210// If the target follows the naming spec, and the parsed scheme is registered with grpc, we will
211// parse the target string according to the spec. e.g. "dns://some_authority/foo.bar" will be parsed
212// into &Target{Scheme: "dns", Authority: "some_authority", Endpoint: "foo.bar"}
213//
214// If the target does not contain a scheme, we will apply the default scheme, and set the Target to
215// be the full target string. e.g. "foo.bar" will be parsed into
216// &Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "foo.bar"}.
217//
218// If the parsed scheme is not registered (i.e. no corresponding resolver available to resolve the
219// endpoint), we set the Scheme to be the default scheme, and set the Endpoint to be the full target
220// string. e.g. target string "unknown_scheme://authority/endpoint" will be parsed into
221// &Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "unknown_scheme://authority/endpoint"}.
222type Target struct {
223 Scheme string
224 Authority string
225 Endpoint string
226}
227
228// Builder creates a resolver that will be used to watch name resolution updates.
229type Builder interface {
230 // Build creates a new resolver for the given target.
231 //
232 // gRPC dial calls Build synchronously, and fails if the returned error is
233 // not nil.
234 Build(target Target, cc ClientConn, opts BuildOptions) (Resolver, error)
235 // Scheme returns the scheme supported by this resolver.
236 // Scheme is defined at https://github.com/grpc/grpc/blob/master/doc/naming.md.
237 Scheme() string
238}
239
240// ResolveNowOptions includes additional information for ResolveNow.
241type ResolveNowOptions struct{}
242
243// Resolver watches for the updates on the specified target.
244// Updates include address updates and service config updates.
245type Resolver interface {
246 // ResolveNow will be called by gRPC to try to resolve the target name
247 // again. It's just a hint, resolver can ignore this if it's not necessary.
248 //
249 // It could be called multiple times concurrently.
250 ResolveNow(ResolveNowOptions)
251 // Close closes the resolver.
252 Close()
253}
254
255// UnregisterForTesting removes the resolver builder with the given scheme from the
256// resolver map.
257// This function is for testing only.
258func UnregisterForTesting(scheme string) {
259 delete(m, scheme)
260}