Skip to content

Commit 978441f

Browse files
committed
cleanup: usages of resolver.Target.Endpoint
* feat(resolver): create Target.ToEndpoint() ** fix(resolver): strip leading "/" from URL.Opaque ** fix(resolver): document stripped "/" in ToEndpoint * fix(internal): remove reliance on Target.Endpoint ** fix(dns_resolver_test): add escape for percent char ** feat(testutils): create helper function for dns_resolver_test ** fix(testutils/parse_url): return output of url.Parse ** fix(testutils/parse_url): simplify documentation
1 parent ae86ff4 commit 978441f

File tree

10 files changed

+69
-25
lines changed

10 files changed

+69
-25
lines changed

balancer/grpclb/grpclb.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ func (b *lbBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) bal
136136

137137
lb := &lbBalancer{
138138
cc: newLBCacheClientConn(cc),
139-
dialTarget: opt.Target.Endpoint,
140-
target: opt.Target.Endpoint,
139+
dialTarget: opt.Target.ToEndpoint(),
140+
target: opt.Target.ToEndpoint(),
141141
opt: opt,
142142
fallbackTimeout: b.fallbackTimeout,
143143
doneCh: make(chan struct{}),

balancer/rls/balancer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ func (b *rlsBalancer) sendNewPickerLocked() {
448448
}
449449
picker := &rlsPicker{
450450
kbm: b.lbCfg.kbMap,
451-
origEndpoint: b.bopts.Target.Endpoint,
451+
origEndpoint: b.bopts.Target.ToEndpoint(),
452452
lb: b,
453453
defaultPolicy: b.defaultPolicy,
454454
ctrlCh: b.ctrlCh,

clientconn.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
256256
if err != nil {
257257
return nil, err
258258
}
259-
cc.authority, err = determineAuthority(cc.parsedTarget.Endpoint, cc.target, cc.dopts)
259+
cc.authority, err = determineAuthority(cc.parsedTarget.ToEndpoint(), cc.target, cc.dopts)
260260
if err != nil {
261261
return nil, err
262262
}

examples/features/load_balancing/client/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ type exampleResolver struct {
111111
}
112112

113113
func (r *exampleResolver) start() {
114-
addrStrs := r.addrsStore[r.target.Endpoint]
114+
addrStrs := r.addrsStore[r.target.ToEndpoint()]
115115
addrs := make([]resolver.Address, len(addrStrs))
116116
for i, s := range addrStrs {
117117
addrs[i] = resolver.Address{Addr: s}

examples/features/name_resolving/client/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ type exampleResolver struct {
119119
}
120120

121121
func (r *exampleResolver) start() {
122-
addrStrs := r.addrsStore[r.target.Endpoint]
122+
addrStrs := r.addrsStore[r.target.ToEndpoint()]
123123
addrs := make([]resolver.Address, len(addrStrs))
124124
for i, s := range addrStrs {
125125
addrs[i] = resolver.Address{Addr: s}

internal/resolver/dns/dns_resolver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ type dnsBuilder struct{}
116116

117117
// Build creates and starts a DNS resolver that watches the name resolution of the target.
118118
func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
119-
host, port, err := parseTarget(target.Endpoint, defaultPort)
119+
host, port, err := parseTarget(target.ToEndpoint(), defaultPort)
120120
if err != nil {
121121
return nil, err
122122
}

internal/resolver/dns/dns_resolver_test.go

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"errors"
2424
"fmt"
2525
"net"
26-
"net/url"
2726
"os"
2827
"reflect"
2928
"strings"
@@ -735,7 +734,7 @@ func testDNSResolver(t *testing.T) {
735734
for _, a := range tests {
736735
b := NewBuilder()
737736
cc := &testClientConn{target: a.target}
738-
r, err := b.Build(resolver.Target{Endpoint: a.target}, cc, resolver.BuildOptions{})
737+
r, err := b.Build(resolver.Target{Endpoint: a.target, URL: *testutils.MustParseURL(fmt.Sprintf("scheme:///%s", a.target))}, cc, resolver.BuildOptions{})
739738
if err != nil {
740739
t.Fatalf("%v\n", err)
741740
}
@@ -807,7 +806,7 @@ func TestDNSResolverExponentialBackoff(t *testing.T) {
807806
cc := &testClientConn{target: test.target}
808807
// Cause ClientConn to return an error.
809808
cc.updateStateErr = balancer.ErrBadResolverState
810-
r, err := b.Build(resolver.Target{Endpoint: test.target}, cc, resolver.BuildOptions{})
809+
r, err := b.Build(resolver.Target{Endpoint: test.target, URL: *testutils.MustParseURL(fmt.Sprintf("scheme:///%s", test.target))}, cc, resolver.BuildOptions{})
811810
if err != nil {
812811
t.Fatalf("Error building resolver for target %v: %v", test.target, err)
813812
}
@@ -962,7 +961,7 @@ func testDNSResolverWithSRV(t *testing.T) {
962961
for _, a := range tests {
963962
b := NewBuilder()
964963
cc := &testClientConn{target: a.target}
965-
r, err := b.Build(resolver.Target{Endpoint: a.target}, cc, resolver.BuildOptions{})
964+
r, err := b.Build(resolver.Target{Endpoint: a.target, URL: *testutils.MustParseURL(fmt.Sprintf("scheme:///%s", a.target))}, cc, resolver.BuildOptions{})
966965
if err != nil {
967966
t.Fatalf("%v\n", err)
968967
}
@@ -1046,7 +1045,7 @@ func testDNSResolveNow(t *testing.T) {
10461045
for _, a := range tests {
10471046
b := NewBuilder()
10481047
cc := &testClientConn{target: a.target}
1049-
r, err := b.Build(resolver.Target{Endpoint: a.target}, cc, resolver.BuildOptions{})
1048+
r, err := b.Build(resolver.Target{Endpoint: a.target, URL: *testutils.MustParseURL(fmt.Sprintf("scheme:///%s", a.target))}, cc, resolver.BuildOptions{})
10501049
if err != nil {
10511050
t.Fatalf("%v\n", err)
10521051
}
@@ -1124,7 +1123,7 @@ func testIPResolver(t *testing.T) {
11241123
for _, v := range tests {
11251124
b := NewBuilder()
11261125
cc := &testClientConn{target: v.target}
1127-
r, err := b.Build(resolver.Target{Endpoint: v.target}, cc, resolver.BuildOptions{})
1126+
r, err := b.Build(resolver.Target{Endpoint: v.target, URL: *testutils.MustParseURL(fmt.Sprintf("scheme:///%s", v.target))}, cc, resolver.BuildOptions{})
11281127
if err != nil {
11291128
t.Fatalf("%v\n", err)
11301129
}
@@ -1175,7 +1174,7 @@ func TestResolveFunc(t *testing.T) {
11751174
{"[2001:db8:a0b:12f0::1]:21", nil},
11761175
{":80", nil},
11771176
{"127.0.0...1:12345", nil},
1178-
{"[fe80::1%lo0]:80", nil},
1177+
{"[fe80::1%25lo0]:80", nil},
11791178
{"golang.org:http", nil},
11801179
{"[2001:db8::1]:http", nil},
11811180
{"[2001:db8::1]:", errEndsWithColon},
@@ -1187,7 +1186,7 @@ func TestResolveFunc(t *testing.T) {
11871186
b := NewBuilder()
11881187
for _, v := range tests {
11891188
cc := &testClientConn{target: v.addr, errChan: make(chan error, 1)}
1190-
r, err := b.Build(resolver.Target{Endpoint: v.addr}, cc, resolver.BuildOptions{})
1189+
r, err := b.Build(resolver.Target{Endpoint: v.addr, URL: *testutils.MustParseURL(fmt.Sprintf("scheme:///%s", v.addr))}, cc, resolver.BuildOptions{})
11911190
if err == nil {
11921191
r.Close()
11931192
}
@@ -1226,7 +1225,7 @@ func TestDisableServiceConfig(t *testing.T) {
12261225
for _, a := range tests {
12271226
b := NewBuilder()
12281227
cc := &testClientConn{target: a.target}
1229-
r, err := b.Build(resolver.Target{Endpoint: a.target}, cc, resolver.BuildOptions{DisableServiceConfig: a.disableServiceConfig})
1228+
r, err := b.Build(resolver.Target{Endpoint: a.target, URL: *testutils.MustParseURL(fmt.Sprintf("scheme:///%s", a.target))}, cc, resolver.BuildOptions{DisableServiceConfig: a.disableServiceConfig})
12301229
if err != nil {
12311230
t.Fatalf("%v\n", err)
12321231
}
@@ -1264,7 +1263,7 @@ func TestTXTError(t *testing.T) {
12641263
envconfig.TXTErrIgnore = ignore
12651264
b := NewBuilder()
12661265
cc := &testClientConn{target: "ipv4.single.fake"} // has A records but not TXT records.
1267-
r, err := b.Build(resolver.Target{Endpoint: "ipv4.single.fake"}, cc, resolver.BuildOptions{})
1266+
r, err := b.Build(resolver.Target{Endpoint: "ipv4.single.fake", URL: *testutils.MustParseURL(fmt.Sprintf("scheme:///%s", "ipv4.single.fake"))}, cc, resolver.BuildOptions{})
12681267
if err != nil {
12691268
t.Fatalf("%v\n", err)
12701269
}
@@ -1300,7 +1299,7 @@ func TestDNSResolverRetry(t *testing.T) {
13001299
b := NewBuilder()
13011300
target := "ipv4.single.fake"
13021301
cc := &testClientConn{target: target}
1303-
r, err := b.Build(resolver.Target{Endpoint: target}, cc, resolver.BuildOptions{})
1302+
r, err := b.Build(resolver.Target{Endpoint: target, URL: *testutils.MustParseURL(fmt.Sprintf("scheme:///%s", target))}, cc, resolver.BuildOptions{})
13041303
if err != nil {
13051304
t.Fatalf("%v\n", err)
13061305
}
@@ -1443,7 +1442,7 @@ func TestCustomAuthority(t *testing.T) {
14431442
target := resolver.Target{
14441443
Endpoint: "foo.bar.com",
14451444
Authority: a.authority,
1446-
URL: url.URL{Host: a.authority},
1445+
URL: *testutils.MustParseURL(fmt.Sprintf("scheme://%s/foo.bar.com", a.authority)),
14471446
}
14481447
r, err := b.Build(target, cc, resolver.BuildOptions{})
14491448

@@ -1501,7 +1500,7 @@ func TestRateLimitedResolve(t *testing.T) {
15011500
b := NewBuilder()
15021501
cc := &testClientConn{target: target}
15031502

1504-
r, err := b.Build(resolver.Target{Endpoint: target}, cc, resolver.BuildOptions{})
1503+
r, err := b.Build(resolver.Target{Endpoint: target, URL: *testutils.MustParseURL(fmt.Sprintf("scheme:///%s", target))}, cc, resolver.BuildOptions{})
15051504
if err != nil {
15061505
t.Fatalf("resolver.Build() returned error: %v\n", err)
15071506
}
@@ -1610,7 +1609,7 @@ func TestReportError(t *testing.T) {
16101609
cc := &testClientConn{target: target, errChan: make(chan error)}
16111610
totalTimesCalledError := 0
16121611
b := NewBuilder()
1613-
r, err := b.Build(resolver.Target{Endpoint: target}, cc, resolver.BuildOptions{})
1612+
r, err := b.Build(resolver.Target{Endpoint: target, URL: *testutils.MustParseURL(fmt.Sprintf("scheme:///%s", target))}, cc, resolver.BuildOptions{})
16141613
if err != nil {
16151614
t.Fatalf("Error building resolver for target %v: %v", target, err)
16161615
}

internal/resolver/passthrough/passthrough.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const scheme = "passthrough"
3131
type passthroughBuilder struct{}
3232

3333
func (*passthroughBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
34-
if target.Endpoint == "" && opts.Dialer == nil {
34+
if target.ToEndpoint() == "" && opts.Dialer == nil {
3535
return nil, errors.New("passthrough: received empty target in Build()")
3636
}
3737
r := &passthroughResolver{
@@ -52,7 +52,7 @@ type passthroughResolver struct {
5252
}
5353

5454
func (r *passthroughResolver) start() {
55-
r.cc.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: r.target.Endpoint}}})
55+
r.cc.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: r.target.ToEndpoint()}}})
5656
}
5757

5858
func (*passthroughResolver) ResolveNow(o resolver.ResolveNowOptions) {}

internal/testutils/parse_url.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
*
3+
* Copyright 2022 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 testutils
20+
21+
import (
22+
"fmt"
23+
"net/url"
24+
)
25+
26+
// MustParseURL attempts to parse the provided target using url.Parse()
27+
// and panics if the url parsing fails.
28+
func MustParseURL(target string) *url.URL {
29+
u, err := url.Parse(target)
30+
if err != nil {
31+
panic(fmt.Sprintf("Error parsing target(%s): %v", target, err))
32+
}
33+
return u
34+
}

resolver/resolver.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"context"
2525
"net"
2626
"net/url"
27+
"strings"
2728

2829
"google.golang.org/grpc/attributes"
2930
"google.golang.org/grpc/credentials"
@@ -247,8 +248,7 @@ type Target struct {
247248
Scheme string
248249
// Deprecated: use URL.Host instead.
249250
Authority string
250-
// Deprecated: use URL.Path or URL.Opaque instead. The latter is set when
251-
// the former is empty.
251+
// Deprecated: use ToEndpoint() instead.
252252
Endpoint string
253253
// URL contains the parsed dial target with an optional default scheme added
254254
// to it if the original dial target contained no scheme or contained an
@@ -257,6 +257,17 @@ type Target struct {
257257
URL url.URL
258258
}
259259

260+
// ToEndpoint retrieves endpoint without leading "/" from either `URL.Path`
261+
// or `URL.Opaque`. The latter is set when the former is empty.
262+
func (t Target) ToEndpoint() string {
263+
endpoint := t.URL.Path
264+
if endpoint == "" {
265+
endpoint = t.URL.Opaque
266+
}
267+
// Leading "/" is stripped to support existing resolver implementations.
268+
return strings.TrimPrefix(endpoint, "/")
269+
}
270+
260271
// Builder creates a resolver that will be used to watch name resolution updates.
261272
type Builder interface {
262273
// Build creates a new resolver for the given target.

0 commit comments

Comments
 (0)