WIP: [#131] add netmap-aware dialer #196

Closed
olefirenque wants to merge 5 commits from olefirenque/frostfs-sdk-go:173-add_netmap_aware_dialer into master
2 changed files with 61 additions and 0 deletions
Showing only changes of commit 6ace44f6b5 - Show all commits

View file

@ -5,6 +5,10 @@ import (
"crypto/ecdsa"
"crypto/tls"
"errors"
"fmt"
netmap "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap/grpc"
Review

stdlib imports should form a separate group, could you move netmap below?

stdlib imports should form a separate group, could you move `netmap` below?
Review

stdlib imports should form a separate group, could you move netmap below?

stdlib imports should form a separate group, could you move `netmap` below?
Review

Also, we have netmap in the SDK (this repo), can we use it instead of the api package?

Also, we have netmap in the SDK (this repo), can we use it instead of the api package?
Review

Yes, I used the grpc domain by mistake.
Fixed.

Yes, I used the grpc domain by mistake. Fixed.
"net/url"
"slices"
"time"
v2accounting "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/accounting"
@ -110,6 +114,22 @@ func (c *Client) Dial(ctx context.Context, prm PrmDial) error {
return nil
}
func (c *Client) NetMapDial(ctx context.Context, endpoint string) error {
u, err := url.Parse(endpoint)
if err != nil {
return err
}
if u.Scheme == "frostfs" {
nodes := c.prm.NetMap.GetNodes()
for _, node := range nodes {
if slices.Equal([]byte(u.Host), node.PublicKey) {
return c.Dial(ctx, PrmDial{Endpoint: node.Addresses[0]})
}
}
}
return fmt.Errorf("dial failure: endpoint %s isn't valid", endpoint)
}
// sets underlying provider of frostFSAPIServer. The method is used for testing as an approach
// to skip Dial stage and override FrostFS API server. MUST NOT be used outside test code.
// In real applications wrapper over git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client
@ -141,6 +161,8 @@ type PrmInit struct {
ResponseInfoCallback func(ResponseMetaInfo) error
NetMap *netmap.Netmap
NetMagic uint64
}

View file

@ -5,6 +5,8 @@ import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"fmt"
netmap "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap/grpc"
"testing"
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
@ -65,3 +67,40 @@ func TestClient_DialContext(t *testing.T) {
assert(ctx, context.DeadlineExceeded)
}
func TestClient_NetMapDialContext(t *testing.T) {
var prmInit PrmInit
var c Client
publicKey := "foo"
endpoint := "localhost:8080"
prmInit.NetMap = &netmap.Netmap{
Epoch: 0,
Nodes: []*netmap.NodeInfo{
{
PublicKey: []byte(publicKey),
Addresses: []string{endpoint},
},
},
}
c.Init(prmInit)
assert := func(ctx context.Context, errExpected error) {
// expect particular context error according to Dial docs
//require.ErrorIs(t, c.Dial(ctx, prm), errExpected)
require.ErrorIs(t, c.NetMapDial(ctx, fmt.Sprintf("frostfs://%s", publicKey)), errExpected)
}
// create pre-abandoned context
ctx, cancel := context.WithCancel(context.Background())
cancel()
assert(ctx, context.Canceled)
// create "pre-deadlined" context
ctx, cancel = context.WithTimeout(context.Background(), 0)
defer cancel()
assert(ctx, context.DeadlineExceeded)
}