Skip to content

Commit

Permalink
add attributes package
Browse files Browse the repository at this point in the history
  • Loading branch information
eshitachandwani committed Nov 29, 2024
1 parent 2be9db3 commit 67e3799
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 36 deletions.
55 changes: 55 additions & 0 deletions internal/attributes/attributes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
*
* Copyright 2024 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 attributes contains functions for getting and setting attributes.
package attributes

import (
"net/url"

"google.golang.org/grpc/resolver"
)

type keyType string

const userAndConnectAddrKey = keyType("grpc.resolver.delegatingresolver.userAndConnectAddr")

type attr struct {
user *url.Userinfo
addr string
}

// SetUserAndConnectAddr returns a copy of the provided resolver.Address with
// attributes containing address to be sent in connect request to proxy and the
// user info. It's data should not be mutated after calling SetConnectAddr.
func SetUserAndConnectAddr(resAddr resolver.Address, user *url.Userinfo, addr string) resolver.Address {
resAddr.Attributes = resAddr.Attributes.WithValue(userAndConnectAddrKey, attr{user: user, addr: addr})
return resAddr
}

// ProxyConnectAddr returns the proxy connect address in resolver.Address, or nil
// if not present. The returned data should not be mutated.
func ProxyConnectAddr(addr resolver.Address) string {
return addr.Attributes.Value(userAndConnectAddrKey).(attr).addr

Check warning on line 48 in internal/attributes/attributes.go

View check run for this annotation

Codecov / codecov/patch

internal/attributes/attributes.go#L47-L48

Added lines #L47 - L48 were not covered by tests
}

// User returns the user info in the resolver.Address, or nil if not present.
// The returned data should not be mutated.
func User(addr resolver.Address) *url.Userinfo {
return addr.Attributes.Value(userAndConnectAddrKey).(attr).user

Check warning on line 54 in internal/attributes/attributes.go

View check run for this annotation

Codecov / codecov/patch

internal/attributes/attributes.go#L53-L54

Added lines #L53 - L54 were not covered by tests
}
32 changes: 2 additions & 30 deletions internal/resolver/delegatingresolver/delegatingresolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"sync"

"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/attributes"
"google.golang.org/grpc/resolver"
"google.golang.org/grpc/serviceconfig"
)
Expand Down Expand Up @@ -147,41 +148,12 @@ func (r *delegatingResolver) Close() {
}

Check warning on line 148 in internal/resolver/delegatingresolver/delegatingresolver.go

View check run for this annotation

Codecov / codecov/patch

internal/resolver/delegatingresolver/delegatingresolver.go#L142-L148

Added lines #L142 - L148 were not covered by tests
}

type keyType string

const userAndConnectAddrKey = keyType("grpc.resolver.delegatingresolver.userAndConnectAddr")

type attr struct {
user *url.Userinfo
addr string
}

// SetUserAndConnectAddr returns a copy of the provided resolver.Address with
// attributes containing address to be sent in connect request to proxy and the
// user info. It's data should not be mutated after calling SetConnectAddr.
func SetUserAndConnectAddr(resAddr resolver.Address, user *url.Userinfo, addr string) resolver.Address {
resAddr.Attributes = resAddr.Attributes.WithValue(userAndConnectAddrKey, attr{user: user, addr: addr})
return resAddr
}

// ProxyConnectAddr returns the proxy connect address in resolver.Address, or nil
// if not present. The returned data should not be mutated.
func ProxyConnectAddr(addr resolver.Address) string {
return addr.Attributes.Value(userAndConnectAddrKey).(attr).addr
}

// User returns the user info in the resolver.Address, or nil if not present.
// The returned data should not be mutated.
func User(addr resolver.Address) *url.Userinfo {
return addr.Attributes.Value(userAndConnectAddrKey).(attr).user
}

