[#131] client: add basic netmap dialer

Signed-off-by: olefirenque <egor.olefirenko892@gmail.com>
This commit is contained in:
Egor Olefirenko 2023-11-30 13:12:15 +03:00
parent 56debcfa56
commit 6ace44f6b5
2 changed files with 61 additions and 0 deletions

View file

@ -5,6 +5,10 @@ import (
"crypto/ecdsa"
"crypto/tls"
"errors"
"fmt"
netmap "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap/grpc"
"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)
}