From c16177901e458c9e0e02500e686abd25bb63877d Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Wed, 18 Dec 2024 19:10:21 +0300 Subject: [PATCH] cli/control: Do not use API client from NeoFS SDK It makes no sense to create client just get underlying connection from it. Instead, direct gRPC dial should be used. This inlines `Client.Dial` to keep previous behavior as much as possible (some error texts could change only). URI parser is copy-pasted because it's internalized by the SDK. Even if it'd export it, we are not ready for the upgrade to the latest yet. Starting from here, `cmd/neofs-cli` packages (all CLI apps actually) no longer uses `github.com/nspcc-dev/neofs-api-go/v2` directly which is good considering the upcoming abandonment of it. Signed-off-by: Leonard Lyubich --- cmd/neofs-cli/modules/control/drop_objects.go | 7 +- .../modules/control/evacuate_shard.go | 7 +- cmd/neofs-cli/modules/control/flush_cache.go | 7 +- cmd/neofs-cli/modules/control/healthcheck.go | 21 +- cmd/neofs-cli/modules/control/object_list.go | 36 ++- .../modules/control/object_revive.go | 7 +- .../modules/control/object_status.go | 7 +- .../modules/control/set_netmap_status.go | 7 +- cmd/neofs-cli/modules/control/shards_dump.go | 7 +- cmd/neofs-cli/modules/control/shards_list.go | 7 +- .../modules/control/shards_restore.go | 7 +- .../modules/control/shards_set_mode.go | 7 +- .../modules/control/synchronize_tree.go | 7 +- cmd/neofs-cli/modules/control/util.go | 100 ++++++- cmd/neofs-cli/modules/control/util_test.go | 49 ++++ pkg/services/control/convert.go | 257 ----------------- pkg/services/control/ir/convert.go | 34 --- pkg/services/control/ir/rpc.go | 34 --- pkg/services/control/rpc.go | 270 ------------------ 19 files changed, 183 insertions(+), 695 deletions(-) create mode 100644 cmd/neofs-cli/modules/control/util_test.go delete mode 100644 pkg/services/control/convert.go delete mode 100644 pkg/services/control/ir/convert.go delete mode 100644 pkg/services/control/ir/rpc.go delete mode 100644 pkg/services/control/rpc.go diff --git a/cmd/neofs-cli/modules/control/drop_objects.go b/cmd/neofs-cli/modules/control/drop_objects.go index 47d0122421..0f522d4c68 100644 --- a/cmd/neofs-cli/modules/control/drop_objects.go +++ b/cmd/neofs-cli/modules/control/drop_objects.go @@ -1,7 +1,6 @@ package control import ( - rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key" "github.com/nspcc-dev/neofs-node/pkg/services/control" @@ -47,11 +46,7 @@ var dropObjectsCmd = &cobra.Command{ return err } - var resp *control.DropObjectsResponse - err = cli.ExecRaw(func(client *rawclient.Client) error { - resp, err = control.DropObjects(client, req) - return err - }) + resp, err := cli.DropObjects(ctx, req) if err != nil { return err } diff --git a/cmd/neofs-cli/modules/control/evacuate_shard.go b/cmd/neofs-cli/modules/control/evacuate_shard.go index a30c323cc6..e65635ff45 100644 --- a/cmd/neofs-cli/modules/control/evacuate_shard.go +++ b/cmd/neofs-cli/modules/control/evacuate_shard.go @@ -3,7 +3,6 @@ package control import ( "fmt" - "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key" "github.com/nspcc-dev/neofs-node/pkg/services/control" @@ -44,11 +43,7 @@ func evacuateShard(cmd *cobra.Command, _ []string) error { return err } - var resp *control.EvacuateShardResponse - err = cli.ExecRaw(func(client *client.Client) error { - resp, err = control.EvacuateShard(client, req) - return err - }) + resp, err := cli.EvacuateShard(ctx, req) if err != nil { return fmt.Errorf("rpc error: %w", err) } diff --git a/cmd/neofs-cli/modules/control/flush_cache.go b/cmd/neofs-cli/modules/control/flush_cache.go index 58d3ad5f8a..6dfa13689f 100644 --- a/cmd/neofs-cli/modules/control/flush_cache.go +++ b/cmd/neofs-cli/modules/control/flush_cache.go @@ -3,7 +3,6 @@ package control import ( "fmt" - "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key" "github.com/nspcc-dev/neofs-node/pkg/services/control" @@ -43,11 +42,7 @@ func flushCache(cmd *cobra.Command, _ []string) error { return err } - var resp *control.FlushCacheResponse - err = cli.ExecRaw(func(client *client.Client) error { - resp, err = control.FlushCache(client, req) - return err - }) + resp, err := cli.FlushCache(ctx, req) if err != nil { return fmt.Errorf("rpc error: %w", err) } diff --git a/cmd/neofs-cli/modules/control/healthcheck.go b/cmd/neofs-cli/modules/control/healthcheck.go index 2e4206e0cc..5a0d898cb3 100644 --- a/cmd/neofs-cli/modules/control/healthcheck.go +++ b/cmd/neofs-cli/modules/control/healthcheck.go @@ -1,17 +1,16 @@ package control import ( + "context" "crypto/ecdsa" "fmt" "os" - rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key" "github.com/nspcc-dev/neofs-node/pkg/services/control" ircontrol "github.com/nspcc-dev/neofs-node/pkg/services/control/ir" ircontrolsrv "github.com/nspcc-dev/neofs-node/pkg/services/control/ir/server" - "github.com/nspcc-dev/neofs-sdk-go/client" "github.com/spf13/cobra" ) @@ -43,13 +42,13 @@ func healthCheck(cmd *cobra.Command, _ []string) error { return err } - cli, err := getClient(ctx) + conn, err := connect(ctx) if err != nil { return err } if isIR, _ := cmd.Flags().GetBool(healthcheckIRFlag); isIR { - return healthCheckIR(cmd, pk, cli) + return healthCheckIR(ctx, cmd, pk, ircontrol.NewControlServiceClient(conn)) } req := new(control.HealthCheckRequest) @@ -60,11 +59,7 @@ func healthCheck(cmd *cobra.Command, _ []string) error { return err } - var resp *control.HealthCheckResponse - err = cli.ExecRaw(func(client *rawclient.Client) error { - resp, err = control.HealthCheck(client, req) - return err - }) + resp, err := control.NewControlServiceClient(conn).HealthCheck(ctx, req) if err != nil { return fmt.Errorf("rpc error: %w", err) } @@ -85,7 +80,7 @@ func healthCheck(cmd *cobra.Command, _ []string) error { return nil } -func healthCheckIR(cmd *cobra.Command, key *ecdsa.PrivateKey, c *client.Client) error { +func healthCheckIR(ctx context.Context, cmd *cobra.Command, key *ecdsa.PrivateKey, c ircontrol.ControlServiceClient) error { req := new(ircontrol.HealthCheckRequest) req.SetBody(new(ircontrol.HealthCheckRequest_Body)) @@ -95,11 +90,7 @@ func healthCheckIR(cmd *cobra.Command, key *ecdsa.PrivateKey, c *client.Client) return fmt.Errorf("could not sign request: %w", err) } - var resp *ircontrol.HealthCheckResponse - err = c.ExecRaw(func(client *rawclient.Client) error { - resp, err = ircontrol.HealthCheck(client, req) - return err - }) + resp, err := c.HealthCheck(ctx, req) if err != nil { return fmt.Errorf("rpc error: %w", err) } diff --git a/cmd/neofs-cli/modules/control/object_list.go b/cmd/neofs-cli/modules/control/object_list.go index 4e08e59c1f..a43c6e0cd5 100644 --- a/cmd/neofs-cli/modules/control/object_list.go +++ b/cmd/neofs-cli/modules/control/object_list.go @@ -1,9 +1,10 @@ package control import ( + "errors" "fmt" + "io" - rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key" "github.com/nspcc-dev/neofs-node/pkg/services/control" @@ -44,22 +45,27 @@ func listObjects(cmd *cobra.Command, _ []string) error { return err } - err = cli.ExecRaw(func(client *rawclient.Client) error { - return control.ListObjects(client, req, func(r *control.ListObjectsResponse) error { - err := verifyResponse(r.GetSignature(), r.GetBody()) - if err != nil { - return err - } - - for _, address := range r.GetBody().GetObjectAddress() { - cmd.Println(string(address)) - } - return nil - }) - }) + stream, err := cli.ListObjects(ctx, req) if err != nil { return fmt.Errorf("rpc error: %w", err) } - return nil + for { + resp, err := stream.Recv() + if err != nil { + if errors.Is(err, io.EOF) { + return nil + } + return fmt.Errorf("rpc error: %w", err) + } + + body := resp.GetBody() + if err := verifyResponse(resp.GetSignature(), body); err != nil { + return err + } + + for _, address := range body.GetObjectAddress() { + cmd.Println(string(address)) + } + } } diff --git a/cmd/neofs-cli/modules/control/object_revive.go b/cmd/neofs-cli/modules/control/object_revive.go index 6926c94833..f53152fe20 100644 --- a/cmd/neofs-cli/modules/control/object_revive.go +++ b/cmd/neofs-cli/modules/control/object_revive.go @@ -3,7 +3,6 @@ package control import ( "fmt" - rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key" "github.com/nspcc-dev/neofs-node/pkg/services/control" @@ -38,7 +37,6 @@ func reviveObject(cmd *cobra.Command, _ []string) error { return fmt.Errorf("reading %s flag: %w", objectFlag, err) } - var resp *control.ReviveObjectResponse req := &control.ReviveObjectRequest{ Body: &control.ReviveObjectRequest_Body{ ObjectAddress: []byte(addressRaw), @@ -54,10 +52,7 @@ func reviveObject(cmd *cobra.Command, _ []string) error { return err } - err = cli.ExecRaw(func(client *rawclient.Client) error { - resp, err = control.ReviveObject(client, req) - return err - }) + resp, err := cli.ReviveObject(ctx, req) if err != nil { return fmt.Errorf("rpc error: %w", err) } diff --git a/cmd/neofs-cli/modules/control/object_status.go b/cmd/neofs-cli/modules/control/object_status.go index 6d976c9d94..f9651e9f07 100644 --- a/cmd/neofs-cli/modules/control/object_status.go +++ b/cmd/neofs-cli/modules/control/object_status.go @@ -3,7 +3,6 @@ package control import ( "fmt" - rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key" "github.com/nspcc-dev/neofs-node/pkg/services/control" @@ -38,7 +37,6 @@ func objectStatus(cmd *cobra.Command, _ []string) error { return fmt.Errorf("validating address (%s): %w", addressRaw, err) } - var resp *control.ObjectStatusResponse req := &control.ObjectStatusRequest{ Body: &control.ObjectStatusRequest_Body{ ObjectAddress: addressRaw, @@ -54,10 +52,7 @@ func objectStatus(cmd *cobra.Command, _ []string) error { return err } - err = cli.ExecRaw(func(client *rawclient.Client) error { - resp, err = control.ObjectStatus(client, req) - return err - }) + resp, err := cli.ObjectStatus(ctx, req) if err != nil { return fmt.Errorf("rpc error: %w", err) } diff --git a/cmd/neofs-cli/modules/control/set_netmap_status.go b/cmd/neofs-cli/modules/control/set_netmap_status.go index 2c23d1a3e6..9a5561038a 100644 --- a/cmd/neofs-cli/modules/control/set_netmap_status.go +++ b/cmd/neofs-cli/modules/control/set_netmap_status.go @@ -3,7 +3,6 @@ package control import ( "fmt" - rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key" @@ -93,11 +92,7 @@ func setNetmapStatus(cmd *cobra.Command, _ []string) error { return err } - var resp *control.SetNetmapStatusResponse - err = cli.ExecRaw(func(client *rawclient.Client) error { - resp, err = control.SetNetmapStatus(client, req) - return err - }) + resp, err := cli.SetNetmapStatus(ctx, req) if err != nil { return fmt.Errorf("rpc error: %w", err) } diff --git a/cmd/neofs-cli/modules/control/shards_dump.go b/cmd/neofs-cli/modules/control/shards_dump.go index aa76843586..c035a39584 100644 --- a/cmd/neofs-cli/modules/control/shards_dump.go +++ b/cmd/neofs-cli/modules/control/shards_dump.go @@ -3,7 +3,6 @@ package control import ( "fmt" - "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key" "github.com/nspcc-dev/neofs-node/pkg/services/control" @@ -58,11 +57,7 @@ func dumpShard(cmd *cobra.Command, _ []string) error { return err } - var resp *control.DumpShardResponse - err = cli.ExecRaw(func(client *client.Client) error { - resp, err = control.DumpShard(client, req) - return err - }) + resp, err := cli.DumpShard(ctx, req) if err != nil { return fmt.Errorf("rpc error: %w", err) } diff --git a/cmd/neofs-cli/modules/control/shards_list.go b/cmd/neofs-cli/modules/control/shards_list.go index 5e8500917c..dc5aff3a01 100644 --- a/cmd/neofs-cli/modules/control/shards_list.go +++ b/cmd/neofs-cli/modules/control/shards_list.go @@ -7,7 +7,6 @@ import ( "strings" "github.com/mr-tron/base58" - rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key" "github.com/nspcc-dev/neofs-node/pkg/services/control" @@ -51,11 +50,7 @@ func listShards(cmd *cobra.Command, _ []string) error { return err } - var resp *control.ListShardsResponse - err = cli.ExecRaw(func(client *rawclient.Client) error { - resp, err = control.ListShards(client, req) - return err - }) + resp, err := cli.ListShards(ctx, req) if err != nil { return fmt.Errorf("rpc error: %w", err) } diff --git a/cmd/neofs-cli/modules/control/shards_restore.go b/cmd/neofs-cli/modules/control/shards_restore.go index dee5b3d96e..6e66a8b8fb 100644 --- a/cmd/neofs-cli/modules/control/shards_restore.go +++ b/cmd/neofs-cli/modules/control/shards_restore.go @@ -3,7 +3,6 @@ package control import ( "fmt" - "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key" "github.com/nspcc-dev/neofs-node/pkg/services/control" @@ -58,11 +57,7 @@ func restoreShard(cmd *cobra.Command, _ []string) error { return err } - var resp *control.RestoreShardResponse - err = cli.ExecRaw(func(client *client.Client) error { - resp, err = control.RestoreShard(client, req) - return err - }) + resp, err := cli.RestoreShard(ctx, req) if err != nil { return fmt.Errorf("rpc error: %w", err) } diff --git a/cmd/neofs-cli/modules/control/shards_set_mode.go b/cmd/neofs-cli/modules/control/shards_set_mode.go index 9a7703f149..eb8a4ed4c7 100644 --- a/cmd/neofs-cli/modules/control/shards_set_mode.go +++ b/cmd/neofs-cli/modules/control/shards_set_mode.go @@ -7,7 +7,6 @@ import ( "strings" "github.com/mr-tron/base58" - rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key" "github.com/nspcc-dev/neofs-node/pkg/services/control" @@ -144,11 +143,7 @@ func setShardMode(cmd *cobra.Command, _ []string) error { return err } - var resp *control.SetShardModeResponse - err = cli.ExecRaw(func(client *rawclient.Client) error { - resp, err = control.SetShardMode(client, req) - return err - }) + resp, err := cli.SetShardMode(ctx, req) if err != nil { return fmt.Errorf("rpc error: %w", err) } diff --git a/cmd/neofs-cli/modules/control/synchronize_tree.go b/cmd/neofs-cli/modules/control/synchronize_tree.go index e7d94279ab..023ce49ad1 100644 --- a/cmd/neofs-cli/modules/control/synchronize_tree.go +++ b/cmd/neofs-cli/modules/control/synchronize_tree.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" - rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key" "github.com/nspcc-dev/neofs-node/pkg/services/control" @@ -72,11 +71,7 @@ func synchronizeTree(cmd *cobra.Command, _ []string) error { return err } - var resp *control.SynchronizeTreeResponse - err = cli.ExecRaw(func(client *rawclient.Client) error { - resp, err = control.SynchronizeTree(client, req) - return err - }) + resp, err := cli.SynchronizeTree(ctx, req) if err != nil { return fmt.Errorf("rpc error: %w", err) } diff --git a/cmd/neofs-cli/modules/control/util.go b/cmd/neofs-cli/modules/control/util.go index ec01353681..da6586b413 100644 --- a/cmd/neofs-cli/modules/control/util.go +++ b/cmd/neofs-cli/modules/control/util.go @@ -5,14 +5,21 @@ import ( "crypto/ecdsa" "errors" "fmt" + "net" + "net/url" + "strings" + "time" - internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" + "github.com/nspcc-dev/neofs-node/pkg/services/control" controlSvc "github.com/nspcc-dev/neofs-node/pkg/services/control/server" - "github.com/nspcc-dev/neofs-sdk-go/client" neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto" neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa" "github.com/spf13/cobra" + "github.com/spf13/viper" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" ) func initControlFlags(cmd *cobra.Command) { @@ -52,6 +59,91 @@ func verifyResponse(sigControl interface { return nil } -func getClient(ctx context.Context) (*client.Client, error) { - return internalclient.GetSDKClientByFlag(ctx, controlRPC) +func getClient(ctx context.Context) (control.ControlServiceClient, error) { + conn, err := connect(ctx) + if err != nil { + return nil, err + } + return control.NewControlServiceClient(conn), nil +} + +func connect(ctx context.Context) (*grpc.ClientConn, error) { + endpoint := viper.GetString(controlRPC) + if endpoint == "" { + return nil, fmt.Errorf("empty flag %q", controlRPC) + } + + addr, withTLS, err := parseURI(endpoint) + if err != nil { + return nil, fmt.Errorf("invalid %q flag: %w", controlRPC, err) + } + + if _, ok := ctx.Deadline(); !ok { // otherwise global deadline is specified already, don't go over it + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, 5*time.Second) + defer cancel() + } + + var creds credentials.TransportCredentials + if withTLS { + creds = credentials.NewTLS(nil) + } else { + creds = insecure.NewCredentials() + } + + // TODO: copy-pasted from SDK. Replace deprecated func with + // grpc.NewClient. This was not done because some options are no longer + // supported. Review carefully and make a proper transition. + //nolint:staticcheck + conn, err := grpc.DialContext(ctx, addr, + grpc.WithTransportCredentials(creds), + grpc.WithReturnConnectionError(), + grpc.FailOnNonTempDialError(true), + ) + if err != nil { + return nil, fmt.Errorf("failed to dial %q via gRPC: %w", endpoint, err) + } + return conn, nil +} + +// parses URI and returns a host and a flag indicating that TLS is enabled. +// Copy-paste from https://github.com/nspcc-dev/neofs-sdk-go/blob/0b9bb748ea16370c9b88090a902413324e86bcf1/internal/uriutil/uri.go#L13. +func parseURI(s string) (string, bool, error) { + uri, err := url.ParseRequestURI(s) + if err != nil { + if !strings.Contains(s, "/") { + _, _, err := net.SplitHostPort(s) + return s, false, err + } + return s, false, err + } + + const ( + grpcScheme = "grpc" + grpcTLSScheme = "grpcs" + ) + + // check if passed string was parsed correctly + // URIs that do not start with a slash after the scheme are interpreted as: + // `scheme:opaque` => if `opaque` is not empty, then it is supposed that URI + // is in `host:port` format + if uri.Host == "" { + uri.Host = uri.Scheme + uri.Scheme = grpcScheme // assume GRPC by default + if uri.Opaque != "" { + uri.Host = net.JoinHostPort(uri.Host, uri.Opaque) + } + } + + switch uri.Scheme { + case grpcTLSScheme, grpcScheme: + default: + return "", false, fmt.Errorf("unsupported scheme: %s", uri.Scheme) + } + + if uri.Port() == "" { + return "", false, errors.New("missing port in address") + } + + return uri.Host, uri.Scheme == grpcTLSScheme, nil } diff --git a/cmd/neofs-cli/modules/control/util_test.go b/cmd/neofs-cli/modules/control/util_test.go new file mode 100644 index 0000000000..918aca5503 --- /dev/null +++ b/cmd/neofs-cli/modules/control/util_test.go @@ -0,0 +1,49 @@ +package control + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestParseURI(t *testing.T) { + for _, tc := range []struct { + s string + host string + withTLS bool + }{ + // no scheme (TCP) + {s: "127.0.0.1:8080", host: "127.0.0.1:8080", withTLS: false}, + {s: "st1.storage.fs.neo.org:8080", host: "st1.storage.fs.neo.org:8080", withTLS: false}, + // with scheme and port + {s: "grpc://127.0.0.1:8080", host: "127.0.0.1:8080", withTLS: false}, + {s: "grpc://st1.storage.fs.neo.org:8080", host: "st1.storage.fs.neo.org:8080", withTLS: false}, + {s: "grpcs://127.0.0.1:8082", host: "127.0.0.1:8082", withTLS: true}, + {s: "grpcs://st1.storage.fs.neo.org:8082", host: "st1.storage.fs.neo.org:8082", withTLS: true}, + } { + host, withTLS, err := parseURI(tc.s) + require.NoError(t, err, tc.s) + require.Equal(t, tc.host, host, tc.s) + require.Equal(t, tc.withTLS, withTLS, tc.s) + } + + t.Run("invalid", func(t *testing.T) { + for _, tc := range []struct { + name, s, err string + }{ + {name: "unsupported scheme", s: "unknown://st1.storage.fs.neo.org:8082", err: "unsupported scheme: unknown"}, + {name: "garbage URI", s: "not a URI", err: "address not a URI: missing port in address"}, + {name: "port only", s: "8080", err: "address 8080: missing port in address"}, + {name: "ip only", s: "127.0.0.1", err: "address 127.0.0.1: missing port in address"}, + {name: "host only", s: "st1.storage.fs.neo.org", err: "address st1.storage.fs.neo.org: missing port in address"}, + {name: "multiaddr", s: "/ip4/127.0.0.1/tcp/8080", err: "missing port in address"}, + {name: "ip with scheme without port", s: "grpc://127.0.0.1", err: "missing port in address"}, + {name: "host with scheme without port", s: "grpc://st1.storage.fs.neo.org", err: "missing port in address"}, + } { + t.Run(tc.name, func(t *testing.T) { + _, _, err := parseURI(tc.s) + require.EqualError(t, err, tc.err) + }) + } + }) +} diff --git a/pkg/services/control/convert.go b/pkg/services/control/convert.go deleted file mode 100644 index a8de90124e..0000000000 --- a/pkg/services/control/convert.go +++ /dev/null @@ -1,257 +0,0 @@ -package control - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" - "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" -) - -type requestWrapper struct { - message.Message - m grpc.Message -} - -func (w *requestWrapper) ToGRPCMessage() grpc.Message { - return w.m -} - -type healthCheckResponseWrapper struct { - m *HealthCheckResponse -} - -func (w *healthCheckResponseWrapper) ToGRPCMessage() grpc.Message { - return w.m -} - -func (w *healthCheckResponseWrapper) FromGRPCMessage(m grpc.Message) error { - var ok bool - - w.m, ok = m.(*HealthCheckResponse) - if !ok { - return message.NewUnexpectedMessageType(m, w.m) - } - - return nil -} - -type setNetmapStatusResponseWrapper struct { - message.Message - m *SetNetmapStatusResponse -} - -func (w *setNetmapStatusResponseWrapper) ToGRPCMessage() grpc.Message { - return w.m -} - -func (w *setNetmapStatusResponseWrapper) FromGRPCMessage(m grpc.Message) error { - var ok bool - - w.m, ok = m.(*SetNetmapStatusResponse) - if !ok { - return message.NewUnexpectedMessageType(m, w.m) - } - - return nil -} - -type dropObjectsResponseWrapper struct { - message.Message - m *DropObjectsResponse -} - -func (w *dropObjectsResponseWrapper) ToGRPCMessage() grpc.Message { - return w.m -} - -func (w *dropObjectsResponseWrapper) FromGRPCMessage(m grpc.Message) error { - var ok bool - - w.m, ok = m.(*DropObjectsResponse) - if !ok { - return message.NewUnexpectedMessageType(m, w.m) - } - - return nil -} - -type listShardsResponseWrapper struct { - m *ListShardsResponse -} - -func (w *listShardsResponseWrapper) ToGRPCMessage() grpc.Message { - return w.m -} - -func (w *listShardsResponseWrapper) FromGRPCMessage(m grpc.Message) error { - var ok bool - - w.m, ok = m.(*ListShardsResponse) - if !ok { - return message.NewUnexpectedMessageType(m, w.m) - } - - return nil -} - -type listObjectsResponseWrapper struct { - m *ListObjectsResponse -} - -func (w *listObjectsResponseWrapper) ToGRPCMessage() grpc.Message { - return w.m -} - -func (w *listObjectsResponseWrapper) FromGRPCMessage(m grpc.Message) error { - var ok bool - - w.m, ok = m.(*ListObjectsResponse) - if !ok { - return message.NewUnexpectedMessageType(m, w.m) - } - - return nil -} - -type setShardModeResponseWrapper struct { - m *SetShardModeResponse -} - -func (w *setShardModeResponseWrapper) ToGRPCMessage() grpc.Message { - return w.m -} - -func (w *setShardModeResponseWrapper) FromGRPCMessage(m grpc.Message) error { - var ok bool - - w.m, ok = m.(*SetShardModeResponse) - if !ok { - return message.NewUnexpectedMessageType(m, w.m) - } - - return nil -} - -type dumpShardResponseWrapper struct { - *DumpShardResponse -} - -func (w *dumpShardResponseWrapper) ToGRPCMessage() grpc.Message { - return w.DumpShardResponse -} - -func (w *dumpShardResponseWrapper) FromGRPCMessage(m grpc.Message) error { - r, ok := m.(*DumpShardResponse) - if !ok { - return message.NewUnexpectedMessageType(m, (*DumpShardResponse)(nil)) - } - - w.DumpShardResponse = r - return nil -} - -type restoreShardResponseWrapper struct { - *RestoreShardResponse -} - -func (w *restoreShardResponseWrapper) ToGRPCMessage() grpc.Message { - return w.RestoreShardResponse -} - -func (w *restoreShardResponseWrapper) FromGRPCMessage(m grpc.Message) error { - r, ok := m.(*RestoreShardResponse) - if !ok { - return message.NewUnexpectedMessageType(m, (*RestoreShardResponse)(nil)) - } - - w.RestoreShardResponse = r - return nil -} - -type synchronizeTreeResponseWrapper struct { - *SynchronizeTreeResponse -} - -func (w *synchronizeTreeResponseWrapper) ToGRPCMessage() grpc.Message { - return w.SynchronizeTreeResponse -} - -func (w *synchronizeTreeResponseWrapper) FromGRPCMessage(m grpc.Message) error { - r, ok := m.(*SynchronizeTreeResponse) - if !ok { - return message.NewUnexpectedMessageType(m, (*SynchronizeTreeResponse)(nil)) - } - - w.SynchronizeTreeResponse = r - return nil -} - -type evacuateShardResponseWrapper struct { - *EvacuateShardResponse -} - -func (w *evacuateShardResponseWrapper) ToGRPCMessage() grpc.Message { - return w.EvacuateShardResponse -} - -func (w *evacuateShardResponseWrapper) FromGRPCMessage(m grpc.Message) error { - r, ok := m.(*EvacuateShardResponse) - if !ok { - return message.NewUnexpectedMessageType(m, (*EvacuateShardResponse)(nil)) - } - - w.EvacuateShardResponse = r - return nil -} - -type flushCacheResponseWrapper struct { - *FlushCacheResponse -} - -func (w *flushCacheResponseWrapper) ToGRPCMessage() grpc.Message { - return w.FlushCacheResponse -} - -func (w *flushCacheResponseWrapper) FromGRPCMessage(m grpc.Message) error { - r, ok := m.(*FlushCacheResponse) - if !ok { - return message.NewUnexpectedMessageType(m, (*FlushCacheResponse)(nil)) - } - - w.FlushCacheResponse = r - return nil -} - -type objectStatusResponseWrapper struct { - *ObjectStatusResponse -} - -func (w *objectStatusResponseWrapper) ToGRPCMessage() grpc.Message { - return w.ObjectStatusResponse -} - -func (w *objectStatusResponseWrapper) FromGRPCMessage(m grpc.Message) error { - r, ok := m.(*ObjectStatusResponse) - if !ok { - return message.NewUnexpectedMessageType(m, (*ObjectStatusResponse)(nil)) - } - - w.ObjectStatusResponse = r - return nil -} - -type reviveObjectResponseWrapper struct { - *ReviveObjectResponse -} - -func (w *reviveObjectResponseWrapper) ToGRPCMessage() grpc.Message { - return w.ReviveObjectResponse -} - -func (w *reviveObjectResponseWrapper) FromGRPCMessage(m grpc.Message) error { - r, ok := m.(*ReviveObjectResponse) - if !ok { - return message.NewUnexpectedMessageType(m, (*ReviveObjectResponse)(nil)) - } - - w.ReviveObjectResponse = r - return nil -} diff --git a/pkg/services/control/ir/convert.go b/pkg/services/control/ir/convert.go deleted file mode 100644 index 24235e520e..0000000000 --- a/pkg/services/control/ir/convert.go +++ /dev/null @@ -1,34 +0,0 @@ -package control - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/rpc/grpc" - "github.com/nspcc-dev/neofs-api-go/v2/rpc/message" -) - -type requestWrapper struct { - message.Message - m grpc.Message -} - -func (w *requestWrapper) ToGRPCMessage() grpc.Message { - return w.m -} - -type healthCheckResponseWrapper struct { - m *HealthCheckResponse -} - -func (w *healthCheckResponseWrapper) ToGRPCMessage() grpc.Message { - return w.m -} - -func (w *healthCheckResponseWrapper) FromGRPCMessage(m grpc.Message) error { - var ok bool - - w.m, ok = m.(*HealthCheckResponse) - if !ok { - return message.NewUnexpectedMessageType(m, w.m) - } - - return nil -} diff --git a/pkg/services/control/ir/rpc.go b/pkg/services/control/ir/rpc.go deleted file mode 100644 index e7b7c23204..0000000000 --- a/pkg/services/control/ir/rpc.go +++ /dev/null @@ -1,34 +0,0 @@ -package control - -import ( - "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" - "github.com/nspcc-dev/neofs-api-go/v2/rpc/common" -) - -const serviceName = "ircontrol.ControlService" - -const ( - rpcHealthCheck = "HealthCheck" -) - -// HealthCheck executes ControlService.HealthCheck RPC. -func HealthCheck( - cli *client.Client, - req *HealthCheckRequest, - opts ...client.CallOption, -) (*HealthCheckResponse, error) { - wResp := &healthCheckResponseWrapper{ - m: new(HealthCheckResponse), - } - - wReq := &requestWrapper{ - m: req, - } - - err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceName, rpcHealthCheck), wReq, wResp, opts...) - if err != nil { - return nil, err - } - - return wResp.m, nil -} diff --git a/pkg/services/control/rpc.go b/pkg/services/control/rpc.go deleted file mode 100644 index 9a94f43efe..0000000000 --- a/pkg/services/control/rpc.go +++ /dev/null @@ -1,270 +0,0 @@ -package control - -import ( - "errors" - "io" - - "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" - "github.com/nspcc-dev/neofs-api-go/v2/rpc/common" -) - -const serviceName = "control.ControlService" - -const ( - rpcHealthCheck = "HealthCheck" - rpcSetNetmapStatus = "SetNetmapStatus" - rpcDropObjects = "DropObjects" - rpcListShards = "ListShards" - rpcListObjects = "ListObjects" - rpcSetShardMode = "SetShardMode" - rpcDumpShard = "DumpShard" - rpcRestoreShard = "RestoreShard" - rpcSynchronizeTree = "SynchronizeTree" - rpcEvacuateShard = "EvacuateShard" - rpcFlushCache = "FlushCache" - rpcObjectStatus = "ObjectStatus" - rpcReviveObject = "ReviveObject" -) - -// HealthCheck executes ControlService.HealthCheck RPC. -func HealthCheck( - cli *client.Client, - req *HealthCheckRequest, - opts ...client.CallOption, -) (*HealthCheckResponse, error) { - wResp := &healthCheckResponseWrapper{ - m: new(HealthCheckResponse), - } - - wReq := &requestWrapper{ - m: req, - } - - err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceName, rpcHealthCheck), wReq, wResp, opts...) - if err != nil { - return nil, err - } - - return wResp.m, nil -} - -// SetNetmapStatus executes ControlService.SetNetmapStatus RPC. -func SetNetmapStatus( - cli *client.Client, - req *SetNetmapStatusRequest, - opts ...client.CallOption, -) (*SetNetmapStatusResponse, error) { - wResp := &setNetmapStatusResponseWrapper{ - m: new(SetNetmapStatusResponse), - } - - wReq := &requestWrapper{ - m: req, - } - - err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceName, rpcSetNetmapStatus), wReq, wResp, opts...) - if err != nil { - return nil, err - } - - return wResp.m, nil -} - -// DropObjects executes ControlService.DropObjects RPC. -func DropObjects( - cli *client.Client, - req *DropObjectsRequest, - opts ...client.CallOption, -) (*DropObjectsResponse, error) { - wResp := &dropObjectsResponseWrapper{ - m: new(DropObjectsResponse), - } - - wReq := &requestWrapper{ - m: req, - } - err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceName, rpcDropObjects), wReq, wResp, opts...) - if err != nil { - return nil, err - } - - return wResp.m, nil -} - -// ListShards executes ControlService.ListShards RPC. -func ListShards( - cli *client.Client, - req *ListShardsRequest, - opts ...client.CallOption, -) (*ListShardsResponse, error) { - wResp := &listShardsResponseWrapper{ - m: new(ListShardsResponse), - } - - wReq := &requestWrapper{ - m: req, - } - err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceName, rpcListShards), wReq, wResp, opts...) - if err != nil { - return nil, err - } - - return wResp.m, nil -} - -// ListObjects executes ControlService.ListObjects RPC. -func ListObjects( - cli *client.Client, - req *ListObjectsRequest, - handleResp func(*ListObjectsResponse) error, - opts ...client.CallOption, -) error { - wReq := &requestWrapper{ - m: req, - } - - stream, err := client.OpenServerStream(cli, common.CallMethodInfoServerStream(serviceName, rpcListObjects), wReq, opts...) - if err != nil { - return err - } - - for { - wResp := &listObjectsResponseWrapper{ - m: new(ListObjectsResponse), - } - err = stream.ReadMessage(wResp) - if errors.Is(err, io.EOF) { - break - } - if err != nil { - return err - } - - err = handleResp(wResp.m) - if err != nil { - return err - } - } - - return nil -} - -// SetShardMode executes ControlService.SetShardMode RPC. -func SetShardMode( - cli *client.Client, - req *SetShardModeRequest, - opts ...client.CallOption, -) (*SetShardModeResponse, error) { - wResp := &setShardModeResponseWrapper{ - m: new(SetShardModeResponse), - } - - wReq := &requestWrapper{ - m: req, - } - err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceName, rpcSetShardMode), wReq, wResp, opts...) - if err != nil { - return nil, err - } - - return wResp.m, nil -} - -// DumpShard executes ControlService.DumpShard RPC. -func DumpShard(cli *client.Client, req *DumpShardRequest, opts ...client.CallOption) (*DumpShardResponse, error) { - wResp := &dumpShardResponseWrapper{new(DumpShardResponse)} - wReq := &requestWrapper{m: req} - - err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceName, rpcDumpShard), wReq, wResp, opts...) - if err != nil { - return nil, err - } - - return wResp.DumpShardResponse, nil -} - -// RestoreShard executes ControlService.DumpShard RPC. -func RestoreShard(cli *client.Client, req *RestoreShardRequest, opts ...client.CallOption) (*RestoreShardResponse, error) { - wResp := &restoreShardResponseWrapper{new(RestoreShardResponse)} - wReq := &requestWrapper{m: req} - - err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceName, rpcRestoreShard), wReq, wResp, opts...) - if err != nil { - return nil, err - } - - return wResp.RestoreShardResponse, nil -} - -// SynchronizeTree executes ControlService.SynchronizeTree RPC. -func SynchronizeTree(cli *client.Client, req *SynchronizeTreeRequest, opts ...client.CallOption) (*SynchronizeTreeResponse, error) { - wResp := &synchronizeTreeResponseWrapper{new(SynchronizeTreeResponse)} - wReq := &requestWrapper{m: req} - - err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceName, rpcSynchronizeTree), wReq, wResp, opts...) - if err != nil { - return nil, err - } - - return wResp.SynchronizeTreeResponse, nil -} - -// EvacuateShard executes ControlService.EvacuateShard RPC. -func EvacuateShard(cli *client.Client, req *EvacuateShardRequest, opts ...client.CallOption) (*EvacuateShardResponse, error) { - wResp := &evacuateShardResponseWrapper{new(EvacuateShardResponse)} - wReq := &requestWrapper{m: req} - - err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceName, rpcEvacuateShard), wReq, wResp, opts...) - if err != nil { - return nil, err - } - - return wResp.EvacuateShardResponse, nil -} - -// FlushCache executes ControlService.FlushCache RPC. -func FlushCache(cli *client.Client, req *FlushCacheRequest, opts ...client.CallOption) (*FlushCacheResponse, error) { - wResp := &flushCacheResponseWrapper{new(FlushCacheResponse)} - wReq := &requestWrapper{m: req} - - err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceName, rpcFlushCache), wReq, wResp, opts...) - if err != nil { - return nil, err - } - - return wResp.FlushCacheResponse, nil -} - -// ObjectStatus executes ControlService.ObjectStatus RPC. -func ObjectStatus(cli *client.Client, req *ObjectStatusRequest, opts ...client.CallOption) (*ObjectStatusResponse, error) { - wResp := &objectStatusResponseWrapper{new(ObjectStatusResponse)} - wReq := &requestWrapper{m: req} - - err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceName, rpcObjectStatus), wReq, wResp, opts...) - if err != nil { - return nil, err - } - - return wResp.ObjectStatusResponse, nil -} - -// ReviveObject executes ControlService.ReviveObject RPC. -func ReviveObject( - cli *client.Client, - req *ReviveObjectRequest, - opts ...client.CallOption, -) (*ReviveObjectResponse, error) { - wResp := &reviveObjectResponseWrapper{ - new(ReviveObjectResponse), - } - - wReq := &requestWrapper{ - m: req, - } - err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceName, rpcReviveObject), wReq, wResp, opts...) - if err != nil { - return nil, err - } - - return wResp.ReviveObjectResponse, nil -}