func (r *delegatingResolver) updateState() []resolver.Address {
var addresses []resolver.Address
for _, proxyAddr := range r.proxyAddrs {
for _, targetAddr := range r.targetAddrs {
newAddr := resolver.Address{Addr: proxyAddr.Addr}
newAddr = SetUserAndConnectAddr(newAddr, r.proxyURL.User, targetAddr.Addr)
newAddr = attributes.SetUserAndConnectAddr(newAddr, r.proxyURL.User, targetAddr.Addr)
addresses = append(addresses, newAddr)
}
}
Expand Down
13 changes: 7 additions & 6 deletions internal/resolver/delegatingresolver/delegatingresolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"testing"

"github.com/google/go-cmp/cmp"
"google.golang.org/grpc/internal/attributes"
"google.golang.org/grpc/internal/grpctest"
"google.golang.org/grpc/internal/testutils"
"google.golang.org/grpc/resolver"
Expand Down Expand Up @@ -182,7 +183,7 @@ func (s) TestDelegatingResolverwithDNSAndProxyWithTargetResolution(t *testing.T)

// Verify that the delegating resolver outputs the same address.
expectedAddr := resolver.Address{Addr: resolvedProxyTestAddr}
expectedAddr = SetUserAndConnectAddr(expectedAddr, nil, resolvedTargetTestAddr)
expectedAddr = attributes.SetUserAndConnectAddr(expectedAddr, nil, resolvedTargetTestAddr)
expectedState := resolver.State{Addresses: []resolver.Address{expectedAddr}}

if state := <-stateCh; len(state.Addresses) != 1 || !cmp.Equal(expectedState, state) {
Expand Down Expand Up @@ -226,7 +227,7 @@ func (s) TestDelegatingResolverwithDNSAndProxyWithNoTargetResolution(t *testing.

// Verify that the delegating resolver outputs the same address.
expectedAddr := resolver.Address{Addr: resolvedProxyTestAddr}
expectedAddr = SetUserAndConnectAddr(expectedAddr, nil, targetTestAddr)
expectedAddr = attributes.SetUserAndConnectAddr(expectedAddr, nil, targetTestAddr)
expectedState := resolver.State{Addresses: []resolver.Address{expectedAddr}}

if state := <-stateCh; len(state.Addresses) != 1 || !cmp.Equal(expectedState, state) {
Expand Down Expand Up @@ -279,16 +280,16 @@ func (s) TestDelegatingResolverwithCustomResolverAndProxy(t *testing.T) {
})

expectedAddr := resolver.Address{Addr: resolvedProxyTestAddr}
expectedAddr = SetUserAndConnectAddr(expectedAddr, nil, resolvedTargetTestAddr)
expectedAddr = attributes.SetUserAndConnectAddr(expectedAddr, nil, resolvedTargetTestAddr)

expectedAddr1 := resolver.Address{Addr: resolvedProxyTestAddr}
expectedAddr1 = SetUserAndConnectAddr(expectedAddr1, nil, resolvedTargetTestAddr1)
expectedAddr1 = attributes.SetUserAndConnectAddr(expectedAddr1, nil, resolvedTargetTestAddr1)

expectedAddr2 := resolver.Address{Addr: resolvedProxyTestAddr1}
expectedAddr2 = SetUserAndConnectAddr(expectedAddr2, nil, resolvedTargetTestAddr)
expectedAddr2 = attributes.SetUserAndConnectAddr(expectedAddr2, nil, resolvedTargetTestAddr)

expectedAddr3 := resolver.Address{Addr: resolvedProxyTestAddr1}
expectedAddr3 = SetUserAndConnectAddr(expectedAddr3, nil, resolvedTargetTestAddr1)
expectedAddr3 = attributes.SetUserAndConnectAddr(expectedAddr3, nil, resolvedTargetTestAddr1)

expectedState := resolver.State{Addresses: []resolver.Address{
expectedAddr,
Expand Down

0 comments on commit 67e3799

Please sign in to comment.