Skip to content

Commit 3e8e161

Browse files
committed
Review comments #1.
1 parent 63be37a commit 3e8e161

File tree

5 files changed

+103
-48
lines changed

5 files changed

+103
-48
lines changed

clientconn.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,12 +1272,6 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
12721272
copts.ChannelzParentID = ac.channelzID
12731273
}
12741274

1275-
// gRPC, resolver, balancer etc. can specify arbitrary data in the
1276-
// Attributes field of resolver.Address, which is shoved into connectCtx
1277-
// that is passed to the transport layer. The transport layer passes the
1278-
// same context to the credential handshaker. This makes is possible for
1279-
// address specific arbitrary data to reach the credential handshaker.
1280-
connectCtx = credentials.WithAddressInfo(connectCtx, credentials.AddressInfo{Attr: addr.Attributes})
12811275
newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, addr, copts, onPrefaceReceipt, onGoAway, onClose)
12821276
if err != nil {
12831277
// newTr is either nil, or closed.

credentials/credentials.go

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -194,30 +194,31 @@ func RequestInfoFromContext(ctx context.Context) (ri RequestInfo, ok bool) {
194194
return
195195
}
196196

197-
// AddressInfo contains address related data attached to the context passed to
198-
// ClientHandshake. This makes it possible to pass arbitrary data to the
199-
// handshaker from gRPC, resolver, balancer etc. Individual credential
200-
// implementations control the actual format of the data that they are willing
201-
// to receive.
197+
// ClientHandshakeInfo holds data to be passed to ClientHandshake. This makes
198+
// it possible to pass arbitrary data to the handshaker from gRPC, resolver,
199+
// balancer etc. Individual credential implementations control the actual
200+
// format of the data that they are willing to receive.
202201
//
203202
// This API is experimental.
204-
type AddressInfo struct {
203+
type ClientHandshakeInfo struct {
205204
// Attr is a generic key/value store.
206205
Attr *attributes.Attributes
207206
}
208207

209-
// addressInfoKey is a struct used as the key to store AddressInfo in a context.
210-
type addressInfoKey struct{}
208+
// clientHandshakeInfoKey is a struct used as the key to store
209+
// ClientHandshakeInfo in a context.
210+
type clientHandshakeInfoKey struct{}
211211

212-
// WithAddressInfo returns a copy of parent with ai stored as a value.
213-
func WithAddressInfo(parent context.Context, ai AddressInfo) context.Context {
214-
return context.WithValue(parent, addressInfoKey{}, ai)
212+
// WithClientHandshakeInfo returns a copy of parent with chi stored as a value.
213+
func WithClientHandshakeInfo(parent context.Context, chi ClientHandshakeInfo) context.Context {
214+
return context.WithValue(parent, clientHandshakeInfoKey{}, chi)
215215
}
216216

217-
// AddressInfoFromContext returns the AddressInfo stored in ctx.
218-
func AddressInfoFromContext(ctx context.Context) AddressInfo {
219-
ai, _ := ctx.Value(addressInfoKey{}).(AddressInfo)
220-
return ai
217+
// ClientHandshakeInfoFromContext returns the ClientHandshakeInfo struct stored
218+
// in ctx.
219+
func ClientHandshakeInfoFromContext(ctx context.Context) ClientHandshakeInfo {
220+
chi, _ := ctx.Value(clientHandshakeInfoKey{}).(ClientHandshakeInfo)
221+
return chi
221222
}
222223

223224
// CheckSecurityLevel checks if a connection's security level is greater than or equal to the specified one.

internal/transport/http2_client.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
215215
}
216216
}
217217
if transportCreds != nil {
218+
// gRPC, resolver, balancer etc. can specify arbitrary data in the
219+
// Attributes field of resolver.Address, which is shoved into connectCtx
220+
// and passed to the credential handshaker. This makes it possible for
221+
// address specific arbitrary data to reach the credential handshaker.
222+
connectCtx = credentials.WithClientHandshakeInfo(connectCtx, credentials.ClientHandshakeInfo{Attr: addr.Attributes})
218223
scheme = "https"
219224
conn, authInfo, err = transportCreds.ClientHandshake(connectCtx, addr.ServerName, conn)
220225
if err != nil {

internal/transport/transport_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,12 @@ import (
3434
"testing"
3535
"time"
3636

37+
"github.com/google/go-cmp/cmp"
3738
"golang.org/x/net/http2"
3839
"golang.org/x/net/http2/hpack"
40+
"google.golang.org/grpc/attributes"
3941
"google.golang.org/grpc/codes"
42+
"google.golang.org/grpc/credentials"
4043
"google.golang.org/grpc/internal/grpctest"
4144
"google.golang.org/grpc/internal/leakcheck"
4245
"google.golang.org/grpc/internal/testutils"
@@ -1816,3 +1819,54 @@ func (s) TestHeaderTblSize(t *testing.T) {
18161819
t.Fatalf("expected len(limits) = 2 within 10s, got != 2")
18171820
}
18181821
}
1822+
1823+
// attrTransportCreds is a transport credential implementation which stores
1824+
// Attributes from the ClientHandshakeInfo struct passed in the context locally
1825+
// for the test to inspect.
1826+
type attrTransportCreds struct {
1827+
credentials.TransportCredentials
1828+
attr *attributes.Attributes
1829+
}
1830+
1831+
func (ac *attrTransportCreds) ClientHandshake(ctx context.Context, addr string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
1832+
ai := credentials.ClientHandshakeInfoFromContext(ctx)
1833+
ac.attr = ai.Attr
1834+
return rawConn, nil, nil
1835+
}
1836+
func (ac *attrTransportCreds) Info() credentials.ProtocolInfo {
1837+
return credentials.ProtocolInfo{}
1838+
}
1839+
func (ac *attrTransportCreds) Clone() credentials.TransportCredentials {
1840+
return nil
1841+
}
1842+
1843+
// TestClientHandshakeInfo adds attributes to the resolver.Address passes to
1844+
// NewClientTransport and verifies that these attributes are received by the
1845+
// transport credential handshaker.
1846+
func (s) TestClientHandshakeInfo(t *testing.T) {
1847+
server := setUpServerOnly(t, 0, &ServerConfig{}, pingpong)
1848+
defer server.stop()
1849+
1850+
const (
1851+
testAttrKey = "foo"
1852+
testAttrVal = "bar"
1853+
)
1854+
addr := resolver.Address{
1855+
Addr: "localhost:" + server.port,
1856+
Attributes: attributes.New(testAttrKey, testAttrVal),
1857+
}
1858+
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(2*time.Second))
1859+
defer cancel()
1860+
creds := &attrTransportCreds{}
1861+
1862+
tr, err := NewClientTransport(ctx, context.Background(), addr, ConnectOptions{TransportCredentials: creds}, func() {}, func(GoAwayReason) {}, func() {})
1863+
if err != nil {
1864+
t.Fatalf("NewClientTransport(): %v", err)
1865+
}
1866+
defer tr.Close()
1867+
1868+
wantAttr := attributes.New(testAttrKey, testAttrVal)
1869+
if gotAttr := creds.attr; !cmp.Equal(gotAttr, wantAttr, cmp.AllowUnexported(attributes.Attributes{})) {
1870+
t.Fatalf("received attributes %v in creds, want %v", gotAttr, wantAttr)
1871+
}
1872+
}

test/balancer_test.go

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -353,27 +353,27 @@ func (s) TestNonGRPCLBBalancerGetsNoGRPCLBAddress(t *testing.T) {
353353
}
354354
}
355355

356-
const aiBalancerName = "addrInfo-attribute-balancer"
356+
const attrBalancerName = "attribute-balancer"
357357

358-
// aiBalancerBuilder builds a balancer and passes the attribute key and value
358+
// attrBalancerBuilder builds a balancer and passes the attribute key and value
359359
// with which it was configured at creation time by the test.
360-
type aiBalancerBuilder struct {
360+
type attrBalancerBuilder struct {
361361
attrKey string
362362
attrVal string
363363
}
364364

365-
func (bb *aiBalancerBuilder) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer {
366-
return &aiBalancer{cc: cc, attrKey: bb.attrKey, attrVal: bb.attrVal}
365+
func (bb *attrBalancerBuilder) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer {
366+
return &attrBalancer{cc: cc, attrKey: bb.attrKey, attrVal: bb.attrVal}
367367
}
368368

369-
func (bb *aiBalancerBuilder) Name() string {
370-
return aiBalancerName
369+
func (bb *attrBalancerBuilder) Name() string {
370+
return attrBalancerName
371371
}
372372

373-
// aiBalancer receives an attribute key and value which it adds to the address
374-
// that it calls NewSubConn on. This key/value pair reaches the credential
375-
// handshaker and the test verifies the same.
376-
type aiBalancer struct {
373+
// attrBalancer receives an attribute key and value which it adds to the
374+
// address that it calls NewSubConn on. This key/value pair reaches the
375+
// credential handshaker and the test verifies the same.
376+
type attrBalancer struct {
377377
balancer.Balancer
378378
cc balancer.ClientConn
379379
attrKey string
@@ -382,7 +382,7 @@ type aiBalancer struct {
382382

383383
// UpdateClientConnState adds an attribute with the configured key/value to the
384384
// addresses received and invokes NewSubConn.
385-
func (b *aiBalancer) UpdateClientConnState(ccs balancer.ClientConnState) error {
385+
func (b *attrBalancer) UpdateClientConnState(ccs balancer.ClientConnState) error {
386386
addrs := ccs.ResolverState.Addresses
387387
if len(addrs) == 0 {
388388
return nil
@@ -399,12 +399,12 @@ func (b *aiBalancer) UpdateClientConnState(ccs balancer.ClientConnState) error {
399399
return nil
400400
}
401401

402-
func (b *aiBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
402+
func (b *attrBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
403403
b.cc.UpdateState(balancer.State{ConnectivityState: state.ConnectivityState, Picker: &aiPicker{result: balancer.PickResult{SubConn: sc}, err: state.ConnectionError}})
404404
}
405405

406-
func (b *aiBalancer) ResolverError(error) {}
407-
func (b *aiBalancer) Close() {}
406+
func (b *attrBalancer) ResolverError(error) {}
407+
func (b *attrBalancer) Close() {}
408408

409409
type aiPicker struct {
410410
result balancer.PickResult
@@ -415,22 +415,23 @@ func (aip *aiPicker) Pick(_ balancer.PickInfo) (balancer.PickResult, error) {
415415
return aip.result, aip.err
416416
}
417417

418-
// addrInfoTransportCreds is a transport credential implementation which stores
419-
// the Attributes struct passed in the context locally for the test to inspect.
420-
type addrInfoTransportCreds struct {
418+
// attrTransportCreds is a transport credential implementation which stores
419+
// Attributes from the ClientHandshakeInfo struct passed in the context locally
420+
// for the test to inspect.
421+
type attrTransportCreds struct {
421422
credentials.TransportCredentials
422423
attr *attributes.Attributes
423424
}
424425

425-
func (ac *addrInfoTransportCreds) ClientHandshake(ctx context.Context, addr string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
426-
ai := credentials.AddressInfoFromContext(ctx)
426+
func (ac *attrTransportCreds) ClientHandshake(ctx context.Context, addr string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
427+
ai := credentials.ClientHandshakeInfoFromContext(ctx)
427428
ac.attr = ai.Attr
428429
return rawConn, nil, nil
429430
}
430-
func (ac *addrInfoTransportCreds) Info() credentials.ProtocolInfo {
431+
func (ac *attrTransportCreds) Info() credentials.ProtocolInfo {
431432
return credentials.ProtocolInfo{}
432433
}
433-
func (ac *addrInfoTransportCreds) Clone() credentials.TransportCredentials {
434+
func (ac *attrTransportCreds) Clone() credentials.TransportCredentials {
434435
return nil
435436
}
436437

@@ -444,9 +445,9 @@ func (s) TestAddressAttributesInNewSubConn(t *testing.T) {
444445
testAttrVal = "bar"
445446
)
446447

447-
balancer.Register(&aiBalancerBuilder{attrKey: testAttrKey, attrVal: testAttrVal})
448-
defer internal.BalancerUnregister(aiBalancerName)
449-
t.Logf("Registered balancer %s...", aiBalancerName)
448+
balancer.Register(&attrBalancerBuilder{attrKey: testAttrKey, attrVal: testAttrVal})
449+
defer internal.BalancerUnregister(attrBalancerName)
450+
t.Logf("Registered balancer %s...", attrBalancerName)
450451

451452
r, cleanup := manual.GenerateAndRegisterManualResolver()
452453
defer cleanup()
@@ -463,10 +464,10 @@ func (s) TestAddressAttributesInNewSubConn(t *testing.T) {
463464
defer s.Stop()
464465
t.Logf("Started gRPC server at %s...", lis.Addr().String())
465466

466-
creds := &addrInfoTransportCreds{}
467+
creds := &attrTransportCreds{}
467468
dopts := []grpc.DialOption{
468469
grpc.WithTransportCredentials(creds),
469-
grpc.WithDefaultServiceConfig(fmt.Sprintf(`{ "loadBalancingConfig": [{"%v": {}}] }`, aiBalancerName)),
470+
grpc.WithDefaultServiceConfig(fmt.Sprintf(`{ "loadBalancingConfig": [{"%v": {}}] }`, attrBalancerName)),
470471
}
471472
cc, err := grpc.Dial(r.Scheme()+":///test.server", dopts...)
472473
if err != nil {

0 commit comments

Comments
 (0)