[#263] v2: Support new rpc library

Implement `message.Message` interface on all structures and use new methods
for conversion instead of functions. make `Unmarshal` and JSON methods to
use encoding functions from `message` library. Remove all per-service
clients and implement `rpc` library of the functions which execute NeoFS API
RPC through new RPC client. Remove no longer used gRPC per-service clients.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2021-03-12 15:57:23 +03:00 committed by Alex Vanin
parent 30c6ca0714
commit 1031f3122e
102 changed files with 7554 additions and 12298 deletions

View file

@ -19,6 +19,18 @@ type Decimal struct {
prec uint32 prec uint32
} }
type BalanceRequest struct {
body *BalanceRequestBody
session.RequestHeaders
}
type BalanceResponse struct {
body *BalanceResponseBody
session.ResponseHeaders
}
func (b *BalanceRequestBody) GetOwnerID() *refs.OwnerID { func (b *BalanceRequestBody) GetOwnerID() *refs.OwnerID {
if b != nil { if b != nil {
return b.ownerID return b.ownerID
@ -47,34 +59,6 @@ func (b *BalanceRequest) SetBody(v *BalanceRequestBody) {
} }
} }
func (b *BalanceRequest) GetMetaHeader() *session.RequestMetaHeader {
if b != nil {
return b.metaHeader
}
return nil
}
func (b *BalanceRequest) SetMetaHeader(v *session.RequestMetaHeader) {
if b != nil {
b.metaHeader = v
}
}
func (b *BalanceRequest) GetVerificationHeader() *session.RequestVerificationHeader {
if b != nil {
return b.verifyHeader
}
return nil
}
func (b *BalanceRequest) SetVerificationHeader(v *session.RequestVerificationHeader) {
if b != nil {
b.verifyHeader = v
}
}
func (d *Decimal) GetValue() int64 { func (d *Decimal) GetValue() int64 {
if d != nil { if d != nil {
return d.val return d.val
@ -130,31 +114,3 @@ func (br *BalanceResponse) SetBody(v *BalanceResponseBody) {
br.body = v br.body = v
} }
} }
func (br *BalanceResponse) GetMetaHeader() *session.ResponseMetaHeader {
if br != nil {
return br.metaHeader
}
return nil
}
func (br *BalanceResponse) SetMetaHeader(v *session.ResponseMetaHeader) {
if br != nil {
br.metaHeader = v
}
}
func (br *BalanceResponse) GetVerificationHeader() *session.ResponseVerificationHeader {
if br != nil {
return br.verifyHeader
}
return nil
}
func (br *BalanceResponse) SetVerificationHeader(v *session.ResponseVerificationHeader) {
if br != nil {
br.verifyHeader = v
}
}

View file

@ -1,156 +0,0 @@
package accounting
import (
"context"
accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/client"
"github.com/pkg/errors"
"google.golang.org/grpc"
)
// Client represents universal accounting
// transport client.
type Client struct {
client *getBalanceClient
}
// Option represents Client option.
type Option func(*cfg)
type cfg struct {
proto client.Protocol
globalOpts []client.Option
gRPC cfgGRPC
}
type cfgGRPC struct {
serviceClient accounting.AccountingServiceClient
grpcCallOpts []grpc.CallOption
callOpts []accounting.Option
client *accounting.Client
}
type getBalanceClient struct {
requestConverter func(*BalanceRequest) interface{}
caller func(context.Context, interface{}) (interface{}, error)
responseConverter func(interface{}) *BalanceResponse
}
// Balance sends BalanceRequest over the network and returns BalanceResponse.
//
// It returns any error encountered during the call.
func (c *Client) Balance(ctx context.Context, req *BalanceRequest) (*BalanceResponse, error) {
resp, err := c.client.caller(ctx, c.client.requestConverter(req))
if err != nil {
return nil, errors.Wrap(err, "could not send balance request")
}
return c.client.responseConverter(resp), nil
}
func defaultCfg() *cfg {
return &cfg{
proto: client.ProtoGRPC,
}
}
func NewClient(opts ...Option) (*Client, error) {
cfg := defaultCfg()
for i := range opts {
opts[i](cfg)
}
var err error
switch cfg.proto {
case client.ProtoGRPC:
var c *accounting.Client
if c, err = newGRPCClient(cfg); err != nil {
break
}
return &Client{
client: &getBalanceClient{
requestConverter: func(req *BalanceRequest) interface{} {
return BalanceRequestToGRPCMessage(req)
},
caller: func(ctx context.Context, req interface{}) (interface{}, error) {
return c.Balance(ctx, req.(*accounting.BalanceRequest))
},
responseConverter: func(resp interface{}) *BalanceResponse {
return BalanceResponseFromGRPCMessage(resp.(*accounting.BalanceResponse))
},
},
}, nil
default:
err = client.ErrProtoUnsupported
}
return nil, errors.Wrapf(err, "could not create %s Accounting client", cfg.proto)
}
func newGRPCClient(cfg *cfg) (*accounting.Client, error) {
var err error
if cfg.gRPC.client == nil {
if cfg.gRPC.serviceClient == nil {
conn, err := client.NewGRPCClientConn(cfg.globalOpts...)
if err != nil {
return nil, errors.Wrap(err, "could not open gRPC client connection")
}
cfg.gRPC.serviceClient = accounting.NewAccountingServiceClient(conn)
}
cfg.gRPC.client, err = accounting.NewClient(
cfg.gRPC.serviceClient,
append(
cfg.gRPC.callOpts,
accounting.WithCallOptions(cfg.gRPC.grpcCallOpts),
)...,
)
}
return cfg.gRPC.client, err
}
func WithGlobalOpts(v ...client.Option) Option {
return func(c *cfg) {
if len(v) > 0 {
c.globalOpts = v
}
}
}
func WithGRPCServiceClient(v accounting.AccountingServiceClient) Option {
return func(c *cfg) {
c.gRPC.serviceClient = v
}
}
func WithGRPCCallOpts(v []grpc.CallOption) Option {
return func(c *cfg) {
c.gRPC.grpcCallOpts = v
}
}
func WithGRPCClientOpts(v []accounting.Option) Option {
return func(c *cfg) {
c.gRPC.callOpts = v
}
}
func WithGRPCClient(v *accounting.Client) Option {
return func(c *cfg) {
c.gRPC.client = v
}
}

View file

@ -1,153 +1,178 @@
package accounting package accounting
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/grpc"
"github.com/nspcc-dev/neofs-api-go/rpc/message"
accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc" accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-api-go/v2/session" refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
) )
func BalanceRequestBodyToGRPCMessage(b *BalanceRequestBody) *accounting.BalanceRequest_Body { func (b *BalanceRequestBody) ToGRPCMessage() grpc.Message {
if b == nil { var m *accounting.BalanceRequest_Body
return nil
if b != nil {
m = new(accounting.BalanceRequest_Body)
m.SetOwnerId(b.ownerID.ToGRPCMessage().(*refsGRPC.OwnerID))
} }
m := new(accounting.BalanceRequest_Body)
m.SetOwnerId(
refs.OwnerIDToGRPCMessage(b.GetOwnerID()),
)
return m return m
} }
func BalanceRequestBodyFromGRPCMessage(m *accounting.BalanceRequest_Body) *BalanceRequestBody { func (b *BalanceRequestBody) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*accounting.BalanceRequest_Body)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
b := new(BalanceRequestBody) var err error
b.SetOwnerID( ownerID := v.GetOwnerId()
refs.OwnerIDFromGRPCMessage(m.GetOwnerId()), if ownerID == nil {
) b.ownerID = nil
} else {
if b.ownerID == nil {
b.ownerID = new(refs.OwnerID)
}
return b err = b.ownerID.FromGRPCMessage(ownerID)
}
return err
} }
func BalanceRequestToGRPCMessage(b *BalanceRequest) *accounting.BalanceRequest { func (b *BalanceRequest) ToGRPCMessage() grpc.Message {
if b == nil { var m *accounting.BalanceRequest
return nil
if b != nil {
m = new(accounting.BalanceRequest)
m.SetBody(b.body.ToGRPCMessage().(*accounting.BalanceRequest_Body))
b.RequestHeaders.ToMessage(m)
} }
m := new(accounting.BalanceRequest)
m.SetBody(
BalanceRequestBodyToGRPCMessage(b.GetBody()),
)
session.RequestHeadersToGRPC(b, m)
return m return m
} }
func BalanceRequestFromGRPCMessage(m *accounting.BalanceRequest) *BalanceRequest { func (b *BalanceRequest) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*accounting.BalanceRequest)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
b := new(BalanceRequest) var err error
b.SetBody( body := v.GetBody()
BalanceRequestBodyFromGRPCMessage(m.GetBody()), if body == nil {
) b.body = nil
} else {
if b.body == nil {
b.body = new(BalanceRequestBody)
}
session.RequestHeadersFromGRPC(m, b) err = b.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return b return b.RequestHeaders.FromMessage(v)
} }
func DecimalToGRPCMessage(d *Decimal) *accounting.Decimal { func (d *Decimal) ToGRPCMessage() grpc.Message {
if d == nil { var m *accounting.Decimal
return nil
if d != nil {
m = new(accounting.Decimal)
m.SetValue(d.val)
m.SetPrecision(d.prec)
} }
m := new(accounting.Decimal)
m.SetValue(d.GetValue())
m.SetPrecision(d.GetPrecision())
return m return m
} }
func DecimalFromGRPCMessage(m *accounting.Decimal) *Decimal { func (d *Decimal) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*accounting.Decimal)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
d := new(Decimal) d.val = v.GetValue()
d.prec = v.GetPrecision()
d.SetValue(m.GetValue()) return nil
d.SetPrecision(m.GetPrecision())
return d
} }
func BalanceResponseBodyToGRPCMessage(br *BalanceResponseBody) *accounting.BalanceResponse_Body { func (br *BalanceResponseBody) ToGRPCMessage() grpc.Message {
if br == nil { var m *accounting.BalanceResponse_Body
return nil
if br != nil {
m = new(accounting.BalanceResponse_Body)
m.SetBalance(br.bal.ToGRPCMessage().(*accounting.Decimal))
} }
m := new(accounting.BalanceResponse_Body)
m.SetBalance(
DecimalToGRPCMessage(br.GetBalance()),
)
return m return m
} }
func BalanceResponseBodyFromGRPCMessage(m *accounting.BalanceResponse_Body) *BalanceResponseBody { func (br *BalanceResponseBody) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*accounting.BalanceResponse_Body)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
br := new(BalanceResponseBody) var err error
br.SetBalance( bal := v.GetBalance()
DecimalFromGRPCMessage(m.GetBalance()), if bal == nil {
) br.bal = nil
} else {
if br.bal == nil {
br.bal = new(Decimal)
}
return br err = br.bal.FromGRPCMessage(bal)
}
return err
} }
func BalanceResponseToGRPCMessage(br *BalanceResponse) *accounting.BalanceResponse { func (br *BalanceResponse) ToGRPCMessage() grpc.Message {
if br == nil { var m *accounting.BalanceResponse
return nil
if br != nil {
m = new(accounting.BalanceResponse)
m.SetBody(br.body.ToGRPCMessage().(*accounting.BalanceResponse_Body))
br.ResponseHeaders.ToMessage(m)
} }
m := new(accounting.BalanceResponse)
m.SetBody(
BalanceResponseBodyToGRPCMessage(br.GetBody()),
)
session.ResponseHeadersToGRPC(br, m)
return m return m
} }
func BalanceResponseFromGRPCMessage(m *accounting.BalanceResponse) *BalanceResponse { func (br *BalanceResponse) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*accounting.BalanceResponse)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
br := new(BalanceResponse) var err error
br.SetBody( body := v.GetBody()
BalanceResponseBodyFromGRPCMessage(m.GetBody()), if body == nil {
) br.body = nil
} else {
if br.body == nil {
br.body = new(BalanceResponseBody)
}
session.ResponseHeadersFromGRPC(m, br) err = br.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return br return br.ResponseHeaders.FromMessage(v)
} }

View file

@ -1,62 +0,0 @@
package accounting
import (
"context"
"github.com/pkg/errors"
"google.golang.org/grpc"
)
// Client wraps AccountingServiceClient
// with pre-defined configurations.
type Client struct {
*cfg
client AccountingServiceClient
}
// Option represents Client option.
type Option func(*cfg)
type cfg struct {
callOpts []grpc.CallOption
}
// ErrNilAccountingServiceClient is returned by functions that expect
// a non-nil AccountingServiceClient, but received nil.
var ErrNilAccountingServiceClient = errors.New("accounting gRPC client is nil")
func defaultCfg() *cfg {
return new(cfg)
}
// NewClient creates, initializes and returns a new Client instance.
//
// Options are applied one by one in order.
func NewClient(c AccountingServiceClient, opts ...Option) (*Client, error) {
if c == nil {
return nil, ErrNilAccountingServiceClient
}
cfg := defaultCfg()
for i := range opts {
opts[i](cfg)
}
return &Client{
cfg: cfg,
client: c,
}, nil
}
func (c *Client) Balance(ctx context.Context, req *BalanceRequest) (*BalanceResponse, error) {
return c.client.Balance(ctx, req, c.callOpts...)
}
// WithCallOptions returns Option that configures
// Client to attach call options to each rpc call.
func WithCallOptions(opts []grpc.CallOption) Option {
return func(c *cfg) {
c.callOpts = opts
}
}

View file

@ -1,26 +1,14 @@
package accounting package accounting
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc" accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc"
"google.golang.org/protobuf/encoding/protojson"
) )
func (d *Decimal) MarshalJSON() ([]byte, error) { func (d *Decimal) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(d)
EmitUnpopulated: true,
}.Marshal(
DecimalToGRPCMessage(d),
)
} }
func (d *Decimal) UnmarshalJSON(data []byte) error { func (d *Decimal) UnmarshalJSON(data []byte) error {
msg := new(accounting.Decimal) return message.UnmarshalJSON(d, data, new(accounting.Decimal))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*d = *DecimalFromGRPCMessage(msg)
return nil
} }

View file

@ -1,20 +0,0 @@
package accounting_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/accounting"
"github.com/stretchr/testify/require"
)
func TestDecimalJSON(t *testing.T) {
i := generateDecimal(10)
data, err := i.MarshalJSON()
require.NoError(t, err)
i2 := new(accounting.Decimal)
require.NoError(t, i2.UnmarshalJSON(data))
require.Equal(t, i, i2)
}

View file

@ -1,9 +1,9 @@
package accounting package accounting
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
protoutil "github.com/nspcc-dev/neofs-api-go/util/proto" protoutil "github.com/nspcc-dev/neofs-api-go/util/proto"
accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc" accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc"
"google.golang.org/protobuf/proto"
) )
const ( const (
@ -56,14 +56,7 @@ func (d *Decimal) StableSize() (size int) {
} }
func (d *Decimal) Unmarshal(data []byte) error { func (d *Decimal) Unmarshal(data []byte) error {
m := new(accounting.Decimal) return message.Unmarshal(d, data, new(accounting.Decimal))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*d = *DecimalFromGRPCMessage(m)
return nil
} }
func (b *BalanceRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (b *BalanceRequestBody) StableMarshal(buf []byte) ([]byte, error) {
@ -93,6 +86,10 @@ func (b *BalanceRequestBody) StableSize() (size int) {
return size return size
} }
func (b *BalanceRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(b, data, new(accounting.BalanceRequest_Body))
}
func (br *BalanceResponseBody) StableMarshal(buf []byte) ([]byte, error) { func (br *BalanceResponseBody) StableMarshal(buf []byte) ([]byte, error) {
if br == nil { if br == nil {
return []byte{}, nil return []byte{}, nil
@ -119,3 +116,7 @@ func (br *BalanceResponseBody) StableSize() (size int) {
return size return size
} }
func (br *BalanceResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(br, data, new(accounting.BalanceResponse_Body))
}

View file

@ -1,81 +0,0 @@
package accounting_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/accounting"
grpc "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/stretchr/testify/require"
goproto "google.golang.org/protobuf/proto"
)
func TestBalanceRequestBody_StableMarshal(t *testing.T) {
requestBodyFrom := generateBalanceRequestBody("Owner ID")
transport := new(grpc.BalanceRequest_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := requestBodyFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
requestBodyTo := accounting.BalanceRequestBodyFromGRPCMessage(transport)
require.Equal(t, requestBodyFrom, requestBodyTo)
})
}
func TestBalanceResponseBody_StableMarshal(t *testing.T) {
responseBodyFrom := generateBalanceResponseBody(444)
transport := new(grpc.BalanceResponse_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := responseBodyFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
responseBodyTo := accounting.BalanceResponseBodyFromGRPCMessage(transport)
require.Equal(t, responseBodyFrom, responseBodyTo)
})
}
func generateDecimal(val int64) *accounting.Decimal {
decimal := new(accounting.Decimal)
decimal.SetValue(val)
decimal.SetPrecision(1000)
return decimal
}
func generateBalanceRequestBody(id string) *accounting.BalanceRequestBody {
owner := new(refs.OwnerID)
owner.SetValue([]byte(id))
request := new(accounting.BalanceRequestBody)
request.SetOwnerID(owner)
return request
}
func generateBalanceResponseBody(val int64) *accounting.BalanceResponseBody {
response := new(accounting.BalanceResponseBody)
response.SetBalance(generateDecimal(val))
return response
}
func TestDecimalMarshal(t *testing.T) {
d := generateDecimal(3)
data, err := d.StableMarshal(nil)
require.NoError(t, err)
d2 := new(accounting.Decimal)
require.NoError(t, d2.Unmarshal(data))
require.Equal(t, d, d2)
}

View file

@ -0,0 +1,19 @@
package accounting_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/rpc/message"
messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test"
accountingtest "github.com/nspcc-dev/neofs-api-go/v2/accounting/test"
)
func TestMessage(t *testing.T) {
messagetest.TestRPCMessage(t,
func(empty bool) message.Message { return accountingtest.GenerateDecimal(empty) },
func(empty bool) message.Message { return accountingtest.GenerateBalanceRequestBody(empty) },
func(empty bool) message.Message { return accountingtest.GenerateBalanceRequest(empty) },
func(empty bool) message.Message { return accountingtest.GenerateBalanceResponseBody(empty) },
func(empty bool) message.Message { return accountingtest.GenerateBalanceResponse(empty) },
)
}

View file

@ -1,27 +0,0 @@
package accounting
import (
"context"
"github.com/nspcc-dev/neofs-api-go/v2/session"
)
type Service interface {
Balance(context.Context, *BalanceRequest) (*BalanceResponse, error)
}
type BalanceRequest struct {
body *BalanceRequestBody
metaHeader *session.RequestMetaHeader
verifyHeader *session.RequestVerificationHeader
}
type BalanceResponse struct {
body *BalanceResponseBody
metaHeader *session.ResponseMetaHeader
verifyHeader *session.ResponseVerificationHeader
}

View file

@ -1,163 +0,0 @@
package main
import (
"context"
"crypto/ecdsa"
"errors"
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/accounting"
accountingGRPC "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-api-go/v2/session"
"github.com/nspcc-dev/neofs-api-go/v2/signature"
"github.com/nspcc-dev/neofs-crypto/test"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
)
type testGRPCClient struct {
server *testGRPCServer
}
type testGRPCServer struct {
key *ecdsa.PrivateKey
resp *accounting.BalanceResponse
err error
}
func (s *testGRPCClient) Balance(ctx context.Context, in *accountingGRPC.BalanceRequest, opts ...grpc.CallOption) (*accountingGRPC.BalanceResponse, error) {
return s.server.Balance(ctx, in)
}
func (s *testGRPCServer) Balance(_ context.Context, req *accountingGRPC.BalanceRequest) (*accountingGRPC.BalanceResponse, error) {
if s.err != nil {
return nil, s.err
}
// verify request structure
if err := signature.VerifyServiceMessage(
accounting.BalanceRequestFromGRPCMessage(req),
); err != nil {
return nil, err
}
// sign response structure
if err := signature.SignServiceMessage(s.key, s.resp); err != nil {
return nil, err
}
return accounting.BalanceResponseToGRPCMessage(s.resp), nil
}
func testRequest() *accounting.BalanceRequest {
ownerID := new(refs.OwnerID)
ownerID.SetValue([]byte{1, 2, 3})
body := new(accounting.BalanceRequestBody)
body.SetOwnerID(ownerID)
meta := new(session.RequestMetaHeader)
meta.SetTTL(1)
req := new(accounting.BalanceRequest)
req.SetBody(body)
req.SetMetaHeader(meta)
return req
}
func testResponse() *accounting.BalanceResponse {
dec := new(accounting.Decimal)
dec.SetValue(10)
body := new(accounting.BalanceResponseBody)
body.SetBalance(dec)
meta := new(session.ResponseMetaHeader)
meta.SetTTL(1)
resp := new(accounting.BalanceResponse)
resp.SetBody(body)
resp.SetMetaHeader(meta)
return resp
}
func TestGRPCClient(t *testing.T) {
ctx := context.TODO()
cliKey := test.DecodeKey(0)
srvKey := test.DecodeKey(1)
t.Run("gRPC server error", func(t *testing.T) {
srvErr := errors.New("test server error")
srv := &testGRPCServer{
err: srvErr,
}
cli := &testGRPCClient{
server: srv,
}
c, err := accounting.NewClient(accounting.WithGRPCServiceClient(cli))
require.NoError(t, err)
resp, err := c.Balance(ctx, new(accounting.BalanceRequest))
require.True(t, errors.Is(err, srvErr))
require.Nil(t, resp)
})
t.Run("invalid request structure", func(t *testing.T) {
req := testRequest()
require.Error(t, signature.VerifyServiceMessage(req))
c, err := accounting.NewClient(
accounting.WithGRPCServiceClient(
&testGRPCClient{
server: new(testGRPCServer),
},
),
)
require.NoError(t, err)
resp, err := c.Balance(ctx, req)
require.Error(t, err)
require.Nil(t, resp)
})
t.Run("correct response", func(t *testing.T) {
req := testRequest()
require.NoError(t, signature.SignServiceMessage(cliKey, req))
resp := testResponse()
{ // w/o this require.Equal fails due to nil and []T{} difference
meta := new(session.ResponseMetaHeader)
meta.SetXHeaders([]*session.XHeader{})
resp.SetMetaHeader(meta)
}
c, err := accounting.NewClient(
accounting.WithGRPCServiceClient(
&testGRPCClient{
server: &testGRPCServer{
key: srvKey,
resp: resp,
},
},
),
)
require.NoError(t, err)
r, err := c.Balance(ctx, req)
require.NoError(t, err)
require.NoError(t, signature.VerifyServiceMessage(r))
require.Equal(t, resp.GetBody(), r.GetBody())
require.Equal(t, resp.GetMetaHeader(), r.GetMetaHeader())
})
}

View file

@ -0,0 +1,54 @@
package accountingtest
import (
"github.com/nspcc-dev/neofs-api-go/v2/accounting"
accountingtest "github.com/nspcc-dev/neofs-api-go/v2/refs/test"
sessiontest "github.com/nspcc-dev/neofs-api-go/v2/session/test"
)
func GenerateBalanceRequest(empty bool) *accounting.BalanceRequest {
m := new(accounting.BalanceRequest)
m.SetBody(GenerateBalanceRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateBalanceRequestBody(empty bool) *accounting.BalanceRequestBody {
m := new(accounting.BalanceRequestBody)
m.SetOwnerID(accountingtest.GenerateOwnerID(empty))
return m
}
func GenerateBalanceResponse(empty bool) *accounting.BalanceResponse {
m := new(accounting.BalanceResponse)
m.SetBody(GenerateBalanceResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateBalanceResponseBody(empty bool) *accounting.BalanceResponseBody {
m := new(accounting.BalanceResponseBody)
m.SetBalance(GenerateDecimal(empty))
return m
}
func GenerateDecimal(empty bool) *accounting.Decimal {
m := new(accounting.Decimal)
if !empty {
m.SetValue(1)
m.SetPrecision(2)
}
return m
}

View file

@ -1,8 +1,11 @@
package acl package acl
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/grpc"
"github.com/nspcc-dev/neofs-api-go/rpc/message"
acl "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc" acl "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-api-go/v2/refs"
refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
) )
// RoleToGRPCField converts unified role enum into grpc enum. // RoleToGRPCField converts unified role enum into grpc enum.
@ -149,316 +152,395 @@ func MatchTypeFromGRPCField(t acl.MatchType) MatchType {
} }
} }
// HeaderFilterToGRPCMessage converts unified header filter struct into grpc struct. func (f *HeaderFilter) ToGRPCMessage() grpc.Message {
func HeaderFilterToGRPCMessage(f *HeaderFilter) *acl.EACLRecord_Filter { var m *acl.EACLRecord_Filter
if f == nil {
return nil if f != nil {
m = new(acl.EACLRecord_Filter)
m.SetKey(f.key)
m.SetValue(f.value)
m.SetHeader(HeaderTypeToGRPCField(f.hdrType))
m.SetMatchType(MatchTypeToGRPCField(f.matchType))
} }
m := new(acl.EACLRecord_Filter)
m.SetHeader(
HeaderTypeToGRPCField(f.GetHeaderType()),
)
m.SetMatchType(
MatchTypeToGRPCField(f.GetMatchType()),
)
m.SetKey(f.GetKey())
m.SetValue(f.GetValue())
return m return m
} }
// HeaderFilterFromGRPCMessage converts grpc struct into unified header filter struct. func (f *HeaderFilter) FromGRPCMessage(m grpc.Message) error {
func HeaderFilterFromGRPCMessage(m *acl.EACLRecord_Filter) *HeaderFilter { v, ok := m.(*acl.EACLRecord_Filter)
if m == nil { if !ok {
return nil return message.NewUnexpectedMessageType(m, v)
} }
f := new(HeaderFilter) f.key = v.GetKey()
f.value = v.GetValue()
f.hdrType = HeaderTypeFromGRPCField(v.GetHeaderType())
f.matchType = MatchTypeFromGRPCField(v.GetMatchType())
f.SetHeaderType( return nil
HeaderTypeFromGRPCField(m.GetHeaderType()),
)
f.SetMatchType(
MatchTypeFromGRPCField(m.GetMatchType()),
)
f.SetKey(m.GetKey())
f.SetValue(m.GetValue())
return f
} }
// TargetToGRPCMessage converts unified role info struct into grpc struct. func HeaderFiltersToGRPC(fs []*HeaderFilter) (res []*acl.EACLRecord_Filter) {
func TargetToGRPCMessage(t *Target) *acl.EACLRecord_Target { if fs != nil {
if t == nil { res = make([]*acl.EACLRecord_Filter, 0, len(fs))
return nil
for i := range fs {
res = append(res, fs[i].ToGRPCMessage().(*acl.EACLRecord_Filter))
}
} }
m := new(acl.EACLRecord_Target) return
}
m.SetRole( func HeaderFiltersFromGRPC(fs []*acl.EACLRecord_Filter) (res []*HeaderFilter, err error) {
RoleToGRPCField(t.GetRole()), if fs != nil {
) res = make([]*HeaderFilter, 0, len(fs))
m.SetKeys(t.GetKeys()) for i := range fs {
var x *HeaderFilter
if fs[i] != nil {
x = new(HeaderFilter)
err = x.FromGRPCMessage(fs[i])
if err != nil {
return
}
}
res = append(res, x)
}
}
return
}
func (t *Target) ToGRPCMessage() grpc.Message {
var m *acl.EACLRecord_Target
if t != nil {
m = new(acl.EACLRecord_Target)
m.SetRole(RoleToGRPCField(t.role))
m.SetKeys(t.keys)
}
return m return m
} }
// TargetInfoFromGRPCMessage converts grpc struct into unified role info struct. func (t *Target) FromGRPCMessage(m grpc.Message) error {
func TargetInfoFromGRPCMessage(m *acl.EACLRecord_Target) *Target { v, ok := m.(*acl.EACLRecord_Target)
if m == nil { if !ok {
return nil return message.NewUnexpectedMessageType(m, v)
} }
t := new(Target) t.role = RoleFromGRPCField(v.GetRole())
t.keys = v.GetKeys()
t.SetRole( return nil
RoleFromGRPCField(m.GetRole()),
)
t.SetKeys(m.GetKeys())
return t
} }
// RecordToGRPCMessage converts unified acl record struct into grpc struct. func TargetsToGRPC(ts []*Target) (res []*acl.EACLRecord_Target) {
func RecordToGRPCMessage(r *Record) *acl.EACLRecord { if ts != nil {
if r == nil { res = make([]*acl.EACLRecord_Target, 0, len(ts))
return nil
for i := range ts {
res = append(res, ts[i].ToGRPCMessage().(*acl.EACLRecord_Target))
}
} }
m := new(acl.EACLRecord) return
}
m.SetOperation( func TargetsFromGRPC(fs []*acl.EACLRecord_Target) (res []*Target, err error) {
OperationToGRPCField(r.GetOperation()), if fs != nil {
) res = make([]*Target, 0, len(fs))
m.SetAction( for i := range fs {
ActionToGRPCField(r.GetAction()), var x *Target
)
filters := r.GetFilters() if fs[i] != nil {
filterMsg := make([]*acl.EACLRecord_Filter, 0, len(filters)) x = new(Target)
for i := range filters { err = x.FromGRPCMessage(fs[i])
filterMsg = append(filterMsg, HeaderFilterToGRPCMessage(filters[i])) if err != nil {
return
}
} }
m.SetFilters(filterMsg) res = append(res, x)
}
targets := r.GetTargets()
targetMsg := make([]*acl.EACLRecord_Target, 0, len(targets))
for i := range targets {
targetMsg = append(targetMsg, TargetToGRPCMessage(targets[i]))
} }
m.SetTargets(targetMsg) return
}
func (r *Record) ToGRPCMessage() grpc.Message {
var m *acl.EACLRecord
if r != nil {
m = new(acl.EACLRecord)
m.SetOperation(OperationToGRPCField(r.op))
m.SetAction(ActionToGRPCField(r.action))
m.SetFilters(HeaderFiltersToGRPC(r.filters))
m.SetTargets(TargetsToGRPC(r.targets))
}
return m return m
} }
// RecordFromGRPCMessage converts grpc struct into unified acl record struct. func (r *Record) FromGRPCMessage(m grpc.Message) error {
func RecordFromGRPCMessage(m *acl.EACLRecord) *Record { v, ok := m.(*acl.EACLRecord)
if m == nil { if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
r.filters, err = HeaderFiltersFromGRPC(v.GetFilters())
if err != nil {
return err
}
r.targets, err = TargetsFromGRPC(v.GetTargets())
if err != nil {
return err
}
r.op = OperationFromGRPCField(v.GetOperation())
r.action = ActionFromGRPCField(v.GetAction())
return nil return nil
}
r := new(Record)
r.SetOperation(
OperationFromGRPCField(m.GetOperation()),
)
r.SetAction(
ActionFromGRPCField(m.GetAction()),
)
filterMsg := m.GetFilters()
filters := make([]*HeaderFilter, 0, len(filterMsg))
for i := range filterMsg {
filters = append(filters, HeaderFilterFromGRPCMessage(filterMsg[i]))
}
r.SetFilters(filters)
targetMsg := m.GetTargets()
targets := make([]*Target, 0, len(targetMsg))
for i := range targetMsg {
targets = append(targets, TargetInfoFromGRPCMessage(targetMsg[i]))
}
r.SetTargets(targets)
return r
} }
// TableToGRPCMessage converts unified acl table struct into grpc struct. func RecordsToGRPC(ts []*Record) (res []*acl.EACLRecord) {
func TableToGRPCMessage(t *Table) *acl.EACLTable { if ts != nil {
if t == nil { res = make([]*acl.EACLRecord, 0, len(ts))
return nil
for i := range ts {
res = append(res, ts[i].ToGRPCMessage().(*acl.EACLRecord))
}
} }
m := new(acl.EACLTable) return
}
m.SetVersion( func RecordsFromGRPC(fs []*acl.EACLRecord) (res []*Record, err error) {
refs.VersionToGRPCMessage(t.GetVersion()), if fs != nil {
) res = make([]*Record, 0, len(fs))
m.SetContainerId(
refs.ContainerIDToGRPCMessage(t.GetContainerID()),
)
records := t.GetRecords() for i := range fs {
recordMsg := make([]*acl.EACLRecord, 0, len(records)) var x *Record
for i := range records { if fs[i] != nil {
recordMsg = append(recordMsg, RecordToGRPCMessage(records[i])) x = new(Record)
err = x.FromGRPCMessage(fs[i])
if err != nil {
return
}
} }
m.SetRecords(recordMsg) res = append(res, x)
}
}
return
}
func (t *Table) ToGRPCMessage() grpc.Message {
var m *acl.EACLTable
if t != nil {
m = new(acl.EACLTable)
m.SetVersion(t.version.ToGRPCMessage().(*refsGRPC.Version))
m.SetContainerId(t.cid.ToGRPCMessage().(*refsGRPC.ContainerID))
m.SetRecords(RecordsToGRPC(t.records))
}
return m return m
} }
// TableFromGRPCMessage converts grpc struct into unified acl table struct. func (t *Table) FromGRPCMessage(m grpc.Message) error {
func TableFromGRPCMessage(m *acl.EACLTable) *Table { v, ok := m.(*acl.EACLTable)
if m == nil { if !ok {
return nil return message.NewUnexpectedMessageType(m, v)
} }
t := new(Table) var err error
t.SetVersion( cid := v.GetContainerId()
refs.VersionFromGRPCMessage(m.GetVersion()), if cid == nil {
) t.cid = nil
t.SetContainerID( } else {
refs.ContainerIDFromGRPCMessage(m.GetContainerId()), if t.cid == nil {
) t.cid = new(refs.ContainerID)
recordMsg := m.GetRecords()
records := make([]*Record, 0, len(recordMsg))
for i := range recordMsg {
records = append(records, RecordFromGRPCMessage(recordMsg[i]))
} }
t.SetRecords(records) err = t.cid.FromGRPCMessage(cid)
if err != nil {
return err
}
}
return t version := v.GetVersion()
if version == nil {
t.version = nil
} else {
if t.version == nil {
t.version = new(refs.Version)
}
err = t.version.FromGRPCMessage(version)
if err != nil {
return err
}
}
t.records, err = RecordsFromGRPC(v.GetRecords())
return err
} }
func TokenLifetimeToGRPCMessage(tl *TokenLifetime) *acl.BearerToken_Body_TokenLifetime { func (l *TokenLifetime) ToGRPCMessage() grpc.Message {
if tl == nil { var m *acl.BearerToken_Body_TokenLifetime
return nil
if l != nil {
m = new(acl.BearerToken_Body_TokenLifetime)
m.SetExp(l.exp)
m.SetIat(l.iat)
m.SetNbf(l.nbf)
} }
m := new(acl.BearerToken_Body_TokenLifetime)
m.SetExp(tl.GetExp())
m.SetNbf(tl.GetNbf())
m.SetIat(tl.GetIat())
return m return m
} }
func TokenLifetimeFromGRPCMessage(m *acl.BearerToken_Body_TokenLifetime) *TokenLifetime { func (l *TokenLifetime) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*acl.BearerToken_Body_TokenLifetime)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
tl := new(TokenLifetime) l.exp = v.GetExp()
l.iat = v.GetIat()
l.nbf = v.GetNbf()
tl.SetExp(m.GetExp()) return nil
tl.SetNbf(m.GetNbf())
tl.SetIat(m.GetIat())
return tl
} }
func BearerTokenBodyToGRPCMessage(v *BearerTokenBody) *acl.BearerToken_Body { func (bt *BearerTokenBody) ToGRPCMessage() grpc.Message {
if v == nil { var m *acl.BearerToken_Body
return nil
if bt != nil {
m = new(acl.BearerToken_Body)
m.SetOwnerId(bt.ownerID.ToGRPCMessage().(*refsGRPC.OwnerID))
m.SetLifetime(bt.lifetime.ToGRPCMessage().(*acl.BearerToken_Body_TokenLifetime))
m.SetEaclTable(bt.eacl.ToGRPCMessage().(*acl.EACLTable))
} }
m := new(acl.BearerToken_Body)
m.SetEaclTable(
TableToGRPCMessage(v.GetEACL()),
)
m.SetOwnerId(
refs.OwnerIDToGRPCMessage(v.GetOwnerID()),
)
m.SetLifetime(
TokenLifetimeToGRPCMessage(v.GetLifetime()),
)
return m return m
} }
func BearerTokenBodyFromGRPCMessage(m *acl.BearerToken_Body) *BearerTokenBody { func (bt *BearerTokenBody) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*acl.BearerToken_Body)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
bt := new(BearerTokenBody) var err error
bt.SetEACL( ownerID := v.GetOwnerId()
TableFromGRPCMessage(m.GetEaclTable()), if ownerID == nil {
) bt.ownerID = nil
} else {
if bt.ownerID == nil {
bt.ownerID = new(refs.OwnerID)
}
bt.SetOwnerID( err = bt.ownerID.FromGRPCMessage(ownerID)
refs.OwnerIDFromGRPCMessage(m.GetOwnerId()), if err != nil {
) return err
}
}
bt.SetLifetime( lifetime := v.GetLifetime()
TokenLifetimeFromGRPCMessage(m.GetLifetime()), if lifetime == nil {
) bt.lifetime = nil
} else {
if bt.lifetime == nil {
bt.lifetime = new(TokenLifetime)
}
return bt err = bt.lifetime.FromGRPCMessage(lifetime)
if err != nil {
return err
}
}
eacl := v.GetEaclTable()
if eacl == nil {
bt.eacl = nil
} else {
if bt.eacl == nil {
bt.eacl = new(Table)
}
err = bt.eacl.FromGRPCMessage(eacl)
}
return err
} }
func BearerTokenToGRPCMessage(t *BearerToken) *acl.BearerToken { func (bt *BearerToken) ToGRPCMessage() grpc.Message {
if t == nil { var m *acl.BearerToken
return nil
if bt != nil {
m = new(acl.BearerToken)
m.SetBody(bt.body.ToGRPCMessage().(*acl.BearerToken_Body))
m.SetSignature(bt.sig.ToGRPCMessage().(*refsGRPC.Signature))
} }
m := new(acl.BearerToken)
m.SetBody(
BearerTokenBodyToGRPCMessage(t.GetBody()),
)
m.SetSignature(
refs.SignatureToGRPCMessage(t.GetSignature()),
)
return m return m
} }
func BearerTokenFromGRPCMessage(m *acl.BearerToken) *BearerToken { func (bt *BearerToken) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*acl.BearerToken)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
bt := new(BearerToken) var err error
bt.SetBody( body := v.GetBody()
BearerTokenBodyFromGRPCMessage(m.GetBody()), if body == nil {
) bt.body = nil
} else {
if bt.body == nil {
bt.body = new(BearerTokenBody)
}
bt.SetSignature( err = bt.body.FromGRPCMessage(body)
refs.SignatureFromGRPCMessage(m.GetSignature()), if err != nil {
) return err
}
}
return bt sig := v.GetSignature()
if sig == nil {
bt.sig = nil
} else {
if bt.sig == nil {
bt.sig = new(refs.Signature)
}
err = bt.sig.FromGRPCMessage(sig)
}
return err
} }

View file

@ -1,146 +1,62 @@
package acl package acl
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
acl "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc" acl "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc"
"google.golang.org/protobuf/encoding/protojson"
) )
func (f *HeaderFilter) MarshalJSON() ([]byte, error) { func (f *HeaderFilter) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(f)
EmitUnpopulated: true,
}.Marshal(
HeaderFilterToGRPCMessage(f),
)
} }
func (f *HeaderFilter) UnmarshalJSON(data []byte) error { func (f *HeaderFilter) UnmarshalJSON(data []byte) error {
msg := new(acl.EACLRecord_Filter) return message.UnmarshalJSON(f, data, new(acl.EACLRecord_Filter))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*f = *HeaderFilterFromGRPCMessage(msg)
return nil
} }
func (t *Target) MarshalJSON() ([]byte, error) { func (t *Target) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(t)
EmitUnpopulated: true,
}.Marshal(
TargetToGRPCMessage(t),
)
} }
func (t *Target) UnmarshalJSON(data []byte) error { func (t *Target) UnmarshalJSON(data []byte) error {
msg := new(acl.EACLRecord_Target) return message.UnmarshalJSON(t, data, new(acl.EACLRecord_Target))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*t = *TargetInfoFromGRPCMessage(msg)
return nil
} }
func (r *Record) MarshalJSON() ([]byte, error) { func (r *Record) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(r)
EmitUnpopulated: true,
}.Marshal(
RecordToGRPCMessage(r),
)
} }
func (r *Record) UnmarshalJSON(data []byte) error { func (r *Record) UnmarshalJSON(data []byte) error {
msg := new(acl.EACLRecord) return message.UnmarshalJSON(r, data, new(acl.EACLRecord))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*r = *RecordFromGRPCMessage(msg)
return nil
} }
func (t *Table) MarshalJSON() ([]byte, error) { func (t *Table) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(t)
EmitUnpopulated: true,
}.Marshal(
TableToGRPCMessage(t),
)
} }
func (t *Table) UnmarshalJSON(data []byte) error { func (t *Table) UnmarshalJSON(data []byte) error {
msg := new(acl.EACLTable) return message.UnmarshalJSON(t, data, new(acl.EACLTable))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*t = *TableFromGRPCMessage(msg)
return nil
} }
func (l *TokenLifetime) MarshalJSON() ([]byte, error) { func (l *TokenLifetime) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(l)
EmitUnpopulated: true,
}.Marshal(
TokenLifetimeToGRPCMessage(l),
)
} }
func (l *TokenLifetime) UnmarshalJSON(data []byte) error { func (l *TokenLifetime) UnmarshalJSON(data []byte) error {
msg := new(acl.BearerToken_Body_TokenLifetime) return message.UnmarshalJSON(l, data, new(acl.BearerToken_Body_TokenLifetime))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*l = *TokenLifetimeFromGRPCMessage(msg)
return nil
} }
func (bt *BearerTokenBody) MarshalJSON() ([]byte, error) { func (bt *BearerTokenBody) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(bt)
EmitUnpopulated: true,
}.Marshal(
BearerTokenBodyToGRPCMessage(bt),
)
} }
func (bt *BearerTokenBody) UnmarshalJSON(data []byte) error { func (bt *BearerTokenBody) UnmarshalJSON(data []byte) error {
msg := new(acl.BearerToken_Body) return message.UnmarshalJSON(bt, data, new(acl.BearerToken_Body))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*bt = *BearerTokenBodyFromGRPCMessage(msg)
return nil
} }
func (bt *BearerToken) MarshalJSON() ([]byte, error) { func (bt *BearerToken) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(bt)
EmitUnpopulated: true,
}.Marshal(
BearerTokenToGRPCMessage(bt),
)
} }
func (bt *BearerToken) UnmarshalJSON(data []byte) error { func (bt *BearerToken) UnmarshalJSON(data []byte) error {
msg := new(acl.BearerToken) return message.UnmarshalJSON(bt, data, new(acl.BearerToken))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*bt = *BearerTokenFromGRPCMessage(msg)
return nil
} }

View file

@ -1,81 +0,0 @@
package acl_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/acl"
"github.com/stretchr/testify/require"
)
func TestBearerTokenJSON(t *testing.T) {
b := generateBearerToken("id")
data, err := b.MarshalJSON()
require.NoError(t, err)
b2 := new(acl.BearerToken)
require.NoError(t, b2.UnmarshalJSON(data))
require.Equal(t, b, b2)
}
func TestFilterJSON(t *testing.T) {
f := generateFilter(acl.HeaderTypeObject, "key", "value")
data, err := f.MarshalJSON()
require.NoError(t, err)
f2 := new(acl.HeaderFilter)
require.NoError(t, f2.UnmarshalJSON(data))
require.Equal(t, f, f2)
}
func TestTargetJSON(t *testing.T) {
tar := generateTarget(acl.RoleSystem, 3)
data, err := tar.MarshalJSON()
require.NoError(t, err)
tar2 := new(acl.Target)
require.NoError(t, tar2.UnmarshalJSON(data))
require.Equal(t, tar, tar2)
}
func TestTable_MarshalJSON(t *testing.T) {
tab := new(acl.Table)
tab.SetRecords([]*acl.Record{generateRecord(false)})
data, err := tab.MarshalJSON()
require.NoError(t, err)
tab2 := new(acl.Table)
require.NoError(t, tab2.UnmarshalJSON(data))
require.Equal(t, tab, tab2)
}
func TestTokenLifetimeJSON(t *testing.T) {
l := generateLifetime(1, 2, 3)
data, err := l.MarshalJSON()
require.NoError(t, err)
l2 := new(acl.TokenLifetime)
require.NoError(t, l2.UnmarshalJSON(data))
require.Equal(t, l, l2)
}
func TestBearerTokenBodyJSON(t *testing.T) {
b := generateBearerTokenBody("id")
data, err := b.MarshalJSON()
require.NoError(t, err)
b2 := new(acl.BearerTokenBody)
require.NoError(t, b2.UnmarshalJSON(data))
require.Equal(t, b, b2)
}

View file

@ -1,9 +1,9 @@
package acl package acl
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
protoutil "github.com/nspcc-dev/neofs-api-go/util/proto" protoutil "github.com/nspcc-dev/neofs-api-go/util/proto"
acl "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc" acl "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc"
"google.golang.org/protobuf/proto"
) )
const ( const (
@ -95,14 +95,7 @@ func (t *Table) StableSize() (size int) {
} }
func (t *Table) Unmarshal(data []byte) error { func (t *Table) Unmarshal(data []byte) error {
m := new(acl.EACLTable) return message.Unmarshal(t, data, new(acl.EACLTable))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*t = *TableFromGRPCMessage(m)
return nil
} }
// StableMarshal marshals unified acl record structure in a protobuf // StableMarshal marshals unified acl record structure in a protobuf
@ -177,14 +170,7 @@ func (r *Record) StableSize() (size int) {
} }
func (r *Record) Unmarshal(data []byte) error { func (r *Record) Unmarshal(data []byte) error {
m := new(acl.EACLRecord) return message.Unmarshal(r, data, new(acl.EACLRecord))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*r = *RecordFromGRPCMessage(m)
return nil
} }
// StableMarshal marshals unified header filter structure in a protobuf // StableMarshal marshals unified header filter structure in a protobuf
@ -247,14 +233,7 @@ func (f *HeaderFilter) StableSize() (size int) {
} }
func (f *HeaderFilter) Unmarshal(data []byte) error { func (f *HeaderFilter) Unmarshal(data []byte) error {
m := new(acl.EACLRecord_Filter) return message.Unmarshal(f, data, new(acl.EACLRecord_Filter))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*f = *HeaderFilterFromGRPCMessage(m)
return nil
} }
// StableMarshal marshals unified role info structure in a protobuf // StableMarshal marshals unified role info structure in a protobuf
@ -301,14 +280,7 @@ func (t *Target) StableSize() (size int) {
} }
func (t *Target) Unmarshal(data []byte) error { func (t *Target) Unmarshal(data []byte) error {
m := new(acl.EACLRecord_Target) return message.Unmarshal(t, data, new(acl.EACLRecord_Target))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*t = *TargetInfoFromGRPCMessage(m)
return nil
} }
func (l *TokenLifetime) StableMarshal(buf []byte) ([]byte, error) { func (l *TokenLifetime) StableMarshal(buf []byte) ([]byte, error) {
@ -360,14 +332,7 @@ func (l *TokenLifetime) StableSize() (size int) {
} }
func (l *TokenLifetime) Unmarshal(data []byte) error { func (l *TokenLifetime) Unmarshal(data []byte) error {
m := new(acl.BearerToken_Body_TokenLifetime) return message.Unmarshal(l, data, new(acl.BearerToken_Body_TokenLifetime))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*l = *TokenLifetimeFromGRPCMessage(m)
return nil
} }
func (bt *BearerTokenBody) StableMarshal(buf []byte) ([]byte, error) { func (bt *BearerTokenBody) StableMarshal(buf []byte) ([]byte, error) {
@ -419,14 +384,7 @@ func (bt *BearerTokenBody) StableSize() (size int) {
} }
func (bt *BearerTokenBody) Unmarshal(data []byte) error { func (bt *BearerTokenBody) Unmarshal(data []byte) error {
m := new(acl.BearerToken_Body) return message.Unmarshal(bt, data, new(acl.BearerToken_Body))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*bt = *BearerTokenBodyFromGRPCMessage(m)
return nil
} }
func (bt *BearerToken) StableMarshal(buf []byte) ([]byte, error) { func (bt *BearerToken) StableMarshal(buf []byte) ([]byte, error) {
@ -470,12 +428,5 @@ func (bt *BearerToken) StableSize() (size int) {
} }
func (bt *BearerToken) Unmarshal(data []byte) error { func (bt *BearerToken) Unmarshal(data []byte) error {
m := new(acl.BearerToken) return message.Unmarshal(bt, data, new(acl.BearerToken))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*bt = *BearerTokenFromGRPCMessage(m)
return nil
} }

View file

@ -1,237 +0,0 @@
package acl_test
import (
"fmt"
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/acl"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/stretchr/testify/require"
)
func generateTarget(u acl.Role, k int) *acl.Target {
target := new(acl.Target)
target.SetRole(u)
keys := make([][]byte, k)
for i := 0; i < k; i++ {
s := fmt.Sprintf("Public Key %d", i+1)
keys[i] = []byte(s)
}
return target
}
func generateFilter(t acl.HeaderType, k, v string) *acl.HeaderFilter {
filter := new(acl.HeaderFilter)
filter.SetHeaderType(t)
filter.SetMatchType(acl.MatchTypeStringEqual)
filter.SetKey(k)
filter.SetValue(v)
return filter
}
func generateRecord(another bool) *acl.Record {
record := new(acl.Record)
switch another {
case true:
t1 := generateTarget(acl.RoleUser, 2)
f1 := generateFilter(acl.HeaderTypeObject, "OID", "ObjectID Value")
record.SetOperation(acl.OperationHead)
record.SetAction(acl.ActionDeny)
record.SetTargets([]*acl.Target{t1})
record.SetFilters([]*acl.HeaderFilter{f1})
default:
t1 := generateTarget(acl.RoleUser, 2)
t2 := generateTarget(acl.RoleSystem, 0)
f1 := generateFilter(acl.HeaderTypeObject, "CID", "Container ID Value")
f2 := generateFilter(acl.HeaderTypeRequest, "X-Header-Key", "X-Header-Value")
record.SetOperation(acl.OperationPut)
record.SetAction(acl.ActionAllow)
record.SetTargets([]*acl.Target{t1, t2})
record.SetFilters([]*acl.HeaderFilter{f1, f2})
}
return record
}
func generateEACL() *acl.Table {
cid := new(refs.ContainerID)
cid.SetValue([]byte("Container ID"))
ver := new(refs.Version)
ver.SetMajor(2)
ver.SetMinor(3)
table := new(acl.Table)
table.SetVersion(ver)
table.SetContainerID(cid)
table.SetRecords([]*acl.Record{generateRecord(true)})
return table
}
func generateSignature(k, v string) *refs.Signature {
sig := new(refs.Signature)
sig.SetKey([]byte(k))
sig.SetSign([]byte(v))
return sig
}
func generateLifetime(exp, nbf, iat uint64) *acl.TokenLifetime {
lifetime := new(acl.TokenLifetime)
lifetime.SetExp(exp)
lifetime.SetNbf(nbf)
lifetime.SetIat(iat)
return lifetime
}
func generateBearerTokenBody(id string) *acl.BearerTokenBody {
owner := new(refs.OwnerID)
owner.SetValue([]byte(id))
tokenBody := new(acl.BearerTokenBody)
tokenBody.SetOwnerID(owner)
tokenBody.SetLifetime(generateLifetime(1, 2, 3))
tokenBody.SetEACL(generateEACL())
return tokenBody
}
func generateBearerToken(id string) *acl.BearerToken {
bearerToken := new(acl.BearerToken)
bearerToken.SetBody(generateBearerTokenBody(id))
bearerToken.SetSignature(generateSignature("id", id))
return bearerToken
}
func TestHeaderFilter_StableMarshal(t *testing.T) {
filterFrom := generateFilter(acl.HeaderTypeObject, "CID", "Container ID Value")
t.Run("non empty", func(t *testing.T) {
filterFrom.SetHeaderType(acl.HeaderTypeObject)
filterFrom.SetMatchType(acl.MatchTypeStringEqual)
filterFrom.SetKey("Hello")
filterFrom.SetValue("World")
wire, err := filterFrom.StableMarshal(nil)
require.NoError(t, err)
filterTo := new(acl.HeaderFilter)
require.NoError(t, filterTo.Unmarshal(wire))
require.Equal(t, filterFrom, filterTo)
})
}
func TestTargetInfo_StableMarshal(t *testing.T) {
targetFrom := generateTarget(acl.RoleUser, 2)
t.Run("non empty", func(t *testing.T) {
targetFrom.SetRole(acl.RoleUser)
targetFrom.SetKeys([][]byte{
[]byte("Public Key 1"),
[]byte("Public Key 2"),
})
wire, err := targetFrom.StableMarshal(nil)
require.NoError(t, err)
targetTo := new(acl.Target)
require.NoError(t, targetTo.Unmarshal(wire))
require.Equal(t, targetFrom, targetTo)
})
}
func TestRecord_StableMarshal(t *testing.T) {
recordFrom := generateRecord(false)
t.Run("non empty", func(t *testing.T) {
wire, err := recordFrom.StableMarshal(nil)
require.NoError(t, err)
to := new(acl.Record)
require.NoError(t, to.Unmarshal(wire))
require.Equal(t, recordFrom, to)
})
}
func TestTable_StableMarshal(t *testing.T) {
tableFrom := new(acl.Table)
t.Run("non empty", func(t *testing.T) {
cid := new(refs.ContainerID)
cid.SetValue([]byte("Container ID"))
ver := new(refs.Version)
ver.SetMajor(2)
ver.SetMinor(3)
r1 := generateRecord(false)
r2 := generateRecord(true)
tableFrom.SetVersion(ver)
tableFrom.SetContainerID(cid)
tableFrom.SetRecords([]*acl.Record{r1, r2})
wire, err := tableFrom.StableMarshal(nil)
require.NoError(t, err)
tableTo := new(acl.Table)
require.NoError(t, tableTo.Unmarshal(wire))
require.Equal(t, tableFrom, tableTo)
})
}
func TestTokenLifetime_StableMarshal(t *testing.T) {
lifetimeFrom := generateLifetime(10, 20, 30)
t.Run("non empty", func(t *testing.T) {
wire, err := lifetimeFrom.StableMarshal(nil)
require.NoError(t, err)
lifetimeTo := new(acl.TokenLifetime)
require.NoError(t, lifetimeTo.Unmarshal(wire))
require.Equal(t, lifetimeFrom, lifetimeTo)
})
}
func TestBearerTokenBody_StableMarshal(t *testing.T) {
bearerTokenBodyFrom := generateBearerTokenBody("Bearer Token Body")
t.Run("non empty", func(t *testing.T) {
wire, err := bearerTokenBodyFrom.StableMarshal(nil)
require.NoError(t, err)
bearerTokenBodyTo := new(acl.BearerTokenBody)
require.NoError(t, bearerTokenBodyTo.Unmarshal(wire))
require.Equal(t, bearerTokenBodyFrom, bearerTokenBodyTo)
})
}
func TestBearerToken_StableMarshal(t *testing.T) {
bearerTokenFrom := generateBearerToken("Bearer Token")
t.Run("non empty", func(t *testing.T) {
wire, err := bearerTokenFrom.StableMarshal(nil)
require.NoError(t, err)
bearerTokenTo := new(acl.BearerToken)
require.NoError(t, bearerTokenTo.Unmarshal(wire))
require.Equal(t, bearerTokenFrom, bearerTokenTo)
})
}

21
v2/acl/message_test.go Normal file
View file

@ -0,0 +1,21 @@
package acl_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/rpc/message"
messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test"
acltest "github.com/nspcc-dev/neofs-api-go/v2/acl/test"
)
func TestMessageConvert(t *testing.T) {
messagetest.TestRPCMessage(t,
func(empty bool) message.Message { return acltest.GenerateFilter(empty) },
func(empty bool) message.Message { return acltest.GenerateTarget(empty) },
func(empty bool) message.Message { return acltest.GenerateRecord(empty) },
func(empty bool) message.Message { return acltest.GenerateTable(empty) },
func(empty bool) message.Message { return acltest.GenerateTokenLifetime(empty) },
func(empty bool) message.Message { return acltest.GenerateBearerTokenBody(empty) },
func(empty bool) message.Message { return acltest.GenerateBearerToken(empty) },
)
}

124
v2/acl/test/generate.go Normal file
View file

@ -0,0 +1,124 @@
package acltest
import (
"github.com/nspcc-dev/neofs-api-go/v2/acl"
accountingtest "github.com/nspcc-dev/neofs-api-go/v2/refs/test"
)
func GenerateBearerToken(empty bool) *acl.BearerToken {
m := new(acl.BearerToken)
m.SetBody(GenerateBearerTokenBody(empty))
m.SetSignature(accountingtest.GenerateSignature(empty))
return m
}
func GenerateBearerTokenBody(empty bool) *acl.BearerTokenBody {
m := new(acl.BearerTokenBody)
m.SetOwnerID(accountingtest.GenerateOwnerID(empty))
m.SetEACL(GenerateTable(empty))
m.SetLifetime(GenerateTokenLifetime(empty))
return m
}
func GenerateTable(empty bool) *acl.Table {
m := new(acl.Table)
m.SetRecords(GenerateRecords(empty))
m.SetContainerID(accountingtest.GenerateContainerID(empty))
m.SetVersion(accountingtest.GenerateVersion(empty))
return m
}
func GenerateRecords(empty bool) []*acl.Record {
rs := make([]*acl.Record, 0)
if !empty {
rs = append(rs,
GenerateRecord(false),
GenerateRecord(false),
)
}
return rs
}
func GenerateRecord(empty bool) *acl.Record {
m := new(acl.Record)
if !empty {
m.SetAction(acl.ActionAllow)
m.SetOperation(acl.OperationGet)
}
m.SetFilters(GenerateFilters(empty))
m.SetTargets(GenerateTargets(empty))
return m
}
func GenerateFilters(empty bool) []*acl.HeaderFilter {
fs := make([]*acl.HeaderFilter, 0)
if !empty {
fs = append(fs,
GenerateFilter(false),
GenerateFilter(false),
)
}
return fs
}
func GenerateFilter(empty bool) *acl.HeaderFilter {
m := new(acl.HeaderFilter)
if !empty {
m.SetKey("key")
m.SetValue("val")
m.SetHeaderType(acl.HeaderTypeRequest)
m.SetMatchType(acl.MatchTypeStringEqual)
}
return m
}
func GenerateTargets(empty bool) []*acl.Target {
ts := make([]*acl.Target, 0)
if !empty {
ts = append(ts,
GenerateTarget(false),
GenerateTarget(false),
)
}
return ts
}
func GenerateTarget(empty bool) *acl.Target {
m := new(acl.Target)
if !empty {
m.SetRole(acl.RoleSystem)
m.SetKeys([][]byte{{1}, {2}})
}
return m
}
func GenerateTokenLifetime(empty bool) *acl.TokenLifetime {
m := new(acl.TokenLifetime)
if !empty {
m.SetExp(1)
m.SetIat(2)
m.SetExp(3)
}
return m
}

View file

@ -1,94 +1,94 @@
package audit package audit
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/grpc"
"github.com/nspcc-dev/neofs-api-go/rpc/message"
audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc" audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-api-go/v2/refs"
refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
) )
// DataAuditResultToGRPCMessage converts unified DataAuditResult structure func (a *DataAuditResult) ToGRPCMessage() grpc.Message {
// into gRPC DataAuditResult message. var m *audit.DataAuditResult
func DataAuditResultToGRPCMessage(a *DataAuditResult) *audit.DataAuditResult {
if a == nil { if a != nil {
return nil m = new(audit.DataAuditResult)
m.SetAuditEpoch(a.auditEpoch)
m.SetPublicKey(a.pubKey)
m.SetContainerId(a.cid.ToGRPCMessage().(*refsGRPC.ContainerID))
m.SetComplete(a.complete)
m.SetVersion(a.version.ToGRPCMessage().(*refsGRPC.Version))
m.SetPassNodes(a.passNodes)
m.SetFailNodes(a.failNodes)
m.SetRetries(a.retries)
m.SetRequests(a.requests)
m.SetHit(a.hit)
m.SetMiss(a.miss)
m.SetFail(a.fail)
m.SetPassSg(refs.ObjectIDListToGRPCMessage(a.passSG))
m.SetFailSg(refs.ObjectIDListToGRPCMessage(a.failSG))
} }
m := new(audit.DataAuditResult)
m.SetVersion(
refs.VersionToGRPCMessage(a.GetVersion()),
)
m.SetAuditEpoch(a.GetAuditEpoch())
m.SetContainerId(
refs.ContainerIDToGRPCMessage(a.GetContainerID()),
)
m.SetPublicKey(a.GetPublicKey())
m.SetComplete(a.GetComplete())
m.SetPassSg(
refs.ObjectIDListToGRPCMessage(a.GetPassSG()),
)
m.SetFailSg(
refs.ObjectIDListToGRPCMessage(a.GetFailSG()),
)
m.SetRequests(a.GetRequests())
m.SetRetries(a.GetRetries())
m.SetHit(a.GetHit())
m.SetMiss(a.GetMiss())
m.SetFail(a.GetFail())
m.SetPassNodes(a.GetPassNodes())
m.SetFailNodes(a.GetFailNodes())
return m return m
} }
// DataAuditResultFromGRPCMessage converts gRPC message DataAuditResult func (a *DataAuditResult) FromGRPCMessage(m grpc.Message) error {
// into unified DataAuditResult structure. v, ok := m.(*audit.DataAuditResult)
func DataAuditResultFromGRPCMessage(m *audit.DataAuditResult) *DataAuditResult { if !ok {
if m == nil { return message.NewUnexpectedMessageType(m, v)
return nil
} }
a := new(DataAuditResult) var err error
a.SetVersion( cid := v.GetContainerId()
refs.VersionFromGRPCMessage(m.GetVersion()), if cid == nil {
) a.cid = nil
} else {
if a.cid == nil {
a.cid = new(refs.ContainerID)
}
a.SetAuditEpoch(m.GetAuditEpoch()) err = a.cid.FromGRPCMessage(cid)
if err != nil {
return err
}
}
a.SetContainerID( version := v.GetVersion()
refs.ContainerIDFromGRPCMessage(m.GetContainerId()), if version == nil {
) a.version = nil
} else {
if a.version == nil {
a.version = new(refs.Version)
}
a.SetPublicKey(m.GetPublicKey()) err = a.version.FromGRPCMessage(version)
if err != nil {
return err
}
}
a.SetComplete(m.GetComplete()) a.passSG, err = refs.ObjectIDListFromGRPCMessage(v.GetPassSg())
if err != nil {
return err
}
a.SetPassSG( a.failSG, err = refs.ObjectIDListFromGRPCMessage(v.GetFailSg())
refs.ObjectIDListFromGRPCMessage(m.GetPassSg()), if err != nil {
) return err
}
a.SetFailSG( a.auditEpoch = v.GetAuditEpoch()
refs.ObjectIDListFromGRPCMessage(m.GetFailSg()), a.pubKey = v.GetPublicKey()
) a.complete = v.GetComplete()
a.passNodes = v.GetPassNodes()
a.failNodes = v.GetFailNodes()
a.retries = v.GetRetries()
a.requests = v.GetRequests()
a.hit = v.GetHit()
a.miss = v.GetMiss()
a.fail = v.GetFail()
a.SetRequests(m.GetRequests()) return err
a.SetRetries(m.GetRetries())
a.SetHit(m.GetHit())
a.SetMiss(m.GetMiss())
a.SetFail(m.GetFail())
a.SetPassNodes(m.GetPassNodes())
a.SetFailNodes(m.GetFailNodes())
return a
} }

View file

@ -1,26 +1,14 @@
package audit package audit
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc" audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc"
"google.golang.org/protobuf/encoding/protojson"
) )
func (a *DataAuditResult) MarshalJSON() ([]byte, error) { func (a *DataAuditResult) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(a)
EmitUnpopulated: true,
}.Marshal(
DataAuditResultToGRPCMessage(a),
)
} }
func (a *DataAuditResult) UnmarshalJSON(data []byte) error { func (a *DataAuditResult) UnmarshalJSON(data []byte) error {
msg := new(audit.DataAuditResult) return message.UnmarshalJSON(a, data, new(audit.DataAuditResult))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*a = *DataAuditResultFromGRPCMessage(msg)
return nil
} }

View file

@ -1,20 +0,0 @@
package audit_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/audit"
"github.com/stretchr/testify/require"
)
func TestDataAuditResultJSON(t *testing.T) {
a := generateDataAuditResult()
data, err := a.MarshalJSON()
require.NoError(t, err)
a2 := new(audit.DataAuditResult)
require.NoError(t, a2.UnmarshalJSON(data))
require.Equal(t, a, a2)
}

View file

@ -1,10 +1,10 @@
package audit package audit
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
"github.com/nspcc-dev/neofs-api-go/util/proto" "github.com/nspcc-dev/neofs-api-go/util/proto"
audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc" audit "github.com/nspcc-dev/neofs-api-go/v2/audit/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-api-go/v2/refs"
goproto "google.golang.org/protobuf/proto"
) )
const ( const (
@ -168,12 +168,5 @@ func (a *DataAuditResult) StableSize() (size int) {
// Unmarshal unmarshals DataAuditResult structure from its protobuf // Unmarshal unmarshals DataAuditResult structure from its protobuf
// binary representation. // binary representation.
func (a *DataAuditResult) Unmarshal(data []byte) error { func (a *DataAuditResult) Unmarshal(data []byte) error {
m := new(audit.DataAuditResult) return message.Unmarshal(a, data, new(audit.DataAuditResult))
if err := goproto.Unmarshal(data, m); err != nil {
return err
}
*a = *DataAuditResultFromGRPCMessage(m)
return nil
} }

View file

@ -1,63 +0,0 @@
package audit_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/audit"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/stretchr/testify/require"
)
func TestDataAuditResult_StableMarshal(t *testing.T) {
from := generateDataAuditResult()
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
to := new(audit.DataAuditResult)
require.NoError(t, to.Unmarshal(wire))
require.Equal(t, from, to)
})
}
func generateDataAuditResult() *audit.DataAuditResult {
a := new(audit.DataAuditResult)
v := new(refs.Version)
v.SetMajor(2)
v.SetMinor(1)
oid1 := new(refs.ObjectID)
oid1.SetValue([]byte("Object ID 1"))
oid2 := new(refs.ObjectID)
oid2.SetValue([]byte("Object ID 2"))
cid := new(refs.ContainerID)
cid.SetValue([]byte("Container ID"))
a.SetVersion(v)
a.SetAuditEpoch(13)
a.SetContainerID(cid)
a.SetPublicKey([]byte("Public key"))
a.SetComplete(true)
a.SetRequests(10)
a.SetRetries(9)
a.SetPassSG([]*refs.ObjectID{oid1, oid2})
a.SetFailSG([]*refs.ObjectID{oid2, oid1})
a.SetHit(1)
a.SetMiss(2)
a.SetFail(3)
a.SetPassNodes([][]byte{
{1, 2},
{3, 4},
})
a.SetFailNodes([][]byte{
{5, 6},
{7, 8},
})
return a
}

15
v2/audit/message_test.go Normal file
View file

@ -0,0 +1,15 @@
package audit_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/rpc/message"
messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test"
audittest "github.com/nspcc-dev/neofs-api-go/v2/audit/test"
)
func TestMessageConvert(t *testing.T) {
messagetest.TestRPCMessage(t,
func(empty bool) message.Message { return audittest.GenerateDataAuditResult(empty) },
)
}

30
v2/audit/test/generate.go Normal file
View file

@ -0,0 +1,30 @@
package audittest
import (
"github.com/nspcc-dev/neofs-api-go/v2/audit"
refstest "github.com/nspcc-dev/neofs-api-go/v2/refs/test"
)
func GenerateDataAuditResult(empty bool) *audit.DataAuditResult {
m := new(audit.DataAuditResult)
if !empty {
m.SetPublicKey([]byte{1, 2, 3})
m.SetAuditEpoch(13)
m.SetHit(100)
m.SetMiss(200)
m.SetFail(300)
m.SetComplete(true)
m.SetPassNodes([][]byte{{1}, {2}})
m.SetFailNodes([][]byte{{3}, {4}})
m.SetRequests(666)
m.SetRetries(777)
}
m.SetVersion(refstest.GenerateVersion(empty))
m.SetContainerID(refstest.GenerateContainerID(empty))
m.SetPassSG(refstest.GenerateObjectIDs(empty))
m.SetFailSG(refstest.GenerateObjectIDs(empty))
return m
}

View file

@ -1,115 +0,0 @@
package client
import (
"context"
"net"
"time"
"google.golang.org/grpc"
)
type Option func(*cfg)
type cfg struct {
addr string
conn net.Conn
gRPC cfgGRPC
dialTimeout time.Duration
}
type cfgGRPC struct {
dialOpts []grpc.DialOption
conn *grpc.ClientConn
}
const defaultDialTimeout = 5 * time.Second
func defaultCfg() *cfg {
return &cfg{
gRPC: cfgGRPC{
dialOpts: []grpc.DialOption{
grpc.WithInsecure(),
},
},
dialTimeout: defaultDialTimeout,
}
}
func NewGRPCClientConn(opts ...Option) (*grpc.ClientConn, error) {
cfg := defaultCfg()
for i := range opts {
opts[i](cfg)
}
var err error
if cfg.gRPC.conn == nil {
if cfg.conn != nil {
if cfg.addr == "" {
cfg.addr = cfg.conn.RemoteAddr().String()
}
cfg.gRPC.dialOpts = append(cfg.gRPC.dialOpts,
grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) {
return cfg.conn, nil
}),
)
}
dialCtx, cancel := context.WithTimeout(context.Background(), cfg.dialTimeout)
cfg.gRPC.conn, err = grpc.DialContext(dialCtx, cfg.addr, cfg.gRPC.dialOpts...)
cancel()
if err != nil {
return nil, err
}
}
return cfg.gRPC.conn, err
}
func WithNetworkAddress(v string) Option {
return func(c *cfg) {
if v != "" {
c.addr = v
}
}
}
func WithNetConn(v net.Conn) Option {
return func(c *cfg) {
if v != nil {
c.conn = v
}
}
}
func WithDialTimeout(v time.Duration) Option {
return func(c *cfg) {
if v > 0 {
c.dialTimeout = v
}
}
}
func WithGRPCDialOpts(v []grpc.DialOption) Option {
return func(c *cfg) {
if len(v) > 0 {
c.gRPC.dialOpts = v
}
}
}
func WithGRPCConn(v *grpc.ClientConn) Option {
return func(c *cfg) {
if v != nil {
c.gRPC.conn = v
}
}
}

View file

@ -1,23 +0,0 @@
package client
import (
"github.com/pkg/errors"
)
type Protocol uint32
const (
_ Protocol = iota
ProtoGRPC
)
var ErrProtoUnsupported = errors.New("unsupported protocol")
func (p Protocol) String() string {
switch p {
case ProtoGRPC:
return "GRPC"
default:
return "UNKNOWN"
}
}

View file

@ -1,355 +0,0 @@
package container
import (
"context"
"github.com/nspcc-dev/neofs-api-go/v2/client"
container "github.com/nspcc-dev/neofs-api-go/v2/container/grpc"
"github.com/pkg/errors"
"google.golang.org/grpc"
)
// Client represents universal container
// transport client.
type Client struct {
cPut *putClient
cGet *getClient
cDel *delClient
cList *listClient
cSetEACL *setEACLClient
cGetEACL *getEACLClient
cAnnounce *announceUsedSpaceClient
}
// Option represents Client option.
type Option func(*cfg)
type cfg struct {
proto client.Protocol
globalOpts []client.Option
gRPC cfgGRPC
}
type cfgGRPC struct {
serviceClient container.ContainerServiceClient
grpcCallOpts []grpc.CallOption
callOpts []container.Option
client *container.Client
}
type putClient struct {
requestConverter func(*PutRequest) interface{}
caller func(context.Context, interface{}) (interface{}, error)
responseConverter func(interface{}) *PutResponse
}
type getClient struct {
requestConverter func(*GetRequest) interface{}
caller func(context.Context, interface{}) (interface{}, error)
responseConverter func(interface{}) *GetResponse
}
type delClient struct {
requestConverter func(*DeleteRequest) interface{}
caller func(context.Context, interface{}) (interface{}, error)
responseConverter func(interface{}) *DeleteResponse
}
type listClient struct {
requestConverter func(*ListRequest) interface{}
caller func(context.Context, interface{}) (interface{}, error)
responseConverter func(interface{}) *ListResponse
}
type setEACLClient struct {
requestConverter func(*SetExtendedACLRequest) interface{}
caller func(context.Context, interface{}) (interface{}, error)
responseConverter func(interface{}) *SetExtendedACLResponse
}
type getEACLClient struct {
requestConverter func(*GetExtendedACLRequest) interface{}
caller func(context.Context, interface{}) (interface{}, error)
responseConverter func(interface{}) *GetExtendedACLResponse
}
type announceUsedSpaceClient struct {
requestConverter func(request *AnnounceUsedSpaceRequest) interface{}
caller func(context.Context, interface{}) (interface{}, error)
responseConverter func(interface{}) *AnnounceUsedSpaceResponse
}
// Put sends PutRequest over the network and returns PutResponse.
//
// It returns any error encountered during the call.
func (c *Client) Put(ctx context.Context, req *PutRequest) (*PutResponse, error) {
resp, err := c.cPut.caller(ctx, c.cPut.requestConverter(req))
if err != nil {
return nil, errors.Wrap(err, "could not send container put request")
}
return c.cPut.responseConverter(resp), nil
}
// Get sends GetRequest over the network and returns GetResponse.
//
// It returns any error encountered during the call.
func (c *Client) Get(ctx context.Context, req *GetRequest) (*GetResponse, error) {
resp, err := c.cGet.caller(ctx, c.cGet.requestConverter(req))
if err != nil {
return nil, errors.Wrap(err, "could not send container get request")
}
return c.cGet.responseConverter(resp), nil
}
// Delete sends GetRequest over the network and returns GetResponse.
//
// It returns any error encountered during the call.
func (c *Client) Delete(ctx context.Context, req *DeleteRequest) (*DeleteResponse, error) {
resp, err := c.cDel.caller(ctx, c.cDel.requestConverter(req))
if err != nil {
return nil, errors.Wrap(err, "could not send container delete request")
}
return c.cDel.responseConverter(resp), nil
}
// List sends ListRequest over the network and returns ListResponse.
//
// It returns any error encountered during the call.
func (c *Client) List(ctx context.Context, req *ListRequest) (*ListResponse, error) {
resp, err := c.cList.caller(ctx, c.cList.requestConverter(req))
if err != nil {
return nil, errors.Wrap(err, "could not send container list request")
}
return c.cList.responseConverter(resp), nil
}
// SetExtendedACL sends SetExtendedACLRequest over the network and returns SetExtendedACLResponse.
//
// It returns any error encountered during the call.
func (c *Client) SetExtendedACL(ctx context.Context, req *SetExtendedACLRequest) (*SetExtendedACLResponse, error) {
resp, err := c.cSetEACL.caller(ctx, c.cSetEACL.requestConverter(req))
if err != nil {
return nil, errors.Wrap(err, "could not send container set EACL request")
}
return c.cSetEACL.responseConverter(resp), nil
}
// GetExtendedACL sends GetExtendedACLRequest over the network and returns GetExtendedACLResponse.
//
// It returns any error encountered during the call.
func (c *Client) GetExtendedACL(ctx context.Context, req *GetExtendedACLRequest) (*GetExtendedACLResponse, error) {
resp, err := c.cGetEACL.caller(ctx, c.cGetEACL.requestConverter(req))
if err != nil {
return nil, errors.Wrap(err, "could not send container get EACL request")
}
return c.cGetEACL.responseConverter(resp), nil
}
// AnnounceUsedSpace sends AnnounceUsedSpaceRequest over the network and returns
// AnnounceUsedSpaceResponse.
//
// It returns any error encountered during the call.
func (c *Client) AnnounceUsedSpace(ctx context.Context, req *AnnounceUsedSpaceRequest) (*AnnounceUsedSpaceResponse, error) {
resp, err := c.cAnnounce.caller(ctx, c.cAnnounce.requestConverter(req))
if err != nil {
return nil, errors.Wrap(err, "could not send announce used space request")
}
return c.cAnnounce.responseConverter(resp), nil
}
func defaultCfg() *cfg {
return &cfg{
proto: client.ProtoGRPC,
}
}
func NewClient(opts ...Option) (*Client, error) {
cfg := defaultCfg()
for i := range opts {
opts[i](cfg)
}
var err error
switch cfg.proto {
case client.ProtoGRPC:
var c *container.Client
if c, err = newGRPCClient(cfg); err != nil {
break
}
return &Client{
cPut: &putClient{
requestConverter: func(req *PutRequest) interface{} {
return PutRequestToGRPCMessage(req)
},
caller: func(ctx context.Context, req interface{}) (interface{}, error) {
return c.Put(ctx, req.(*container.PutRequest))
},
responseConverter: func(resp interface{}) *PutResponse {
return PutResponseFromGRPCMessage(resp.(*container.PutResponse))
},
},
cGet: &getClient{
requestConverter: func(req *GetRequest) interface{} {
return GetRequestToGRPCMessage(req)
},
caller: func(ctx context.Context, req interface{}) (interface{}, error) {
return c.Get(ctx, req.(*container.GetRequest))
},
responseConverter: func(resp interface{}) *GetResponse {
return GetResponseFromGRPCMessage(resp.(*container.GetResponse))
},
},
cDel: &delClient{
requestConverter: func(req *DeleteRequest) interface{} {
return DeleteRequestToGRPCMessage(req)
},
caller: func(ctx context.Context, req interface{}) (interface{}, error) {
return c.Delete(ctx, req.(*container.DeleteRequest))
},
responseConverter: func(resp interface{}) *DeleteResponse {
return DeleteResponseFromGRPCMessage(resp.(*container.DeleteResponse))
},
},
cList: &listClient{
requestConverter: func(req *ListRequest) interface{} {
return ListRequestToGRPCMessage(req)
},
caller: func(ctx context.Context, req interface{}) (interface{}, error) {
return c.List(ctx, req.(*container.ListRequest))
},
responseConverter: func(resp interface{}) *ListResponse {
return ListResponseFromGRPCMessage(resp.(*container.ListResponse))
},
},
cSetEACL: &setEACLClient{
requestConverter: func(req *SetExtendedACLRequest) interface{} {
return SetExtendedACLRequestToGRPCMessage(req)
},
caller: func(ctx context.Context, req interface{}) (interface{}, error) {
return c.SetExtendedACL(ctx, req.(*container.SetExtendedACLRequest))
},
responseConverter: func(resp interface{}) *SetExtendedACLResponse {
return SetExtendedACLResponseFromGRPCMessage(resp.(*container.SetExtendedACLResponse))
},
},
cGetEACL: &getEACLClient{
requestConverter: func(req *GetExtendedACLRequest) interface{} {
return GetExtendedACLRequestToGRPCMessage(req)
},
caller: func(ctx context.Context, req interface{}) (interface{}, error) {
return c.GetExtendedACL(ctx, req.(*container.GetExtendedACLRequest))
},
responseConverter: func(resp interface{}) *GetExtendedACLResponse {
return GetExtendedACLResponseFromGRPCMessage(resp.(*container.GetExtendedACLResponse))
},
},
cAnnounce: &announceUsedSpaceClient{
requestConverter: func(req *AnnounceUsedSpaceRequest) interface{} {
return AnnounceUsedSpaceRequestToGRPCMessage(req)
},
caller: func(ctx context.Context, req interface{}) (interface{}, error) {
return c.AnnounceUsedSpace(ctx, req.(*container.AnnounceUsedSpaceRequest))
},
responseConverter: func(resp interface{}) *AnnounceUsedSpaceResponse {
return AnnounceUsedSpaceResponseFromGRPCMessage(resp.(*container.AnnounceUsedSpaceResponse))
},
},
}, nil
default:
err = client.ErrProtoUnsupported
}
return nil, errors.Wrapf(err, "could not create %s Session client", cfg.proto)
}
func newGRPCClient(cfg *cfg) (*container.Client, error) {
var err error
if cfg.gRPC.client == nil {
if cfg.gRPC.serviceClient == nil {
conn, err := client.NewGRPCClientConn(cfg.globalOpts...)
if err != nil {
return nil, errors.Wrap(err, "could not open gRPC client connection")
}
cfg.gRPC.serviceClient = container.NewContainerServiceClient(conn)
}
cfg.gRPC.client, err = container.NewClient(
cfg.gRPC.serviceClient,
append(
cfg.gRPC.callOpts,
container.WithCallOptions(cfg.gRPC.grpcCallOpts),
)...,
)
}
return cfg.gRPC.client, err
}
func WithGlobalOpts(v ...client.Option) Option {
return func(c *cfg) {
if len(v) > 0 {
c.globalOpts = v
}
}
}
func WithGRPCServiceClient(v container.ContainerServiceClient) Option {
return func(c *cfg) {
c.gRPC.serviceClient = v
}
}
func WithGRPCCallOpts(v []grpc.CallOption) Option {
return func(c *cfg) {
c.gRPC.grpcCallOpts = v
}
}
func WithGRPCClientOpts(v []container.Option) Option {
return func(c *cfg) {
c.gRPC.callOpts = v
}
}
func WithGRPCClient(v *container.Client) Option {
return func(c *cfg) {
c.gRPC.client = v
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,86 +0,0 @@
package container
import (
"context"
"github.com/pkg/errors"
"google.golang.org/grpc"
)
// Client wraps ContainerServiceClient
// with pre-defined configurations.
type Client struct {
*cfg
client ContainerServiceClient
}
// Option represents Client option.
type Option func(*cfg)
type cfg struct {
callOpts []grpc.CallOption
}
// ErrNilContainerServiceClient is returned by functions that expect
// a non-nil ContainerServiceClient, but received nil.
var ErrNilContainerServiceClient = errors.New("container gRPC client is nil")
func defaultCfg() *cfg {
return new(cfg)
}
// NewClient creates, initializes and returns a new Client instance.
//
// Options are applied one by one in order.
func NewClient(c ContainerServiceClient, opts ...Option) (*Client, error) {
if c == nil {
return nil, ErrNilContainerServiceClient
}
cfg := defaultCfg()
for i := range opts {
opts[i](cfg)
}
return &Client{
cfg: cfg,
client: c,
}, nil
}
func (c *Client) Put(ctx context.Context, req *PutRequest) (*PutResponse, error) {
return c.client.Put(ctx, req, c.callOpts...)
}
func (c *Client) Get(ctx context.Context, req *GetRequest) (*GetResponse, error) {
return c.client.Get(ctx, req, c.callOpts...)
}
func (c *Client) Delete(ctx context.Context, req *DeleteRequest) (*DeleteResponse, error) {
return c.client.Delete(ctx, req, c.callOpts...)
}
func (c *Client) List(ctx context.Context, req *ListRequest) (*ListResponse, error) {
return c.client.List(ctx, req, c.callOpts...)
}
func (c *Client) SetExtendedACL(ctx context.Context, req *SetExtendedACLRequest) (*SetExtendedACLResponse, error) {
return c.client.SetExtendedACL(ctx, req, c.callOpts...)
}
func (c *Client) GetExtendedACL(ctx context.Context, req *GetExtendedACLRequest) (*GetExtendedACLResponse, error) {
return c.client.GetExtendedACL(ctx, req, c.callOpts...)
}
func (c *Client) AnnounceUsedSpace(ctx context.Context, req *AnnounceUsedSpaceRequest) (*AnnounceUsedSpaceResponse, error) {
return c.client.AnnounceUsedSpace(ctx, req, c.callOpts...)
}
// WithCallOptions returns Option that configures
// Client to attach call options to each rpc call.
func WithCallOptions(opts []grpc.CallOption) Option {
return func(c *cfg) {
c.callOpts = opts
}
}

View file

@ -1,46 +1,22 @@
package container package container
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
container "github.com/nspcc-dev/neofs-api-go/v2/container/grpc" container "github.com/nspcc-dev/neofs-api-go/v2/container/grpc"
"google.golang.org/protobuf/encoding/protojson"
) )
func (a *Attribute) MarshalJSON() ([]byte, error) { func (a *Attribute) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(a)
EmitUnpopulated: true,
}.Marshal(
AttributeToGRPCMessage(a),
)
} }
func (a *Attribute) UnmarshalJSON(data []byte) error { func (a *Attribute) UnmarshalJSON(data []byte) error {
msg := new(container.Container_Attribute) return message.UnmarshalJSON(a, data, new(container.Container_Attribute))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*a = *AttributeFromGRPCMessage(msg)
return nil
} }
func (c *Container) MarshalJSON() ([]byte, error) { func (c *Container) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(c)
EmitUnpopulated: true,
}.Marshal(
ContainerToGRPCMessage(c),
)
} }
func (c *Container) UnmarshalJSON(data []byte) error { func (c *Container) UnmarshalJSON(data []byte) error {
msg := new(container.Container) return message.UnmarshalJSON(c, data, new(container.Container))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*c = *ContainerFromGRPCMessage(msg)
return nil
} }

View file

@ -1,32 +0,0 @@
package container_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/container"
"github.com/stretchr/testify/require"
)
func TestContainerJSON(t *testing.T) {
c := generateContainer("nonce")
data, err := c.MarshalJSON()
require.NoError(t, err)
c2 := new(container.Container)
require.NoError(t, c2.UnmarshalJSON(data))
require.Equal(t, c, c2)
}
func TestAttributeJSON(t *testing.T) {
b := generateAttribute("key", "value")
data, err := b.MarshalJSON()
require.NoError(t, err)
b2 := new(container.Attribute)
require.NoError(t, b2.UnmarshalJSON(data))
require.Equal(t, b, b2)
}

View file

@ -1,9 +1,9 @@
package container package container
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
protoutil "github.com/nspcc-dev/neofs-api-go/util/proto" protoutil "github.com/nspcc-dev/neofs-api-go/util/proto"
container "github.com/nspcc-dev/neofs-api-go/v2/container/grpc" container "github.com/nspcc-dev/neofs-api-go/v2/container/grpc"
"google.golang.org/protobuf/proto"
) )
const ( const (
@ -89,14 +89,7 @@ func (a *Attribute) StableSize() (size int) {
} }
func (a *Attribute) Unmarshal(data []byte) error { func (a *Attribute) Unmarshal(data []byte) error {
m := new(container.Container_Attribute) return message.Unmarshal(a, data, new(container.Container_Attribute))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*a = *AttributeFromGRPCMessage(m)
return nil
} }
func (c *Container) StableMarshal(buf []byte) ([]byte, error) { func (c *Container) StableMarshal(buf []byte) ([]byte, error) {
@ -178,14 +171,7 @@ func (c *Container) StableSize() (size int) {
} }
func (c *Container) Unmarshal(data []byte) error { func (c *Container) Unmarshal(data []byte) error {
m := new(container.Container) return message.Unmarshal(c, data, new(container.Container))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*c = *ContainerFromGRPCMessage(m)
return nil
} }
func (r *PutRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (r *PutRequestBody) StableMarshal(buf []byte) ([]byte, error) {
@ -228,6 +214,10 @@ func (r *PutRequestBody) StableSize() (size int) {
return size return size
} }
func (r *PutRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.PutRequest_Body))
}
func (r *PutResponseBody) StableMarshal(buf []byte) ([]byte, error) { func (r *PutResponseBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -259,6 +249,10 @@ func (r *PutResponseBody) StableSize() (size int) {
return size return size
} }
func (r *PutResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.PutResponse_Body))
}
func (r *DeleteRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (r *DeleteRequestBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -299,6 +293,10 @@ func (r *DeleteRequestBody) StableSize() (size int) {
return size return size
} }
func (r *DeleteRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.DeleteRequest_Body))
}
func (r *DeleteResponseBody) StableMarshal(buf []byte) ([]byte, error) { func (r *DeleteResponseBody) StableMarshal(buf []byte) ([]byte, error) {
return nil, nil return nil, nil
} }
@ -307,6 +305,10 @@ func (r *DeleteResponseBody) StableSize() (size int) {
return 0 return 0
} }
func (r *DeleteResponseBody) Unmarshal([]byte) error {
return nil
}
func (r *GetRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (r *GetRequestBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -334,6 +336,10 @@ func (r *GetRequestBody) StableSize() (size int) {
return size return size
} }
func (r *GetRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.GetRequest_Body))
}
func (r *GetResponseBody) StableMarshal(buf []byte) ([]byte, error) { func (r *GetResponseBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -361,6 +367,10 @@ func (r *GetResponseBody) StableSize() (size int) {
return size return size
} }
func (r *GetResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.GetResponse_Body))
}
func (r *ListRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (r *ListRequestBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -388,6 +398,10 @@ func (r *ListRequestBody) StableSize() (size int) {
return size return size
} }
func (r *ListRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.ListRequest_Body))
}
func (r *ListResponseBody) StableMarshal(buf []byte) ([]byte, error) { func (r *ListResponseBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -426,6 +440,10 @@ func (r *ListResponseBody) StableSize() (size int) {
return size return size
} }
func (r *ListResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.ListResponse_Body))
}
func (r *SetExtendedACLRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (r *SetExtendedACLRequestBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -466,6 +484,10 @@ func (r *SetExtendedACLRequestBody) StableSize() (size int) {
return size return size
} }
func (r *SetExtendedACLRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.SetExtendedACLRequest_Body))
}
func (r *SetExtendedACLResponseBody) StableMarshal(buf []byte) ([]byte, error) { func (r *SetExtendedACLResponseBody) StableMarshal(buf []byte) ([]byte, error) {
return nil, nil return nil, nil
} }
@ -474,6 +496,10 @@ func (r *SetExtendedACLResponseBody) StableSize() (size int) {
return 0 return 0
} }
func (r *SetExtendedACLResponseBody) Unmarshal([]byte) error {
return nil
}
func (r *GetExtendedACLRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (r *GetExtendedACLRequestBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -501,6 +527,10 @@ func (r *GetExtendedACLRequestBody) StableSize() (size int) {
return size return size
} }
func (r *GetExtendedACLRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.GetExtendedACLRequest_Body))
}
func (r *GetExtendedACLResponseBody) StableMarshal(buf []byte) ([]byte, error) { func (r *GetExtendedACLResponseBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -541,6 +571,10 @@ func (r *GetExtendedACLResponseBody) StableSize() (size int) {
return size return size
} }
func (r *GetExtendedACLResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.GetExtendedACLResponse_Body))
}
func (a *UsedSpaceAnnouncement) StableMarshal(buf []byte) ([]byte, error) { func (a *UsedSpaceAnnouncement) StableMarshal(buf []byte) ([]byte, error) {
if a == nil { if a == nil {
return []byte{}, nil return []byte{}, nil
@ -590,14 +624,7 @@ func (a *UsedSpaceAnnouncement) StableSize() (size int) {
} }
func (a *UsedSpaceAnnouncement) Unmarshal(data []byte) error { func (a *UsedSpaceAnnouncement) Unmarshal(data []byte) error {
m := new(container.AnnounceUsedSpaceRequest_Body_Announcement) return message.Unmarshal(a, data, new(container.AnnounceUsedSpaceRequest_Body_Announcement))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*a = *UsedSpaceAnnouncementFromGRPCMessage(m)
return nil
} }
func (r *AnnounceUsedSpaceRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (r *AnnounceUsedSpaceRequestBody) StableMarshal(buf []byte) ([]byte, error) {
@ -638,6 +665,10 @@ func (r *AnnounceUsedSpaceRequestBody) StableSize() (size int) {
return size return size
} }
func (r *AnnounceUsedSpaceRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(container.AnnounceUsedSpaceRequest_Body))
}
func (r *AnnounceUsedSpaceResponseBody) StableMarshal(buf []byte) ([]byte, error) { func (r *AnnounceUsedSpaceResponseBody) StableMarshal(buf []byte) ([]byte, error) {
return nil, nil return nil, nil
} }
@ -645,3 +676,7 @@ func (r *AnnounceUsedSpaceResponseBody) StableMarshal(buf []byte) ([]byte, error
func (r *AnnounceUsedSpaceResponseBody) StableSize() (size int) { func (r *AnnounceUsedSpaceResponseBody) StableSize() (size int) {
return 0 return 0
} }
func (r *AnnounceUsedSpaceResponseBody) Unmarshal([]byte) error {
return nil
}

View file

@ -1,492 +0,0 @@
package container_test
import (
"crypto/sha256"
"fmt"
"math/rand"
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/acl"
"github.com/nspcc-dev/neofs-api-go/v2/container"
grpc "github.com/nspcc-dev/neofs-api-go/v2/container/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/stretchr/testify/require"
goproto "google.golang.org/protobuf/proto"
)
func TestAttribute_StableMarshal(t *testing.T) {
attributeFrom := generateAttribute("key", "value")
t.Run("non empty", func(t *testing.T) {
wire, err := attributeFrom.StableMarshal(nil)
require.NoError(t, err)
attributeTo := new(container.Attribute)
require.NoError(t, attributeTo.Unmarshal(wire))
require.Equal(t, attributeFrom, attributeTo)
})
}
func TestContainer_StableMarshal(t *testing.T) {
cnrFrom := generateContainer("nonce")
t.Run("non empty", func(t *testing.T) {
wire, err := cnrFrom.StableMarshal(nil)
require.NoError(t, err)
cnrTo := new(container.Container)
require.NoError(t, cnrTo.Unmarshal(wire))
require.Equal(t, cnrFrom, cnrTo)
})
}
func TestPutRequestBody_StableMarshal(t *testing.T) {
requestFrom := generatePutRequestBody("nonce")
transport := new(grpc.PutRequest_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := requestFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
requestTo := container.PutRequestBodyFromGRPCMessage(transport)
require.Equal(t, requestFrom, requestTo)
})
}
func TestPutResponseBody_StableMarshal(t *testing.T) {
responseFrom := generatePutResponseBody("Container ID")
transport := new(grpc.PutResponse_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := responseFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
responseTo := container.PutResponseBodyFromGRPCMessage(transport)
require.Equal(t, responseFrom, responseTo)
})
}
func TestDeleteRequestBody_StableMarshal(t *testing.T) {
requestFrom := generateDeleteRequestBody("Container ID")
transport := new(grpc.DeleteRequest_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := requestFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
requestTo := container.DeleteRequestBodyFromGRPCMessage(transport)
require.Equal(t, requestFrom, requestTo)
})
}
func TestDeleteResponseBody_StableMarshal(t *testing.T) {
responseFrom := generateDeleteResponseBody()
transport := new(grpc.DeleteResponse_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := responseFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
responseTo := container.DeleteResponseBodyFromGRPCMessage(transport)
require.Equal(t, responseFrom, responseTo)
})
}
func TestGetRequestBody_StableMarshal(t *testing.T) {
requestFrom := generateGetRequestBody("Container ID")
transport := new(grpc.GetRequest_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := requestFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
requestTo := container.GetRequestBodyFromGRPCMessage(transport)
require.Equal(t, requestFrom, requestTo)
})
}
func TestGetResponseBody_StableMarshal(t *testing.T) {
responseFrom := generateGetResponseBody("nonce")
transport := new(grpc.GetResponse_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := responseFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
responseTo := container.GetResponseBodyFromGRPCMessage(transport)
require.Equal(t, responseFrom, responseTo)
})
}
func TestListRequestBody_StableMarshal(t *testing.T) {
requestFrom := generateListRequestBody("Owner ID")
transport := new(grpc.ListRequest_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := requestFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
requestTo := container.ListRequestBodyFromGRPCMessage(transport)
require.Equal(t, requestFrom, requestTo)
})
}
func TestListResponseBody_StableMarshal(t *testing.T) {
responseFrom := generateListResponseBody(3)
transport := new(grpc.ListResponse_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := responseFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
responseTo := container.ListResponseBodyFromGRPCMessage(transport)
require.Equal(t, responseFrom, responseTo)
})
}
func TestSetEACLRequestBody_StableMarshal(t *testing.T) {
requestFrom := generateSetEACLRequestBody(4, "Filter Key", "Filter Value")
transport := new(grpc.SetExtendedACLRequest_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := requestFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
requestTo := container.SetExtendedACLRequestBodyFromGRPCMessage(transport)
require.Equal(t, requestFrom, requestTo)
})
}
func TestSetEACLResponseBody_StableMarshal(t *testing.T) {
responseFrom := generateSetEACLResponseBody()
transport := new(grpc.SetExtendedACLResponse_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := responseFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
responseTo := container.SetExtendedACLResponseBodyFromGRPCMessage(transport)
require.Equal(t, responseFrom, responseTo)
})
}
func TestGetEACLRequestBody_StableMarshal(t *testing.T) {
requestFrom := generateGetEACLRequestBody("Container ID")
transport := new(grpc.GetExtendedACLRequest_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := requestFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
requestTo := container.GetExtendedACLRequestBodyFromGRPCMessage(transport)
require.Equal(t, requestFrom, requestTo)
})
}
func TestGetEACLResponseBody_StableMarshal(t *testing.T) {
responseFrom := generateGetEACLResponseBody(3, "Filter Key", "Filter Value")
transport := new(grpc.GetExtendedACLResponse_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := responseFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
responseTo := container.GetExtendedACLResponseBodyFromGRPCMessage(transport)
require.Equal(t, responseFrom, responseTo)
})
}
func TestUsedSpaceAnnouncement_StableMarshal(t *testing.T) {
from := generateAnnouncement()
transport := new(grpc.AnnounceUsedSpaceRequest_Body_Announcement)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := container.UsedSpaceAnnouncementFromGRPCMessage(transport)
require.Equal(t, from, to)
})
}
func TestAnnounceUsedSpaceRequestBody_StableMarshal(t *testing.T) {
requestFrom := generateAnnounceRequestBody(10)
transport := new(grpc.AnnounceUsedSpaceRequest_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := requestFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
requestTo := container.AnnounceUsedSpaceRequestBodyFromGRPCMessage(transport)
require.Equal(t, requestFrom, requestTo)
})
}
func TestAnnounceUsedSpaceResponseBody_StableMarshal(t *testing.T) {
responseFrom := generateAnnounceResponseBody()
transport := new(grpc.AnnounceUsedSpaceResponse_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := responseFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
responseTo := container.AnnounceUsedSpaceResponseBodyFromGRPCMessage(transport)
require.Equal(t, responseFrom, responseTo)
})
}
func generateAttribute(k, v string) *container.Attribute {
attr := new(container.Attribute)
attr.SetKey(k)
attr.SetValue(v)
return attr
}
func generateContainer(n string) *container.Container {
owner := new(refs.OwnerID)
owner.SetValue([]byte("Owner ID"))
version := new(refs.Version)
version.SetMajor(2)
version.SetMinor(0)
// todo: add placement rule
cnr := new(container.Container)
cnr.SetOwnerID(owner)
cnr.SetVersion(version)
cnr.SetAttributes([]*container.Attribute{
generateAttribute("one", "two"),
generateAttribute("three", "four"),
})
cnr.SetBasicACL(100)
cnr.SetNonce([]byte(n))
return cnr
}
func generateSignature(k, v string) *refs.Signature {
sig := new(refs.Signature)
sig.SetKey([]byte(k))
sig.SetSign([]byte(v))
return sig
}
func generatePutRequestBody(n string) *container.PutRequestBody {
req := new(container.PutRequestBody)
req.SetContainer(generateContainer(n))
req.SetSignature(generateSignature("public key", "signature"))
return req
}
func generatePutResponseBody(id string) *container.PutResponseBody {
cid := new(refs.ContainerID)
cid.SetValue([]byte(id))
resp := new(container.PutResponseBody)
resp.SetContainerID(cid)
return resp
}
func generateDeleteRequestBody(id string) *container.DeleteRequestBody {
cid := new(refs.ContainerID)
cid.SetValue([]byte(id))
req := new(container.DeleteRequestBody)
req.SetContainerID(cid)
req.SetSignature(generateSignature("public key", "signature"))
return req
}
func generateDeleteResponseBody() *container.DeleteResponseBody {
return new(container.DeleteResponseBody)
}
func generateGetRequestBody(id string) *container.GetRequestBody {
cid := new(refs.ContainerID)
cid.SetValue([]byte(id))
req := new(container.GetRequestBody)
req.SetContainerID(cid)
return req
}
func generateGetResponseBody(n string) *container.GetResponseBody {
resp := new(container.GetResponseBody)
resp.SetContainer(generateContainer(n))
return resp
}
func generateListRequestBody(id string) *container.ListRequestBody {
owner := new(refs.OwnerID)
owner.SetValue([]byte(id))
req := new(container.ListRequestBody)
req.SetOwnerID(owner)
return req
}
func generateListResponseBody(n int) *container.ListResponseBody {
resp := new(container.ListResponseBody)
ids := make([]*refs.ContainerID, n)
for i := 0; i < n; i++ {
cid := new(refs.ContainerID)
cid.SetValue([]byte(fmt.Sprintf("Container ID %d", n+1)))
ids[i] = cid
}
resp.SetContainerIDs(ids)
return resp
}
func generateEACL(n int, k, v string) *acl.Table {
target := new(acl.Target)
target.SetRole(acl.RoleUser)
keys := make([][]byte, n)
for i := 0; i < n; i++ {
s := fmt.Sprintf("Public Key %d", i+1)
keys[i] = []byte(s)
}
filter := new(acl.HeaderFilter)
filter.SetHeaderType(acl.HeaderTypeObject)
filter.SetMatchType(acl.MatchTypeStringEqual)
filter.SetKey(k)
filter.SetValue(v)
record := new(acl.Record)
record.SetOperation(acl.OperationHead)
record.SetAction(acl.ActionDeny)
record.SetTargets([]*acl.Target{target})
record.SetFilters([]*acl.HeaderFilter{filter})
table := new(acl.Table)
cid := new(refs.ContainerID)
cid.SetValue([]byte("Container ID"))
table.SetContainerID(cid)
table.SetRecords([]*acl.Record{record})
return table
}
func generateSetEACLRequestBody(n int, k, v string) *container.SetExtendedACLRequestBody {
req := new(container.SetExtendedACLRequestBody)
req.SetEACL(generateEACL(n, k, v))
req.SetSignature(generateSignature("public key", "signature"))
return req
}
func generateSetEACLResponseBody() *container.SetExtendedACLResponseBody {
return new(container.SetExtendedACLResponseBody)
}
func generateGetEACLRequestBody(id string) *container.GetExtendedACLRequestBody {
cid := new(refs.ContainerID)
cid.SetValue([]byte(id))
req := new(container.GetExtendedACLRequestBody)
req.SetContainerID(cid)
return req
}
func generateGetEACLResponseBody(n int, k, v string) *container.GetExtendedACLResponseBody {
resp := new(container.GetExtendedACLResponseBody)
resp.SetEACL(generateEACL(n, k, v))
resp.SetSignature(generateSignature("public key", "signature"))
return resp
}
func generateAnnouncement() *container.UsedSpaceAnnouncement {
buf := make([]byte, sha256.Size)
rand.Read(buf)
cid := new(refs.ContainerID)
cid.SetValue(buf)
a := new(container.UsedSpaceAnnouncement)
a.SetEpoch(rand.Uint64())
a.SetContainerID(cid)
a.SetUsedSpace(rand.Uint64())
return a
}
func generateAnnounceRequestBody(n int) *container.AnnounceUsedSpaceRequestBody {
resp := new(container.AnnounceUsedSpaceRequestBody)
announcements := make([]*container.UsedSpaceAnnouncement, 0, n)
for i := 0; i < n; i++ {
announcements = append(announcements, generateAnnouncement())
}
resp.SetAnnouncements(announcements)
return resp
}
func generateAnnounceResponseBody() *container.AnnounceUsedSpaceResponseBody {
return new(container.AnnounceUsedSpaceResponseBody)
}

View file

@ -0,0 +1,43 @@
package container_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/rpc/message"
messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test"
containertest "github.com/nspcc-dev/neofs-api-go/v2/container/test"
)
func TestMessageConvert(t *testing.T) {
messagetest.TestRPCMessage(t,
func(empty bool) message.Message { return containertest.GenerateAttribute(empty) },
func(empty bool) message.Message { return containertest.GenerateContainer(empty) },
func(empty bool) message.Message { return containertest.GeneratePutRequestBody(empty) },
func(empty bool) message.Message { return containertest.GeneratePutRequest(empty) },
func(empty bool) message.Message { return containertest.GeneratePutResponseBody(empty) },
func(empty bool) message.Message { return containertest.GeneratePutResponse(empty) },
func(empty bool) message.Message { return containertest.GenerateGetRequestBody(empty) },
func(empty bool) message.Message { return containertest.GenerateGetRequest(empty) },
func(empty bool) message.Message { return containertest.GenerateGetResponseBody(empty) },
func(empty bool) message.Message { return containertest.GenerateGetResponse(empty) },
func(empty bool) message.Message { return containertest.GenerateDeleteRequestBody(empty) },
func(empty bool) message.Message { return containertest.GenerateDeleteRequest(empty) },
func(empty bool) message.Message { return containertest.GenerateDeleteResponseBody(empty) },
func(empty bool) message.Message { return containertest.GenerateDeleteResponse(empty) },
func(empty bool) message.Message { return containertest.GenerateListRequestBody(empty) },
func(empty bool) message.Message { return containertest.GenerateListRequest(empty) },
func(empty bool) message.Message { return containertest.GenerateListResponseBody(empty) },
func(empty bool) message.Message { return containertest.GenerateListResponse(empty) },
func(empty bool) message.Message { return containertest.GenerateSetExtendedACLRequestBody(empty) },
func(empty bool) message.Message { return containertest.GenerateSetExtendedACLRequest(empty) },
func(empty bool) message.Message { return containertest.GenerateGetRequestBody(empty) },
func(empty bool) message.Message { return containertest.GenerateGetRequest(empty) },
func(empty bool) message.Message { return containertest.GenerateGetResponseBody(empty) },
func(empty bool) message.Message { return containertest.GenerateGetResponse(empty) },
func(empty bool) message.Message { return containertest.GenerateUsedSpaceAnnouncement(empty) },
func(empty bool) message.Message { return containertest.GenerateAnnounceUsedSpaceRequestBody(empty) },
func(empty bool) message.Message { return containertest.GenerateAnnounceUsedSpaceRequest(empty) },
func(empty bool) message.Message { return containertest.GenerateAnnounceUsedSpaceResponseBody(empty) },
func(empty bool) message.Message { return containertest.GenerateAnnounceUsedSpaceResponse(empty) },
)
}

View file

@ -1,113 +0,0 @@
package container
import (
"context"
"github.com/nspcc-dev/neofs-api-go/v2/session"
)
type Service interface {
Put(context.Context, *PutRequest) (*PutResponse, error)
Delete(context.Context, *DeleteRequest) (*DeleteResponse, error)
Get(context.Context, *GetRequest) (*GetResponse, error)
List(context.Context, *ListRequest) (*ListResponse, error)
SetExtendedACL(context.Context, *SetExtendedACLRequest) (*SetExtendedACLResponse, error)
GetExtendedACL(context.Context, *GetExtendedACLRequest) (*GetExtendedACLResponse, error)
AnnounceUsedSpace(context.Context, *AnnounceUsedSpaceRequest) (*AnnounceUsedSpaceResponse, error)
}
type PutRequest struct {
body *PutRequestBody
metaHeader *session.RequestMetaHeader
verifyHeader *session.RequestVerificationHeader
}
type PutResponse struct {
body *PutResponseBody
metaHeader *session.ResponseMetaHeader
verifyHeader *session.ResponseVerificationHeader
}
type DeleteRequest struct {
body *DeleteRequestBody
metaHeader *session.RequestMetaHeader
verifyHeader *session.RequestVerificationHeader
}
type DeleteResponse struct {
body *DeleteResponseBody
metaHeader *session.ResponseMetaHeader
verifyHeader *session.ResponseVerificationHeader
}
type ListRequest struct {
body *ListRequestBody
metaHeader *session.RequestMetaHeader
verifyHeader *session.RequestVerificationHeader
}
type ListResponse struct {
body *ListResponseBody
metaHeader *session.ResponseMetaHeader
verifyHeader *session.ResponseVerificationHeader
}
type SetExtendedACLRequest struct {
body *SetExtendedACLRequestBody
metaHeader *session.RequestMetaHeader
verifyHeader *session.RequestVerificationHeader
}
type SetExtendedACLResponse struct {
body *SetExtendedACLResponseBody
metaHeader *session.ResponseMetaHeader
verifyHeader *session.ResponseVerificationHeader
}
type GetExtendedACLRequest struct {
body *GetExtendedACLRequestBody
metaHeader *session.RequestMetaHeader
verifyHeader *session.RequestVerificationHeader
}
type GetExtendedACLResponse struct {
body *GetExtendedACLResponseBody
metaHeader *session.ResponseMetaHeader
verifyHeader *session.ResponseVerificationHeader
}
type AnnounceUsedSpaceRequest struct {
body *AnnounceUsedSpaceRequestBody
metaHeader *session.RequestMetaHeader
verifyHeader *session.RequestVerificationHeader
}
type AnnounceUsedSpaceResponse struct {
body *AnnounceUsedSpaceResponseBody
metaHeader *session.ResponseMetaHeader
verifyHeader *session.ResponseVerificationHeader
}

View file

@ -1,958 +0,0 @@
package main
import (
"context"
"crypto/ecdsa"
"errors"
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/acl"
"github.com/nspcc-dev/neofs-api-go/v2/container"
containerGRPC "github.com/nspcc-dev/neofs-api-go/v2/container/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-api-go/v2/session"
"github.com/nspcc-dev/neofs-api-go/v2/signature"
"github.com/nspcc-dev/neofs-crypto/test"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
)
type testGRPCClient struct {
server containerGRPC.ContainerServiceServer
}
type testGRPCServer struct {
key *ecdsa.PrivateKey
putResp *container.PutResponse
getResp *container.GetResponse
delResp *container.DeleteResponse
listResp *container.ListResponse
sEaclResp *container.SetExtendedACLResponse
gEaclResp *container.GetExtendedACLResponse
announceResp *container.AnnounceUsedSpaceResponse
err error
}
func (s *testGRPCClient) Put(ctx context.Context, in *containerGRPC.PutRequest, opts ...grpc.CallOption) (*containerGRPC.PutResponse, error) {
return s.server.Put(ctx, in)
}
func (s *testGRPCClient) Delete(ctx context.Context, in *containerGRPC.DeleteRequest, opts ...grpc.CallOption) (*containerGRPC.DeleteResponse, error) {
return s.server.Delete(ctx, in)
}
func (s *testGRPCClient) Get(ctx context.Context, in *containerGRPC.GetRequest, opts ...grpc.CallOption) (*containerGRPC.GetResponse, error) {
return s.server.Get(ctx, in)
}
func (s *testGRPCClient) List(ctx context.Context, in *containerGRPC.ListRequest, opts ...grpc.CallOption) (*containerGRPC.ListResponse, error) {
return s.server.List(ctx, in)
}
func (s *testGRPCClient) SetExtendedACL(ctx context.Context, in *containerGRPC.SetExtendedACLRequest, opts ...grpc.CallOption) (*containerGRPC.SetExtendedACLResponse, error) {
return s.server.SetExtendedACL(ctx, in)
}
func (s *testGRPCClient) GetExtendedACL(ctx context.Context, in *containerGRPC.GetExtendedACLRequest, opts ...grpc.CallOption) (*containerGRPC.GetExtendedACLResponse, error) {
return s.server.GetExtendedACL(ctx, in)
}
func (s *testGRPCClient) AnnounceUsedSpace(ctx context.Context, in *containerGRPC.AnnounceUsedSpaceRequest, opts ...grpc.CallOption) (*containerGRPC.AnnounceUsedSpaceResponse, error) {
return s.server.AnnounceUsedSpace(ctx, in)
}
func (s *testGRPCServer) Put(_ context.Context, req *containerGRPC.PutRequest) (*containerGRPC.PutResponse, error) {
if s.err != nil {
return nil, s.err
}
// verify request structure
if err := signature.VerifyServiceMessage(
container.PutRequestFromGRPCMessage(req),
); err != nil {
return nil, err
}
// sign response structure
if err := signature.SignServiceMessage(s.key, s.putResp); err != nil {
return nil, err
}
return container.PutResponseToGRPCMessage(s.putResp), nil
}
func (s *testGRPCServer) Delete(_ context.Context, req *containerGRPC.DeleteRequest) (*containerGRPC.DeleteResponse, error) {
if s.err != nil {
return nil, s.err
}
// verify request structure
if err := signature.VerifyServiceMessage(
container.DeleteRequestFromGRPCMessage(req),
); err != nil {
return nil, err
}
// sign response structure
if err := signature.SignServiceMessage(s.key, s.delResp); err != nil {
return nil, err
}
return container.DeleteResponseToGRPCMessage(s.delResp), nil
}
func (s *testGRPCServer) Get(_ context.Context, req *containerGRPC.GetRequest) (*containerGRPC.GetResponse, error) {
if s.err != nil {
return nil, s.err
}
// verify request structure
if err := signature.VerifyServiceMessage(
container.GetRequestFromGRPCMessage(req),
); err != nil {
return nil, err
}
// sign response structure
if err := signature.SignServiceMessage(s.key, s.getResp); err != nil {
return nil, err
}
return container.GetResponseToGRPCMessage(s.getResp), nil
}
func (s *testGRPCServer) List(_ context.Context, req *containerGRPC.ListRequest) (*containerGRPC.ListResponse, error) {
if s.err != nil {
return nil, s.err
}
// verify request structure
if err := signature.VerifyServiceMessage(
container.ListRequestFromGRPCMessage(req),
); err != nil {
return nil, err
}
// sign response structure
if err := signature.SignServiceMessage(s.key, s.listResp); err != nil {
return nil, err
}
return container.ListResponseToGRPCMessage(s.listResp), nil
}
func (s *testGRPCServer) SetExtendedACL(_ context.Context, req *containerGRPC.SetExtendedACLRequest) (*containerGRPC.SetExtendedACLResponse, error) {
if s.err != nil {
return nil, s.err
}
// verify request structure
if err := signature.VerifyServiceMessage(
container.SetExtendedACLRequestFromGRPCMessage(req),
); err != nil {
return nil, err
}
// sign response structure
if err := signature.SignServiceMessage(s.key, s.sEaclResp); err != nil {
return nil, err
}
return container.SetExtendedACLResponseToGRPCMessage(s.sEaclResp), nil
}
func (s *testGRPCServer) GetExtendedACL(_ context.Context, req *containerGRPC.GetExtendedACLRequest) (*containerGRPC.GetExtendedACLResponse, error) {
if s.err != nil {
return nil, s.err
}
// verify request structure
if err := signature.VerifyServiceMessage(
container.GetExtendedACLRequestFromGRPCMessage(req),
); err != nil {
return nil, err
}
// sign response structure
if err := signature.SignServiceMessage(s.key, s.gEaclResp); err != nil {
return nil, err
}
return container.GetExtendedACLResponseToGRPCMessage(s.gEaclResp), nil
}
func (s *testGRPCServer) AnnounceUsedSpace(_ context.Context, req *containerGRPC.AnnounceUsedSpaceRequest) (*containerGRPC.AnnounceUsedSpaceResponse, error) {
if s.err != nil {
return nil, s.err
}
// verify request structure
if err := signature.VerifyServiceMessage(
container.AnnounceUsedSpaceRequestFromGRPCMessage(req),
); err != nil {
return nil, err
}
// sign response structure
if err := signature.SignServiceMessage(s.key, s.announceResp); err != nil {
return nil, err
}
return container.AnnounceUsedSpaceResponseToGRPCMessage(s.announceResp), nil
}
func testPutRequest() *container.PutRequest {
cnr := new(container.Container)
cnr.SetBasicACL(1)
body := new(container.PutRequestBody)
body.SetContainer(cnr)
meta := new(session.RequestMetaHeader)
meta.SetTTL(1)
req := new(container.PutRequest)
req.SetBody(body)
req.SetMetaHeader(meta)
return req
}
func testPutResponse() *container.PutResponse {
cid := new(refs.ContainerID)
cid.SetValue([]byte{1, 2, 3})
body := new(container.PutResponseBody)
body.SetContainerID(cid)
meta := new(session.ResponseMetaHeader)
meta.SetTTL(1)
meta.SetXHeaders([]*session.XHeader{}) // w/o this require.Equal fails due to nil and []T{} difference
resp := new(container.PutResponse)
resp.SetBody(body)
resp.SetMetaHeader(meta)
return resp
}
func testGetRequest() *container.GetRequest {
cid := new(refs.ContainerID)
cid.SetValue([]byte{1, 2, 3})
body := new(container.GetRequestBody)
body.SetContainerID(cid)
meta := new(session.RequestMetaHeader)
meta.SetTTL(1)
req := new(container.GetRequest)
req.SetBody(body)
req.SetMetaHeader(meta)
return req
}
func testGetResponse() *container.GetResponse {
cnr := new(container.Container)
cnr.SetAttributes([]*container.Attribute{}) // w/o this require.Equal fails due to nil and []T{} difference
body := new(container.GetResponseBody)
body.SetContainer(cnr)
meta := new(session.ResponseMetaHeader)
meta.SetTTL(1)
meta.SetXHeaders([]*session.XHeader{}) // w/o this require.Equal fails due to nil and []T{} difference
resp := new(container.GetResponse)
resp.SetBody(body)
resp.SetMetaHeader(meta)
return resp
}
func testDelRequest() *container.DeleteRequest {
cid := new(refs.ContainerID)
cid.SetValue([]byte{1, 2, 3})
body := new(container.DeleteRequestBody)
body.SetContainerID(cid)
meta := new(session.RequestMetaHeader)
meta.SetTTL(1)
req := new(container.DeleteRequest)
req.SetBody(body)
req.SetMetaHeader(meta)
return req
}
func testDelResponse() *container.DeleteResponse {
body := new(container.DeleteResponseBody)
meta := new(session.ResponseMetaHeader)
meta.SetTTL(1)
meta.SetXHeaders([]*session.XHeader{}) // w/o this require.Equal fails due to nil and []T{} difference
resp := new(container.DeleteResponse)
resp.SetBody(body)
resp.SetMetaHeader(meta)
return resp
}
func testListRequest() *container.ListRequest {
ownerID := new(refs.OwnerID)
ownerID.SetValue([]byte{1, 2, 3})
body := new(container.ListRequestBody)
body.SetOwnerID(ownerID)
meta := new(session.RequestMetaHeader)
meta.SetTTL(1)
req := new(container.ListRequest)
req.SetBody(body)
req.SetMetaHeader(meta)
return req
}
func testListResponse() *container.ListResponse {
cid := new(refs.ContainerID)
cid.SetValue([]byte{1, 2, 3})
body := new(container.ListResponseBody)
body.SetContainerIDs([]*refs.ContainerID{cid})
meta := new(session.ResponseMetaHeader)
meta.SetTTL(1)
meta.SetXHeaders([]*session.XHeader{}) // w/o this require.Equal fails due to nil and []T{} difference
resp := new(container.ListResponse)
resp.SetBody(body)
resp.SetMetaHeader(meta)
return resp
}
func testSetEACLRequest() *container.SetExtendedACLRequest {
cid := new(refs.ContainerID)
cid.SetValue([]byte{1, 2, 3})
eacl := new(acl.Table)
eacl.SetContainerID(cid)
body := new(container.SetExtendedACLRequestBody)
body.SetEACL(eacl)
meta := new(session.RequestMetaHeader)
meta.SetTTL(1)
req := new(container.SetExtendedACLRequest)
req.SetBody(body)
req.SetMetaHeader(meta)
return req
}
func testSetEACLResponse() *container.SetExtendedACLResponse {
body := new(container.SetExtendedACLResponseBody)
meta := new(session.ResponseMetaHeader)
meta.SetTTL(1)
meta.SetXHeaders([]*session.XHeader{}) // w/o this require.Equal fails due to nil and []T{} difference
resp := new(container.SetExtendedACLResponse)
resp.SetBody(body)
resp.SetMetaHeader(meta)
return resp
}
func testGetEACLRequest() *container.GetExtendedACLRequest {
cid := new(refs.ContainerID)
cid.SetValue([]byte{1, 2, 3})
body := new(container.GetExtendedACLRequestBody)
body.SetContainerID(cid)
meta := new(session.RequestMetaHeader)
meta.SetTTL(1)
req := new(container.GetExtendedACLRequest)
req.SetBody(body)
req.SetMetaHeader(meta)
return req
}
func testGetEACLResponse() *container.GetExtendedACLResponse {
cid := new(refs.ContainerID)
cid.SetValue([]byte{1, 2, 3})
eacl := new(acl.Table)
eacl.SetContainerID(cid)
eacl.SetRecords([]*acl.Record{}) // w/o this require.Equal fails due to nil and []T{} difference
body := new(container.GetExtendedACLResponseBody)
body.SetEACL(eacl)
meta := new(session.ResponseMetaHeader)
meta.SetTTL(1)
meta.SetXHeaders([]*session.XHeader{}) // w/o this require.Equal fails due to nil and []T{} difference
resp := new(container.GetExtendedACLResponse)
resp.SetBody(body)
resp.SetMetaHeader(meta)
return resp
}
func testAnnounceRequest() *container.AnnounceUsedSpaceRequest {
cid1 := new(refs.ContainerID)
cid1.SetValue([]byte{1, 2, 3})
cid2 := new(refs.ContainerID)
cid2.SetValue([]byte{4, 5, 6})
a1 := new(container.UsedSpaceAnnouncement)
a1.SetEpoch(20)
a1.SetUsedSpace(10)
a1.SetContainerID(cid1)
a2 := new(container.UsedSpaceAnnouncement)
a2.SetEpoch(20)
a2.SetUsedSpace(20)
a2.SetContainerID(cid2)
announcements := []*container.UsedSpaceAnnouncement{a1, a2}
body := new(container.AnnounceUsedSpaceRequestBody)
body.SetAnnouncements(announcements)
meta := new(session.RequestMetaHeader)
meta.SetTTL(1)
req := new(container.AnnounceUsedSpaceRequest)
req.SetBody(body)
req.SetMetaHeader(meta)
return req
}
func testAnnounceResponse() *container.AnnounceUsedSpaceResponse {
body := new(container.AnnounceUsedSpaceResponseBody)
meta := new(session.ResponseMetaHeader)
meta.SetTTL(1)
meta.SetXHeaders([]*session.XHeader{}) // w/o this require.Equal fails due to nil and []T{} difference
resp := new(container.AnnounceUsedSpaceResponse)
resp.SetBody(body)
resp.SetMetaHeader(meta)
return resp
}
func TestGRPCClient_Put(t *testing.T) {
ctx := context.TODO()
cliKey := test.DecodeKey(0)
srvKey := test.DecodeKey(1)
t.Run("gRPC server error", func(t *testing.T) {
srvErr := errors.New("test server error")
srv := &testGRPCServer{
err: srvErr,
}
cli := &testGRPCClient{
server: srv,
}
c, err := container.NewClient(container.WithGRPCServiceClient(cli))
require.NoError(t, err)
resp, err := c.Put(ctx, new(container.PutRequest))
require.True(t, errors.Is(err, srvErr))
require.Nil(t, resp)
})
t.Run("invalid request structure", func(t *testing.T) {
req := testPutRequest()
require.Error(t, signature.VerifyServiceMessage(req))
c, err := container.NewClient(
container.WithGRPCServiceClient(
&testGRPCClient{
server: new(testGRPCServer),
},
),
)
require.NoError(t, err)
resp, err := c.Put(ctx, req)
require.Error(t, err)
require.Nil(t, resp)
})
t.Run("correct response", func(t *testing.T) {
req := testPutRequest()
require.NoError(t, signature.SignServiceMessage(cliKey, req))
resp := testPutResponse()
c, err := container.NewClient(
container.WithGRPCServiceClient(
&testGRPCClient{
server: &testGRPCServer{
key: srvKey,
putResp: resp,
},
},
),
)
require.NoError(t, err)
r, err := c.Put(ctx, req)
require.NoError(t, err)
require.NoError(t, signature.VerifyServiceMessage(r))
require.Equal(t, resp.GetBody(), r.GetBody())
require.Equal(t, resp.GetMetaHeader(), r.GetMetaHeader())
})
}
func TestGRPCClient_Get(t *testing.T) {
ctx := context.TODO()
cliKey := test.DecodeKey(0)
srvKey := test.DecodeKey(1)
t.Run("gRPC server error", func(t *testing.T) {
srvErr := errors.New("test server error")
srv := &testGRPCServer{
err: srvErr,
}
cli := &testGRPCClient{
server: srv,
}
c, err := container.NewClient(container.WithGRPCServiceClient(cli))
require.NoError(t, err)
resp, err := c.Get(ctx, new(container.GetRequest))
require.True(t, errors.Is(err, srvErr))
require.Nil(t, resp)
})
t.Run("invalid request structure", func(t *testing.T) {
req := testGetRequest()
require.Error(t, signature.VerifyServiceMessage(req))
c, err := container.NewClient(
container.WithGRPCServiceClient(
&testGRPCClient{
server: new(testGRPCServer),
},
),
)
require.NoError(t, err)
resp, err := c.Get(ctx, req)
require.Error(t, err)
require.Nil(t, resp)
})
t.Run("correct response", func(t *testing.T) {
req := testGetRequest()
require.NoError(t, signature.SignServiceMessage(cliKey, req))
resp := testGetResponse()
c, err := container.NewClient(
container.WithGRPCServiceClient(
&testGRPCClient{
server: &testGRPCServer{
key: srvKey,
getResp: resp,
},
},
),
)
require.NoError(t, err)
r, err := c.Get(ctx, req)
require.NoError(t, err)
require.NoError(t, signature.VerifyServiceMessage(r))
require.Equal(t, resp.GetBody(), r.GetBody())
require.Equal(t, resp.GetMetaHeader(), r.GetMetaHeader())
})
}
func TestGRPCClient_Delete(t *testing.T) {
ctx := context.TODO()
cliKey := test.DecodeKey(0)
srvKey := test.DecodeKey(1)
t.Run("gRPC server error", func(t *testing.T) {
srvErr := errors.New("test server error")
srv := &testGRPCServer{
err: srvErr,
}
cli := &testGRPCClient{
server: srv,
}
c, err := container.NewClient(container.WithGRPCServiceClient(cli))
require.NoError(t, err)
resp, err := c.Delete(ctx, new(container.DeleteRequest))
require.True(t, errors.Is(err, srvErr))
require.Nil(t, resp)
})
t.Run("invalid request structure", func(t *testing.T) {
req := testDelRequest()
require.Error(t, signature.VerifyServiceMessage(req))
c, err := container.NewClient(
container.WithGRPCServiceClient(
&testGRPCClient{
server: new(testGRPCServer),
},
),
)
require.NoError(t, err)
resp, err := c.Delete(ctx, req)
require.Error(t, err)
require.Nil(t, resp)
})
t.Run("correct response", func(t *testing.T) {
req := testDelRequest()
require.NoError(t, signature.SignServiceMessage(cliKey, req))
resp := testDelResponse()
c, err := container.NewClient(
container.WithGRPCServiceClient(
&testGRPCClient{
server: &testGRPCServer{
key: srvKey,
delResp: resp,
},
},
),
)
require.NoError(t, err)
r, err := c.Delete(ctx, req)
require.NoError(t, err)
require.NoError(t, signature.VerifyServiceMessage(r))
require.Equal(t, resp.GetBody(), r.GetBody())
require.Equal(t, resp.GetMetaHeader(), r.GetMetaHeader())
})
}
func TestGRPCClient_List(t *testing.T) {
ctx := context.TODO()
cliKey := test.DecodeKey(0)
srvKey := test.DecodeKey(1)
t.Run("gRPC server error", func(t *testing.T) {
srvErr := errors.New("test server error")
srv := &testGRPCServer{
err: srvErr,
}
cli := &testGRPCClient{
server: srv,
}
c, err := container.NewClient(container.WithGRPCServiceClient(cli))
require.NoError(t, err)
resp, err := c.List(ctx, new(container.ListRequest))
require.True(t, errors.Is(err, srvErr))
require.Nil(t, resp)
})
t.Run("invalid request structure", func(t *testing.T) {
req := testListRequest()
require.Error(t, signature.VerifyServiceMessage(req))
c, err := container.NewClient(
container.WithGRPCServiceClient(
&testGRPCClient{
server: new(testGRPCServer),
},
),
)
require.NoError(t, err)
resp, err := c.List(ctx, req)
require.Error(t, err)
require.Nil(t, resp)
})
t.Run("correct response", func(t *testing.T) {
req := testListRequest()
require.NoError(t, signature.SignServiceMessage(cliKey, req))
resp := testListResponse()
c, err := container.NewClient(
container.WithGRPCServiceClient(
&testGRPCClient{
server: &testGRPCServer{
key: srvKey,
listResp: resp,
},
},
),
)
require.NoError(t, err)
r, err := c.List(ctx, req)
require.NoError(t, err)
require.NoError(t, signature.VerifyServiceMessage(r))
require.Equal(t, resp.GetBody(), r.GetBody())
require.Equal(t, resp.GetMetaHeader(), r.GetMetaHeader())
})
}
func TestGRPCClient_SetEACL(t *testing.T) {
ctx := context.TODO()
cliKey := test.DecodeKey(0)
srvKey := test.DecodeKey(1)
t.Run("gRPC server error", func(t *testing.T) {
srvErr := errors.New("test server error")
srv := &testGRPCServer{
err: srvErr,
}
cli := &testGRPCClient{
server: srv,
}
c, err := container.NewClient(container.WithGRPCServiceClient(cli))
require.NoError(t, err)
resp, err := c.SetExtendedACL(ctx, new(container.SetExtendedACLRequest))
require.True(t, errors.Is(err, srvErr))
require.Nil(t, resp)
})
t.Run("invalid request structure", func(t *testing.T) {
req := testSetEACLRequest()
require.Error(t, signature.VerifyServiceMessage(req))
c, err := container.NewClient(
container.WithGRPCServiceClient(
&testGRPCClient{
server: new(testGRPCServer),
},
),
)
require.NoError(t, err)
resp, err := c.SetExtendedACL(ctx, req)
require.Error(t, err)
require.Nil(t, resp)
})
t.Run("correct response", func(t *testing.T) {
req := testSetEACLRequest()
require.NoError(t, signature.SignServiceMessage(cliKey, req))
resp := testSetEACLResponse()
c, err := container.NewClient(
container.WithGRPCServiceClient(
&testGRPCClient{
server: &testGRPCServer{
key: srvKey,
sEaclResp: resp,
},
},
),
)
require.NoError(t, err)
r, err := c.SetExtendedACL(ctx, req)
require.NoError(t, err)
require.NoError(t, signature.VerifyServiceMessage(r))
require.Equal(t, resp.GetBody(), r.GetBody())
require.Equal(t, resp.GetMetaHeader(), r.GetMetaHeader())
})
}
func TestGRPCClient_GetEACL(t *testing.T) {
ctx := context.TODO()
cliKey := test.DecodeKey(0)
srvKey := test.DecodeKey(1)
t.Run("gRPC server error", func(t *testing.T) {
srvErr := errors.New("test server error")
srv := &testGRPCServer{
err: srvErr,
}
cli := &testGRPCClient{
server: srv,
}
c, err := container.NewClient(container.WithGRPCServiceClient(cli))
require.NoError(t, err)
resp, err := c.GetExtendedACL(ctx, new(container.GetExtendedACLRequest))
require.True(t, errors.Is(err, srvErr))
require.Nil(t, resp)
})
t.Run("invalid request structure", func(t *testing.T) {
req := testGetEACLRequest()
require.Error(t, signature.VerifyServiceMessage(req))
c, err := container.NewClient(
container.WithGRPCServiceClient(
&testGRPCClient{
server: new(testGRPCServer),
},
),
)
require.NoError(t, err)
resp, err := c.GetExtendedACL(ctx, req)
require.Error(t, err)
require.Nil(t, resp)
})
t.Run("correct response", func(t *testing.T) {
req := testGetEACLRequest()
require.NoError(t, signature.SignServiceMessage(cliKey, req))
resp := testGetEACLResponse()
c, err := container.NewClient(
container.WithGRPCServiceClient(
&testGRPCClient{
server: &testGRPCServer{
key: srvKey,
gEaclResp: resp,
},
},
),
)
require.NoError(t, err)
r, err := c.GetExtendedACL(ctx, req)
require.NoError(t, err)
require.NoError(t, signature.VerifyServiceMessage(r))
require.Equal(t, resp.GetBody(), r.GetBody())
require.Equal(t, resp.GetMetaHeader(), r.GetMetaHeader())
})
}
func TestGRPCClient_AnnounceUsedSpace(t *testing.T) {
ctx := context.TODO()
cliKey := test.DecodeKey(0)
srvKey := test.DecodeKey(1)
t.Run("gRPC server error", func(t *testing.T) {
srvErr := errors.New("test server error")
srv := &testGRPCServer{
err: srvErr,
}
cli := &testGRPCClient{
server: srv,
}
c, err := container.NewClient(container.WithGRPCServiceClient(cli))
require.NoError(t, err)
resp, err := c.AnnounceUsedSpace(ctx, new(container.AnnounceUsedSpaceRequest))
require.True(t, errors.Is(err, srvErr))
require.Nil(t, resp)
})
t.Run("invalid request structure", func(t *testing.T) {
req := testAnnounceRequest()
require.Error(t, signature.VerifyServiceMessage(req))
c, err := container.NewClient(
container.WithGRPCServiceClient(
&testGRPCClient{
server: new(testGRPCServer),
},
),
)
require.NoError(t, err)
resp, err := c.AnnounceUsedSpace(ctx, req)
require.Error(t, err)
require.Nil(t, resp)
})
t.Run("correct response", func(t *testing.T) {
req := testAnnounceRequest()
require.NoError(t, signature.SignServiceMessage(cliKey, req))
resp := testAnnounceResponse()
c, err := container.NewClient(
container.WithGRPCServiceClient(
&testGRPCClient{
server: &testGRPCServer{
key: srvKey,
announceResp: resp,
},
},
),
)
require.NoError(t, err)
r, err := c.AnnounceUsedSpace(ctx, req)
require.NoError(t, err)
require.NoError(t, signature.VerifyServiceMessage(r))
require.Equal(t, resp.GetBody(), r.GetBody())
require.Equal(t, resp.GetMetaHeader(), r.GetMetaHeader())
})
}

View file

@ -0,0 +1,318 @@
package containertest
import (
acltest "github.com/nspcc-dev/neofs-api-go/v2/acl/test"
"github.com/nspcc-dev/neofs-api-go/v2/container"
netmaptest "github.com/nspcc-dev/neofs-api-go/v2/netmap/test"
refstest "github.com/nspcc-dev/neofs-api-go/v2/refs/test"
sessiontest "github.com/nspcc-dev/neofs-api-go/v2/session/test"
)
func GenerateAttribute(empty bool) *container.Attribute {
m := new(container.Attribute)
if !empty {
m.SetKey("key")
m.SetValue("val")
}
return m
}
func GenerateAttributes(empty bool) (res []*container.Attribute) {
if !empty {
res = append(res,
GenerateAttribute(false),
GenerateAttribute(false),
)
}
return
}
func GenerateContainer(empty bool) *container.Container {
m := new(container.Container)
if !empty {
m.SetBasicACL(12)
m.SetNonce([]byte{1, 2, 3})
}
m.SetOwnerID(refstest.GenerateOwnerID(empty))
m.SetVersion(refstest.GenerateVersion(empty))
m.SetAttributes(GenerateAttributes(empty))
m.SetPlacementPolicy(netmaptest.GeneratePlacementPolicy(empty))
return m
}
func GeneratePutRequestBody(empty bool) *container.PutRequestBody {
m := new(container.PutRequestBody)
m.SetContainer(GenerateContainer(empty))
m.SetSignature(refstest.GenerateSignature(empty))
return m
}
func GeneratePutRequest(empty bool) *container.PutRequest {
m := new(container.PutRequest)
m.SetBody(GeneratePutRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GeneratePutResponseBody(empty bool) *container.PutResponseBody {
m := new(container.PutResponseBody)
m.SetContainerID(refstest.GenerateContainerID(empty))
return m
}
func GeneratePutResponse(empty bool) *container.PutResponse {
m := new(container.PutResponse)
m.SetBody(GeneratePutResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateGetRequestBody(empty bool) *container.GetRequestBody {
m := new(container.GetRequestBody)
m.SetContainerID(refstest.GenerateContainerID(empty))
return m
}
func GenerateGetRequest(empty bool) *container.GetRequest {
m := new(container.GetRequest)
m.SetBody(GenerateGetRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateGetResponseBody(empty bool) *container.GetResponseBody {
m := new(container.GetResponseBody)
m.SetContainer(GenerateContainer(empty))
return m
}
func GenerateGetResponse(empty bool) *container.GetResponse {
m := new(container.GetResponse)
m.SetBody(GenerateGetResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateDeleteRequestBody(empty bool) *container.DeleteRequestBody {
m := new(container.DeleteRequestBody)
m.SetContainerID(refstest.GenerateContainerID(empty))
m.SetSignature(refstest.GenerateSignature(empty))
return m
}
func GenerateDeleteRequest(empty bool) *container.DeleteRequest {
m := new(container.DeleteRequest)
m.SetBody(GenerateDeleteRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateDeleteResponseBody(empty bool) *container.DeleteResponseBody {
m := new(container.DeleteResponseBody)
return m
}
func GenerateDeleteResponse(empty bool) *container.DeleteResponse {
m := new(container.DeleteResponse)
m.SetBody(GenerateDeleteResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateListRequestBody(empty bool) *container.ListRequestBody {
m := new(container.ListRequestBody)
m.SetOwnerID(refstest.GenerateOwnerID(empty))
return m
}
func GenerateListRequest(empty bool) *container.ListRequest {
m := new(container.ListRequest)
m.SetBody(GenerateListRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateListResponseBody(empty bool) *container.ListResponseBody {
m := new(container.ListResponseBody)
m.SetContainerIDs(refstest.GenerateContainerIDs(empty))
return m
}
func GenerateListResponse(empty bool) *container.ListResponse {
m := new(container.ListResponse)
m.SetBody(GenerateListResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateSetExtendedACLRequestBody(empty bool) *container.SetExtendedACLRequestBody {
m := new(container.SetExtendedACLRequestBody)
m.SetEACL(acltest.GenerateTable(empty))
m.SetSignature(refstest.GenerateSignature(empty))
return m
}
func GenerateSetExtendedACLRequest(empty bool) *container.SetExtendedACLRequest {
m := new(container.SetExtendedACLRequest)
m.SetBody(GenerateSetExtendedACLRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateSetExtendedACLResponseBody(empty bool) *container.SetExtendedACLResponseBody {
m := new(container.SetExtendedACLResponseBody)
return m
}
func GenerateSetExtendedACLResponse(empty bool) *container.SetExtendedACLResponse {
m := new(container.SetExtendedACLResponse)
m.SetBody(GenerateSetExtendedACLResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateGetExtendedACLRequestBody(empty bool) *container.GetExtendedACLRequestBody {
m := new(container.GetExtendedACLRequestBody)
m.SetContainerID(refstest.GenerateContainerID(empty))
return m
}
func GenerateGetExtendedACLRequest(empty bool) *container.GetExtendedACLRequest {
m := new(container.GetExtendedACLRequest)
m.SetBody(GenerateGetExtendedACLRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateGetExtendedACLResponseBody(empty bool) *container.GetExtendedACLResponseBody {
m := new(container.GetExtendedACLResponseBody)
m.SetEACL(acltest.GenerateTable(empty))
m.SetSignature(refstest.GenerateSignature(empty))
return m
}
func GenerateGetExtendedACLResponse(empty bool) *container.GetExtendedACLResponse {
m := new(container.GetExtendedACLResponse)
m.SetBody(GenerateGetExtendedACLResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateUsedSpaceAnnouncement(empty bool) *container.UsedSpaceAnnouncement {
m := new(container.UsedSpaceAnnouncement)
m.SetContainerID(refstest.GenerateContainerID(empty))
m.SetEpoch(1)
m.SetUsedSpace(2)
return m
}
func GenerateUsedSpaceAnnouncements(empty bool) (res []*container.UsedSpaceAnnouncement) {
if !empty {
res = append(res,
GenerateUsedSpaceAnnouncement(false),
GenerateUsedSpaceAnnouncement(false),
)
}
return
}
func GenerateAnnounceUsedSpaceRequestBody(empty bool) *container.AnnounceUsedSpaceRequestBody {
m := new(container.AnnounceUsedSpaceRequestBody)
m.SetAnnouncements(GenerateUsedSpaceAnnouncements(empty))
return m
}
func GenerateAnnounceUsedSpaceRequest(empty bool) *container.AnnounceUsedSpaceRequest {
m := new(container.AnnounceUsedSpaceRequest)
m.SetBody(GenerateAnnounceUsedSpaceRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateAnnounceUsedSpaceResponseBody(empty bool) *container.AnnounceUsedSpaceResponseBody {
m := new(container.AnnounceUsedSpaceResponseBody)
return m
}
func GenerateAnnounceUsedSpaceResponse(empty bool) *container.AnnounceUsedSpaceResponse {
m := new(container.AnnounceUsedSpaceResponse)
m.SetBody(GenerateAnnounceUsedSpaceResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}

View file

@ -30,11 +30,22 @@ type PutRequestBody struct {
sig *refs.Signature sig *refs.Signature
} }
type PutRequest struct {
body *PutRequestBody
session.RequestHeaders
}
type PutResponseBody struct { type PutResponseBody struct {
cid *refs.ContainerID cid *refs.ContainerID
} }
type PutResponse struct {
body *PutResponseBody
session.ResponseHeaders
}
type GetRequestBody struct { type GetRequestBody struct {
cid *refs.ContainerID cid *refs.ContainerID
} }
@ -42,9 +53,7 @@ type GetRequestBody struct {
type GetRequest struct { type GetRequest struct {
body *GetRequestBody body *GetRequestBody
metaHeader *session.RequestMetaHeader session.RequestHeaders
verifyHeader *session.RequestVerificationHeader
} }
type GetResponseBody struct { type GetResponseBody struct {
@ -54,9 +63,7 @@ type GetResponseBody struct {
type GetResponse struct { type GetResponse struct {
body *GetResponseBody body *GetResponseBody
metaHeader *session.ResponseMetaHeader session.ResponseHeaders
verifyHeader *session.ResponseVerificationHeader
} }
type DeleteRequestBody struct { type DeleteRequestBody struct {
@ -65,34 +72,82 @@ type DeleteRequestBody struct {
sig *refs.Signature sig *refs.Signature
} }
type DeleteRequest struct {
body *DeleteRequestBody
session.RequestHeaders
}
type DeleteResponseBody struct{} type DeleteResponseBody struct{}
type DeleteResponse struct {
body *DeleteResponseBody
session.ResponseHeaders
}
type ListRequestBody struct { type ListRequestBody struct {
ownerID *refs.OwnerID ownerID *refs.OwnerID
} }
type ListRequest struct {
body *ListRequestBody
session.RequestHeaders
}
type ListResponseBody struct { type ListResponseBody struct {
cidList []*refs.ContainerID cidList []*refs.ContainerID
} }
type ListResponse struct {
body *ListResponseBody
session.ResponseHeaders
}
type SetExtendedACLRequestBody struct { type SetExtendedACLRequestBody struct {
eacl *acl.Table eacl *acl.Table
sig *refs.Signature sig *refs.Signature
} }
type SetExtendedACLRequest struct {
body *SetExtendedACLRequestBody
session.RequestHeaders
}
type SetExtendedACLResponseBody struct{} type SetExtendedACLResponseBody struct{}
type SetExtendedACLResponse struct {
body *SetExtendedACLResponseBody
session.ResponseHeaders
}
type GetExtendedACLRequestBody struct { type GetExtendedACLRequestBody struct {
cid *refs.ContainerID cid *refs.ContainerID
} }
type GetExtendedACLRequest struct {
body *GetExtendedACLRequestBody
session.RequestHeaders
}
type GetExtendedACLResponseBody struct { type GetExtendedACLResponseBody struct {
eacl *acl.Table eacl *acl.Table
sig *refs.Signature sig *refs.Signature
} }
type GetExtendedACLResponse struct {
body *GetExtendedACLResponseBody
session.ResponseHeaders
}
type UsedSpaceAnnouncement struct { type UsedSpaceAnnouncement struct {
epoch uint64 epoch uint64
@ -105,8 +160,20 @@ type AnnounceUsedSpaceRequestBody struct {
announcements []*UsedSpaceAnnouncement announcements []*UsedSpaceAnnouncement
} }
type AnnounceUsedSpaceRequest struct {
body *AnnounceUsedSpaceRequestBody
session.RequestHeaders
}
type AnnounceUsedSpaceResponseBody struct{} type AnnounceUsedSpaceResponseBody struct{}
type AnnounceUsedSpaceResponse struct {
body *AnnounceUsedSpaceResponseBody
session.ResponseHeaders
}
func (a *Attribute) GetKey() string { func (a *Attribute) GetKey() string {
if a != nil { if a != nil {
return a.key return a.key
@ -261,34 +328,6 @@ func (r *PutRequest) SetBody(v *PutRequestBody) {
} }
} }
func (r *PutRequest) GetMetaHeader() *session.RequestMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *PutRequest) SetMetaHeader(v *session.RequestMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *PutRequest) GetVerificationHeader() *session.RequestVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *PutRequest) SetVerificationHeader(v *session.RequestVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *PutResponseBody) GetContainerID() *refs.ContainerID { func (r *PutResponseBody) GetContainerID() *refs.ContainerID {
if r != nil { if r != nil {
return r.cid return r.cid
@ -317,34 +356,6 @@ func (r *PutResponse) SetBody(v *PutResponseBody) {
} }
} }
func (r *PutResponse) GetMetaHeader() *session.ResponseMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *PutResponse) SetMetaHeader(v *session.ResponseMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *PutResponse) GetVerificationHeader() *session.ResponseVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *PutResponse) SetVerificationHeader(v *session.ResponseVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *GetRequestBody) GetContainerID() *refs.ContainerID { func (r *GetRequestBody) GetContainerID() *refs.ContainerID {
if r != nil { if r != nil {
return r.cid return r.cid
@ -373,34 +384,6 @@ func (r *GetRequest) SetBody(v *GetRequestBody) {
} }
} }
func (r *GetRequest) GetMetaHeader() *session.RequestMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *GetRequest) SetMetaHeader(v *session.RequestMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *GetRequest) GetVerificationHeader() *session.RequestVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *GetRequest) SetVerificationHeader(v *session.RequestVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *GetResponseBody) GetContainer() *Container { func (r *GetResponseBody) GetContainer() *Container {
if r != nil { if r != nil {
return r.cnr return r.cnr
@ -429,34 +412,6 @@ func (r *GetResponse) SetBody(v *GetResponseBody) {
} }
} }
func (r *GetResponse) GetMetaHeader() *session.ResponseMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *GetResponse) SetMetaHeader(v *session.ResponseMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *GetResponse) GetVerificationHeader() *session.ResponseVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *GetResponse) SetVerificationHeader(v *session.ResponseVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *DeleteRequestBody) GetContainerID() *refs.ContainerID { func (r *DeleteRequestBody) GetContainerID() *refs.ContainerID {
if r != nil { if r != nil {
return r.cid return r.cid
@ -499,34 +454,6 @@ func (r *DeleteRequest) SetBody(v *DeleteRequestBody) {
} }
} }
func (r *DeleteRequest) GetMetaHeader() *session.RequestMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *DeleteRequest) SetMetaHeader(v *session.RequestMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *DeleteRequest) GetVerificationHeader() *session.RequestVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *DeleteRequest) SetVerificationHeader(v *session.RequestVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *DeleteResponse) GetBody() *DeleteResponseBody { func (r *DeleteResponse) GetBody() *DeleteResponseBody {
if r != nil { if r != nil {
return r.body return r.body
@ -541,34 +468,6 @@ func (r *DeleteResponse) SetBody(v *DeleteResponseBody) {
} }
} }
func (r *DeleteResponse) GetMetaHeader() *session.ResponseMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *DeleteResponse) SetMetaHeader(v *session.ResponseMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *DeleteResponse) GetVerificationHeader() *session.ResponseVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *DeleteResponse) SetVerificationHeader(v *session.ResponseVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *ListRequestBody) GetOwnerID() *refs.OwnerID { func (r *ListRequestBody) GetOwnerID() *refs.OwnerID {
if r != nil { if r != nil {
return r.ownerID return r.ownerID
@ -597,34 +496,6 @@ func (r *ListRequest) SetBody(v *ListRequestBody) {
} }
} }
func (r *ListRequest) GetMetaHeader() *session.RequestMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *ListRequest) SetMetaHeader(v *session.RequestMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *ListRequest) GetVerificationHeader() *session.RequestVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *ListRequest) SetVerificationHeader(v *session.RequestVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *ListResponseBody) GetContainerIDs() []*refs.ContainerID { func (r *ListResponseBody) GetContainerIDs() []*refs.ContainerID {
if r != nil { if r != nil {
return r.cidList return r.cidList
@ -653,34 +524,6 @@ func (r *ListResponse) SetBody(v *ListResponseBody) {
} }
} }
func (r *ListResponse) GetMetaHeader() *session.ResponseMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *ListResponse) SetMetaHeader(v *session.ResponseMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *ListResponse) GetVerificationHeader() *session.ResponseVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *ListResponse) SetVerificationHeader(v *session.ResponseVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *SetExtendedACLRequestBody) GetEACL() *acl.Table { func (r *SetExtendedACLRequestBody) GetEACL() *acl.Table {
if r != nil { if r != nil {
return r.eacl return r.eacl
@ -723,34 +566,6 @@ func (r *SetExtendedACLRequest) SetBody(v *SetExtendedACLRequestBody) {
} }
} }
func (r *SetExtendedACLRequest) GetMetaHeader() *session.RequestMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *SetExtendedACLRequest) SetMetaHeader(v *session.RequestMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *SetExtendedACLRequest) GetVerificationHeader() *session.RequestVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *SetExtendedACLRequest) SetVerificationHeader(v *session.RequestVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *SetExtendedACLResponse) GetBody() *SetExtendedACLResponseBody { func (r *SetExtendedACLResponse) GetBody() *SetExtendedACLResponseBody {
if r != nil { if r != nil {
return r.body return r.body
@ -765,34 +580,6 @@ func (r *SetExtendedACLResponse) SetBody(v *SetExtendedACLResponseBody) {
} }
} }
func (r *SetExtendedACLResponse) GetMetaHeader() *session.ResponseMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *SetExtendedACLResponse) SetMetaHeader(v *session.ResponseMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *SetExtendedACLResponse) GetVerificationHeader() *session.ResponseVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *SetExtendedACLResponse) SetVerificationHeader(v *session.ResponseVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *GetExtendedACLRequestBody) GetContainerID() *refs.ContainerID { func (r *GetExtendedACLRequestBody) GetContainerID() *refs.ContainerID {
if r != nil { if r != nil {
return r.cid return r.cid
@ -821,34 +608,6 @@ func (r *GetExtendedACLRequest) SetBody(v *GetExtendedACLRequestBody) {
} }
} }
func (r *GetExtendedACLRequest) GetMetaHeader() *session.RequestMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *GetExtendedACLRequest) SetMetaHeader(v *session.RequestMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *GetExtendedACLRequest) GetVerificationHeader() *session.RequestVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *GetExtendedACLRequest) SetVerificationHeader(v *session.RequestVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *GetExtendedACLResponseBody) GetEACL() *acl.Table { func (r *GetExtendedACLResponseBody) GetEACL() *acl.Table {
if r != nil { if r != nil {
return r.eacl return r.eacl
@ -891,34 +650,6 @@ func (r *GetExtendedACLResponse) SetBody(v *GetExtendedACLResponseBody) {
} }
} }
func (r *GetExtendedACLResponse) GetMetaHeader() *session.ResponseMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *GetExtendedACLResponse) SetMetaHeader(v *session.ResponseMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *GetExtendedACLResponse) GetVerificationHeader() *session.ResponseVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *GetExtendedACLResponse) SetVerificationHeader(v *session.ResponseVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (a *UsedSpaceAnnouncement) GetEpoch() uint64 { func (a *UsedSpaceAnnouncement) GetEpoch() uint64 {
if a != nil { if a != nil {
return a.epoch return a.epoch
@ -989,34 +720,6 @@ func (r *AnnounceUsedSpaceRequest) SetBody(v *AnnounceUsedSpaceRequestBody) {
} }
} }
func (r *AnnounceUsedSpaceRequest) GetMetaHeader() *session.RequestMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *AnnounceUsedSpaceRequest) SetMetaHeader(v *session.RequestMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *AnnounceUsedSpaceRequest) GetVerificationHeader() *session.RequestVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *AnnounceUsedSpaceRequest) SetVerificationHeader(v *session.RequestVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *AnnounceUsedSpaceResponse) GetBody() *AnnounceUsedSpaceResponseBody { func (r *AnnounceUsedSpaceResponse) GetBody() *AnnounceUsedSpaceResponseBody {
if r != nil { if r != nil {
return r.body return r.body
@ -1030,31 +733,3 @@ func (r *AnnounceUsedSpaceResponse) SetBody(v *AnnounceUsedSpaceResponseBody) {
r.body = v r.body = v
} }
} }
func (r *AnnounceUsedSpaceResponse) GetMetaHeader() *session.ResponseMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *AnnounceUsedSpaceResponse) SetMetaHeader(v *session.ResponseMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *AnnounceUsedSpaceResponse) GetVerificationHeader() *session.ResponseVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *AnnounceUsedSpaceResponse) SetVerificationHeader(v *session.ResponseVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}

View file

@ -1,190 +0,0 @@
package netmap
import (
"context"
"github.com/nspcc-dev/neofs-api-go/v2/client"
netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc"
"github.com/pkg/errors"
"google.golang.org/grpc"
)
// Client represents universal netmap transport client.
type Client struct {
cLocalNodeInfo *localNodeInfoClient
cNetworkInfo *networkInfoClient
}
// Option represents Client option.
type Option func(*cfg)
type cfg struct {
proto client.Protocol
globalOpts []client.Option
gRPC cfgGRPC
}
type cfgGRPC struct {
serviceClient netmap.NetmapServiceClient
grpcCallOpts []grpc.CallOption
callOpts []netmap.Option
client *netmap.Client
}
type localNodeInfoClient struct {
requestConverter func(*LocalNodeInfoRequest) interface{}
caller func(context.Context, interface{}) (interface{}, error)
responseConverter func(interface{}) *LocalNodeInfoResponse
}
type networkInfoClient struct {
requestConverter func(*NetworkInfoRequest) interface{}
caller func(context.Context, interface{}) (interface{}, error)
responseConverter func(interface{}) *NetworkInfoResponse
}
// LocalNodeInfo sends LocalNodeInfoRequest over the network.
func (c *Client) LocalNodeInfo(ctx context.Context, req *LocalNodeInfoRequest) (*LocalNodeInfoResponse, error) {
resp, err := c.cLocalNodeInfo.caller(ctx, c.cLocalNodeInfo.requestConverter(req))
if err != nil {
return nil, errors.Wrap(err, "could not send local node info request")
}
return c.cLocalNodeInfo.responseConverter(resp), nil
}
// NetworkInfo sends NetworkInfoRequest over the network.
func (c *Client) NetworkInfo(ctx context.Context, req *NetworkInfoRequest) (*NetworkInfoResponse, error) {
resp, err := c.cNetworkInfo.caller(ctx, c.cNetworkInfo.requestConverter(req))
if err != nil {
return nil, errors.Wrap(err, "could not send network info request")
}
return c.cNetworkInfo.responseConverter(resp), nil
}
func defaultCfg() *cfg {
return &cfg{
proto: client.ProtoGRPC,
}
}
// NewClient is a constructor for netmap transport client.
func NewClient(opts ...Option) (*Client, error) {
cfg := defaultCfg()
for i := range opts {
opts[i](cfg)
}
var err error
switch cfg.proto {
case client.ProtoGRPC:
var c *netmap.Client
if c, err = newGRPCClient(cfg); err != nil {
break
}
return &Client{
cLocalNodeInfo: &localNodeInfoClient{
requestConverter: func(req *LocalNodeInfoRequest) interface{} {
return LocalNodeInfoRequestToGRPCMessage(req)
},
caller: func(ctx context.Context, req interface{}) (interface{}, error) {
return c.LocalNodeInfo(ctx, req.(*netmap.LocalNodeInfoRequest))
},
responseConverter: func(resp interface{}) *LocalNodeInfoResponse {
return LocalNodeInfoResponseFromGRPCMessage(resp.(*netmap.LocalNodeInfoResponse))
},
},
cNetworkInfo: &networkInfoClient{
requestConverter: func(req *NetworkInfoRequest) interface{} {
return NetworkInfoRequestToGRPCMessage(req)
},
caller: func(ctx context.Context, req interface{}) (interface{}, error) {
return c.NetworkInfo(ctx, req.(*netmap.NetworkInfoRequest))
},
responseConverter: func(resp interface{}) *NetworkInfoResponse {
return NetworkInfoResponseFromGRPCMessage(resp.(*netmap.NetworkInfoResponse))
},
},
}, nil
default:
err = client.ErrProtoUnsupported
}
return nil, errors.Wrapf(err, "could not create %s Netmap client", cfg.proto)
}
func newGRPCClient(cfg *cfg) (*netmap.Client, error) {
var err error
if cfg.gRPC.client == nil {
if cfg.gRPC.serviceClient == nil {
conn, err := client.NewGRPCClientConn(cfg.globalOpts...)
if err != nil {
return nil, errors.Wrap(err, "could not open gRPC client connection")
}
cfg.gRPC.serviceClient = netmap.NewNetmapServiceClient(conn)
}
cfg.gRPC.client, err = netmap.NewClient(
cfg.gRPC.serviceClient,
append(
cfg.gRPC.callOpts,
netmap.WithCallOptions(cfg.gRPC.grpcCallOpts),
)...,
)
}
return cfg.gRPC.client, err
}
// WithGlobalOpts sets global client options to client.
func WithGlobalOpts(v ...client.Option) Option {
return func(c *cfg) {
if len(v) > 0 {
c.globalOpts = v
}
}
}
// WithGRPCServiceClient sets existing service client.
func WithGRPCServiceClient(v netmap.NetmapServiceClient) Option {
return func(c *cfg) {
c.gRPC.serviceClient = v
}
}
// WithGRPCServiceClient sets GRPC specific call options.
func WithGRPCCallOpts(v []grpc.CallOption) Option {
return func(c *cfg) {
c.gRPC.grpcCallOpts = v
}
}
// WithGRPCServiceClient sets GRPC specific client options.
func WithGRPCClientOpts(v []netmap.Option) Option {
return func(c *cfg) {
c.gRPC.callOpts = v
}
}
// WithGRPCServiceClient sets existing GRPC client.
func WithGRPCClient(v *netmap.Client) Option {
return func(c *cfg) {
c.gRPC.client = v
}
}

View file

@ -1,167 +1,252 @@
package netmap package netmap
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/grpc"
"github.com/nspcc-dev/neofs-api-go/rpc/message"
netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc" netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-api-go/v2/session" refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
) )
func FilterToGRPCMessage(f *Filter) *netmap.Filter { func (f *Filter) ToGRPCMessage() grpc.Message {
if f == nil { var m *netmap.Filter
return nil
if f != nil {
m = new(netmap.Filter)
m.SetKey(f.key)
m.SetValue(f.value)
m.SetName(f.name)
m.SetOp(OperationToGRPCMessage(f.op))
m.SetFilters(FiltersToGRPC(f.filters))
} }
m := new(netmap.Filter)
m.SetName(f.GetName())
m.SetKey(f.GetKey())
m.SetValue(f.GetValue())
m.SetOp(OperationToGRPCMessage(f.GetOp()))
filters := make([]*netmap.Filter, 0, len(f.GetFilters()))
for _, filter := range f.GetFilters() {
filters = append(filters, FilterToGRPCMessage(filter))
}
m.SetFilters(filters)
return m return m
} }
func FilterFromGRPCMessage(m *netmap.Filter) *Filter { func (f *Filter) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*netmap.Filter)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
f.filters, err = FiltersFromGRPC(v.GetFilters())
if err != nil {
return err
}
f.key = v.GetKey()
f.value = v.GetValue()
f.name = v.GetName()
f.op = OperationFromGRPCMessage(v.GetOp())
return nil return nil
}
f := new(Filter)
f.SetName(m.GetName())
f.SetKey(m.GetKey())
f.SetValue(m.GetValue())
f.SetOp(OperationFromGRPCMessage(m.GetOp()))
filters := make([]*Filter, 0, len(f.GetFilters()))
for _, filter := range m.GetFilters() {
filters = append(filters, FilterFromGRPCMessage(filter))
}
f.SetFilters(filters)
return f
} }
func SelectorToGRPCMessage(s *Selector) *netmap.Selector { func FiltersToGRPC(fs []*Filter) (res []*netmap.Filter) {
if s == nil { if fs != nil {
return nil res = make([]*netmap.Filter, 0, len(fs))
for i := range fs {
res = append(res, fs[i].ToGRPCMessage().(*netmap.Filter))
}
} }
m := new(netmap.Selector) return
}
m.SetName(s.GetName()) func FiltersFromGRPC(fs []*netmap.Filter) (res []*Filter, err error) {
m.SetCount(s.GetCount()) if fs != nil {
m.SetClause(ClauseToGRPCMessage(s.GetClause())) res = make([]*Filter, 0, len(fs))
m.SetFilter(s.GetFilter())
m.SetAttribute(s.GetAttribute()) for i := range fs {
var f *Filter
if fs[i] != nil {
f = new(Filter)
err = f.FromGRPCMessage(fs[i])
if err != nil {
return
}
}
res = append(res, f)
}
}
return
}
func (s *Selector) ToGRPCMessage() grpc.Message {
var m *netmap.Selector
if s != nil {
m = new(netmap.Selector)
m.SetName(s.name)
m.SetAttribute(s.attribute)
m.SetFilter(s.filter)
m.SetCount(s.count)
m.SetClause(ClauseToGRPCMessage(s.clause))
}
return m return m
} }
func SelectorFromGRPCMessage(m *netmap.Selector) *Selector { func (s *Selector) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*netmap.Selector)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
s := new(Selector) s.name = v.GetName()
s.attribute = v.GetAttribute()
s.filter = v.GetFilter()
s.count = v.GetCount()
s.clause = ClauseFromGRPCMessage(v.GetClause())
s.SetName(m.GetName()) return nil
s.SetCount(m.GetCount())
s.SetClause(ClauseFromGRPCMessage(m.GetClause()))
s.SetFilter(m.GetFilter())
s.SetAttribute(m.GetAttribute())
return s
} }
func ReplicaToGRPCMessage(r *Replica) *netmap.Replica { func SelectorsToGRPC(ss []*Selector) (res []*netmap.Selector) {
if r == nil { if ss != nil {
return nil res = make([]*netmap.Selector, 0, len(ss))
for i := range ss {
res = append(res, ss[i].ToGRPCMessage().(*netmap.Selector))
}
} }
m := new(netmap.Replica) return
}
m.SetCount(r.GetCount()) func SelectorsFromGRPC(ss []*netmap.Selector) (res []*Selector, err error) {
m.SetSelector(r.GetSelector()) if ss != nil {
res = make([]*Selector, 0, len(ss))
for i := range ss {
var s *Selector
if ss[i] != nil {
s = new(Selector)
err = s.FromGRPCMessage(ss[i])
if err != nil {
return
}
}
res = append(res, s)
}
}
return
}
func (r *Replica) ToGRPCMessage() grpc.Message {
var m *netmap.Replica
if r != nil {
m = new(netmap.Replica)
m.SetSelector(r.selector)
m.SetCount(r.count)
}
return m return m
} }
func ReplicaFromGRPCMessage(m *netmap.Replica) *Replica { func (r *Replica) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*netmap.Replica)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
r := new(Replica) r.selector = v.GetSelector()
r.SetSelector(m.GetSelector()) r.count = v.GetCount()
r.SetCount(m.GetCount())
return r return nil
} }
func PlacementPolicyToGRPCMessage(p *PlacementPolicy) *netmap.PlacementPolicy { func ReplicasToGRPC(rs []*Replica) (res []*netmap.Replica) {
if p == nil { if rs != nil {
return nil res = make([]*netmap.Replica, 0, len(rs))
for i := range rs {
res = append(res, rs[i].ToGRPCMessage().(*netmap.Replica))
}
} }
filters := make([]*netmap.Filter, 0, len(p.GetFilters())) return
for _, filter := range p.GetFilters() { }
filters = append(filters, FilterToGRPCMessage(filter))
func ReplicasFromGRPC(rs []*netmap.Replica) (res []*Replica, err error) {
if rs != nil {
res = make([]*Replica, 0, len(rs))
for i := range rs {
var r *Replica
if rs[i] != nil {
r = new(Replica)
err = r.FromGRPCMessage(rs[i])
if err != nil {
return
}
} }
selectors := make([]*netmap.Selector, 0, len(p.GetSelectors())) res = append(res, r)
for _, selector := range p.GetSelectors() { }
selectors = append(selectors, SelectorToGRPCMessage(selector))
} }
replicas := make([]*netmap.Replica, 0, len(p.GetReplicas())) return
for _, replica := range p.GetReplicas() { }
replicas = append(replicas, ReplicaToGRPCMessage(replica))
func (p *PlacementPolicy) ToGRPCMessage() grpc.Message {
var m *netmap.PlacementPolicy
if p != nil {
m = new(netmap.PlacementPolicy)
m.SetFilters(FiltersToGRPC(p.filters))
m.SetSelectors(SelectorsToGRPC(p.selectors))
m.SetReplicas(ReplicasToGRPC(p.replicas))
m.SetContainerBackupFactor(p.backupFactor)
} }
m := new(netmap.PlacementPolicy)
m.SetContainerBackupFactor(p.GetContainerBackupFactor())
m.SetFilters(filters)
m.SetSelectors(selectors)
m.SetReplicas(replicas)
return m return m
} }
func PlacementPolicyFromGRPCMessage(m *netmap.PlacementPolicy) *PlacementPolicy { func (p *PlacementPolicy) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*netmap.PlacementPolicy)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
p.filters, err = FiltersFromGRPC(v.GetFilters())
if err != nil {
return err
}
p.selectors, err = SelectorsFromGRPC(v.GetSelectors())
if err != nil {
return err
}
p.replicas, err = ReplicasFromGRPC(v.GetReplicas())
if err != nil {
return err
}
p.backupFactor = v.GetContainerBackupFactor()
return nil return nil
}
filters := make([]*Filter, 0, len(m.GetFilters()))
for _, filter := range m.GetFilters() {
filters = append(filters, FilterFromGRPCMessage(filter))
}
selectors := make([]*Selector, 0, len(m.GetSelectors()))
for _, selector := range m.GetSelectors() {
selectors = append(selectors, SelectorFromGRPCMessage(selector))
}
replicas := make([]*Replica, 0, len(m.GetReplicas()))
for _, replica := range m.GetReplicas() {
replicas = append(replicas, ReplicaFromGRPCMessage(replica))
}
p := new(PlacementPolicy)
p.SetContainerBackupFactor(m.GetContainerBackupFactor())
p.SetFilters(filters)
p.SetSelectors(selectors)
p.SetReplicas(replicas)
return p
} }
func ClauseToGRPCMessage(n Clause) netmap.Clause { func ClauseToGRPCMessage(n Clause) netmap.Clause {
@ -188,286 +273,397 @@ func NodeStateFromRPCMessage(n netmap.NodeInfo_State) NodeState {
return NodeState(n) return NodeState(n)
} }
func AttributeToGRPCMessage(a *Attribute) *netmap.NodeInfo_Attribute { func (a *Attribute) ToGRPCMessage() grpc.Message {
if a == nil { var m *netmap.NodeInfo_Attribute
return nil
if a != nil {
m = new(netmap.NodeInfo_Attribute)
m.SetKey(a.key)
m.SetValue(a.value)
m.SetParents(a.parents)
} }
m := new(netmap.NodeInfo_Attribute)
m.SetKey(a.GetKey())
m.SetValue(a.GetValue())
m.SetParents(a.GetParents())
return m return m
} }
func AttributeFromGRPCMessage(m *netmap.NodeInfo_Attribute) *Attribute { func (a *Attribute) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*netmap.NodeInfo_Attribute)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
a := new(Attribute) a.key = v.GetKey()
a.value = v.GetValue()
a.parents = v.GetParents()
a.SetKey(m.GetKey()) return nil
a.SetValue(m.GetValue())
a.SetParents(m.GetParents())
return a
} }
func NodeInfoToGRPCMessage(n *NodeInfo) *netmap.NodeInfo { func AttributesToGRPC(as []*Attribute) (res []*netmap.NodeInfo_Attribute) {
if n == nil { if as != nil {
return nil res = make([]*netmap.NodeInfo_Attribute, 0, len(as))
for i := range as {
res = append(res, as[i].ToGRPCMessage().(*netmap.NodeInfo_Attribute))
}
} }
m := new(netmap.NodeInfo) return
}
m.SetPublicKey(n.GetPublicKey()) func AttributesFromGRPC(as []*netmap.NodeInfo_Attribute) (res []*Attribute, err error) {
m.SetAddress(n.GetAddress()) if as != nil {
m.SetState(NodeStateToGRPCMessage(n.GetState())) res = make([]*Attribute, 0, len(as))
attr := n.GetAttributes() for i := range as {
attrMsg := make([]*netmap.NodeInfo_Attribute, 0, len(attr)) var a *Attribute
for i := range attr { if as[i] != nil {
attrMsg = append(attrMsg, AttributeToGRPCMessage(attr[i])) a = new(Attribute)
err = a.FromGRPCMessage(as[i])
if err != nil {
return
}
} }
m.SetAttributes(attrMsg) res = append(res, a)
}
}
return
}
func (ni *NodeInfo) ToGRPCMessage() grpc.Message {
var m *netmap.NodeInfo
if ni != nil {
m = new(netmap.NodeInfo)
m.SetPublicKey(ni.publicKey)
m.SetAddress(ni.address)
m.SetState(NodeStateToGRPCMessage(ni.state))
m.SetAttributes(AttributesToGRPC(ni.attributes))
}
return m return m
} }
func NodeInfoFromGRPCMessage(m *netmap.NodeInfo) *NodeInfo { func (ni *NodeInfo) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*netmap.NodeInfo)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
ni.attributes, err = AttributesFromGRPC(v.GetAttributes())
if err != nil {
return err
}
ni.publicKey = v.GetPublicKey()
ni.address = v.GetAddress()
ni.state = NodeStateFromRPCMessage(v.GetState())
return nil return nil
}
a := new(NodeInfo)
a.SetPublicKey(m.GetPublicKey())
a.SetAddress(m.GetAddress())
a.SetState(NodeStateFromRPCMessage(m.GetState()))
attrMsg := m.GetAttributes()
attr := make([]*Attribute, 0, len(attrMsg))
for i := range attrMsg {
attr = append(attr, AttributeFromGRPCMessage(attrMsg[i]))
}
a.SetAttributes(attr)
return a
} }
func LocalNodeInfoRequestBodyToGRPCMessage(r *LocalNodeInfoRequestBody) *netmap.LocalNodeInfoRequest_Body { func (l *LocalNodeInfoRequestBody) ToGRPCMessage() grpc.Message {
if r == nil { var m *netmap.LocalNodeInfoRequest_Body
return nil
if l != nil {
m = new(netmap.LocalNodeInfoRequest_Body)
} }
return new(netmap.LocalNodeInfoRequest_Body)
}
func LocalNodeInfoRequestBodyFromGRPCMessage(m *netmap.LocalNodeInfoRequest_Body) *LocalNodeInfoRequestBody {
if m == nil {
return nil
}
return new(LocalNodeInfoRequestBody)
}
func LocalNodeInfoResponseBodyToGRPCMessage(r *LocalNodeInfoResponseBody) *netmap.LocalNodeInfoResponse_Body {
if r == nil {
return nil
}
m := new(netmap.LocalNodeInfoResponse_Body)
m.SetVersion(refs.VersionToGRPCMessage(r.GetVersion()))
m.SetNodeInfo(NodeInfoToGRPCMessage(r.GetNodeInfo()))
return m return m
} }
func LocalNodeInfoResponseBodyFromGRPCMessage(m *netmap.LocalNodeInfoResponse_Body) *LocalNodeInfoResponseBody { func (l *LocalNodeInfoRequestBody) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*netmap.LocalNodeInfoRequest_Body)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
r := new(LocalNodeInfoResponseBody) return nil
r.SetVersion(refs.VersionFromGRPCMessage(m.GetVersion()))
r.SetNodeInfo(NodeInfoFromGRPCMessage(m.GetNodeInfo()))
return r
} }
func LocalNodeInfoRequestToGRPCMessage(r *LocalNodeInfoRequest) *netmap.LocalNodeInfoRequest { func (l *LocalNodeInfoRequest) ToGRPCMessage() grpc.Message {
if r == nil { var m *netmap.LocalNodeInfoRequest
return nil
if l != nil {
m = new(netmap.LocalNodeInfoRequest)
m.SetBody(l.body.ToGRPCMessage().(*netmap.LocalNodeInfoRequest_Body))
l.RequestHeaders.ToMessage(m)
} }
m := new(netmap.LocalNodeInfoRequest)
m.SetBody(LocalNodeInfoRequestBodyToGRPCMessage(r.GetBody()))
session.RequestHeadersToGRPC(r, m)
return m return m
} }
func LocalNodeInfoRequestFromGRPCMessage(m *netmap.LocalNodeInfoRequest) *LocalNodeInfoRequest { func (l *LocalNodeInfoRequest) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*netmap.LocalNodeInfoRequest)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
r := new(LocalNodeInfoRequest) var err error
r.SetBody(LocalNodeInfoRequestBodyFromGRPCMessage(m.GetBody()))
session.RequestHeadersFromGRPC(m, r) body := v.GetBody()
if body == nil {
l.body = nil
} else {
if l.body == nil {
l.body = new(LocalNodeInfoRequestBody)
}
return r err = l.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return l.RequestHeaders.FromMessage(v)
} }
func LocalNodeInfoResponseToGRPCMessage(r *LocalNodeInfoResponse) *netmap.LocalNodeInfoResponse { func (l *LocalNodeInfoResponseBody) ToGRPCMessage() grpc.Message {
if r == nil { var m *netmap.LocalNodeInfoResponse_Body
return nil
if l != nil {
m = new(netmap.LocalNodeInfoResponse_Body)
m.SetVersion(l.version.ToGRPCMessage().(*refsGRPC.Version))
m.SetNodeInfo(l.nodeInfo.ToGRPCMessage().(*netmap.NodeInfo))
} }
m := new(netmap.LocalNodeInfoResponse)
m.SetBody(LocalNodeInfoResponseBodyToGRPCMessage(r.GetBody()))
session.ResponseHeadersToGRPC(r, m)
return m return m
} }
func LocalNodeInfoResponseFromGRPCMessage(m *netmap.LocalNodeInfoResponse) *LocalNodeInfoResponse { func (l *LocalNodeInfoResponseBody) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*netmap.LocalNodeInfoResponse_Body)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
r := new(LocalNodeInfoResponse) var err error
r.SetBody(LocalNodeInfoResponseBodyFromGRPCMessage(m.GetBody()))
session.ResponseHeadersFromGRPC(m, r) version := v.GetVersion()
if version == nil {
l.version = nil
} else {
if l.version == nil {
l.version = new(refs.Version)
}
return r err = l.version.FromGRPCMessage(version)
if err != nil {
return err
}
}
nodeInfo := v.GetNodeInfo()
if nodeInfo == nil {
l.nodeInfo = nil
} else {
if l.nodeInfo == nil {
l.nodeInfo = new(NodeInfo)
}
err = l.nodeInfo.FromGRPCMessage(nodeInfo)
}
return err
} }
func NetworkInfoToGRPCMessage(n *NetworkInfo) *netmap.NetworkInfo { func (l *LocalNodeInfoResponse) ToGRPCMessage() grpc.Message {
if n == nil { var m *netmap.LocalNodeInfoResponse
return nil
if l != nil {
m = new(netmap.LocalNodeInfoResponse)
m.SetBody(l.body.ToGRPCMessage().(*netmap.LocalNodeInfoResponse_Body))
l.ResponseHeaders.ToMessage(m)
} }
m := new(netmap.NetworkInfo)
m.SetCurrentEpoch(n.GetCurrentEpoch())
m.SetMagicNumber(n.GetMagicNumber())
return m return m
} }
func NetworkInfoFromGRPCMessage(m *netmap.NetworkInfo) *NetworkInfo { func (l *LocalNodeInfoResponse) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*netmap.LocalNodeInfoResponse)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
n := new(NetworkInfo) var err error
n.SetCurrentEpoch(m.GetCurrentEpoch()) body := v.GetBody()
n.SetMagicNumber(m.GetMagicNumber()) if body == nil {
l.body = nil
} else {
if l.body == nil {
l.body = new(LocalNodeInfoResponseBody)
}
return n err = l.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return l.ResponseHeaders.FromMessage(v)
} }
func NetworkInfoRequestBodyToGRPCMessage(r *NetworkInfoRequestBody) *netmap.NetworkInfoRequest_Body { func (i *NetworkInfo) ToGRPCMessage() grpc.Message {
if r == nil { var m *netmap.NetworkInfo
return nil
if i != nil {
m = new(netmap.NetworkInfo)
m.SetMagicNumber(i.magicNum)
m.SetCurrentEpoch(i.curEpoch)
} }
return new(netmap.NetworkInfoRequest_Body)
}
func NetworkInfoRequestBodyFromGRPCMessage(m *netmap.NetworkInfoRequest_Body) *NetworkInfoRequestBody {
if m == nil {
return nil
}
return new(NetworkInfoRequestBody)
}
func NetworkInfoResponseBodyToGRPCMessage(r *NetworkInfoResponseBody) *netmap.NetworkInfoResponse_Body {
if r == nil {
return nil
}
m := new(netmap.NetworkInfoResponse_Body)
m.SetNetworkInfo(NetworkInfoToGRPCMessage(r.GetNetworkInfo()))
return m return m
} }
func NetworkInfoResponseBodyFromGRPCMessage(m *netmap.NetworkInfoResponse_Body) *NetworkInfoResponseBody { func (i *NetworkInfo) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*netmap.NetworkInfo)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
r := new(NetworkInfoResponseBody) i.magicNum = v.GetMagicNumber()
r.SetNetworkInfo(NetworkInfoFromGRPCMessage(m.GetNetworkInfo())) i.curEpoch = v.GetCurrentEpoch()
return r return nil
} }
func NetworkInfoRequestToGRPCMessage(r *NetworkInfoRequest) *netmap.NetworkInfoRequest { func (l *NetworkInfoRequestBody) ToGRPCMessage() grpc.Message {
if r == nil { var m *netmap.NetworkInfoRequest_Body
return nil
if l != nil {
m = new(netmap.NetworkInfoRequest_Body)
} }
m := new(netmap.NetworkInfoRequest)
m.SetBody(NetworkInfoRequestBodyToGRPCMessage(r.GetBody()))
session.RequestHeadersToGRPC(r, m)
return m return m
} }
func NetworkInfoRequestFromGRPCMessage(m *netmap.NetworkInfoRequest) *NetworkInfoRequest { func (l *NetworkInfoRequestBody) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*netmap.NetworkInfoRequest_Body)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
r := new(NetworkInfoRequest) return nil
r.SetBody(NetworkInfoRequestBodyFromGRPCMessage(m.GetBody()))
session.RequestHeadersFromGRPC(m, r)
return r
} }
func NetworkInfoResponseToGRPCMessage(r *NetworkInfoResponse) *netmap.NetworkInfoResponse { func (l *NetworkInfoRequest) ToGRPCMessage() grpc.Message {
if r == nil { var m *netmap.NetworkInfoRequest
return nil
if l != nil {
m = new(netmap.NetworkInfoRequest)
m.SetBody(l.body.ToGRPCMessage().(*netmap.NetworkInfoRequest_Body))
l.RequestHeaders.ToMessage(m)
} }
m := new(netmap.NetworkInfoResponse)
m.SetBody(NetworkInfoResponseBodyToGRPCMessage(r.GetBody()))
session.ResponseHeadersToGRPC(r, m)
return m return m
} }
func NetworkInfoResponseFromGRPCMessage(m *netmap.NetworkInfoResponse) *NetworkInfoResponse { func (l *NetworkInfoRequest) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*netmap.NetworkInfoRequest)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
r := new(NetworkInfoResponse) var err error
r.SetBody(NetworkInfoResponseBodyFromGRPCMessage(m.GetBody()))
session.ResponseHeadersFromGRPC(m, r) body := v.GetBody()
if body == nil {
l.body = nil
} else {
if l.body == nil {
l.body = new(NetworkInfoRequestBody)
}
return r err = l.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return l.RequestHeaders.FromMessage(v)
}
func (i *NetworkInfoResponseBody) ToGRPCMessage() grpc.Message {
var m *netmap.NetworkInfoResponse_Body
if i != nil {
m = new(netmap.NetworkInfoResponse_Body)
m.SetNetworkInfo(i.netInfo.ToGRPCMessage().(*netmap.NetworkInfo))
}
return m
}
func (i *NetworkInfoResponseBody) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.NetworkInfoResponse_Body)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
netInfo := v.GetNetworkInfo()
if netInfo == nil {
i.netInfo = nil
} else {
if i.netInfo == nil {
i.netInfo = new(NetworkInfo)
}
err = i.netInfo.FromGRPCMessage(netInfo)
}
return err
}
func (l *NetworkInfoResponse) ToGRPCMessage() grpc.Message {
var m *netmap.NetworkInfoResponse
if l != nil {
m = new(netmap.NetworkInfoResponse)
m.SetBody(l.body.ToGRPCMessage().(*netmap.NetworkInfoResponse_Body))
l.ResponseHeaders.ToMessage(m)
}
return m
}
func (l *NetworkInfoResponse) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.NetworkInfoResponse)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
body := v.GetBody()
if body == nil {
l.body = nil
} else {
if l.body == nil {
l.body = new(NetworkInfoResponseBody)
}
err = l.body.FromGRPCMessage(body)
if err != nil {
return err
}
}
return l.ResponseHeaders.FromMessage(v)
} }

View file

@ -1,66 +0,0 @@
package netmap
import (
"context"
"github.com/pkg/errors"
"google.golang.org/grpc"
)
// Client wraps NetmapServiceClient
// with pre-defined configurations.
type Client struct {
*cfg
client NetmapServiceClient
}
// Option represents Client option.
type Option func(*cfg)
type cfg struct {
callOpts []grpc.CallOption
}
// ErrNilNetmapServiceClient is returned by functions that expect
// a non-nil ContainerServiceClient, but received nil.
var ErrNilNetmapServiceClient = errors.New("netmap gRPC client is nil")
func defaultCfg() *cfg {
return new(cfg)
}
// NewClient creates, initializes and returns a new Client instance.
//
// Options are applied one by one in order.
func NewClient(c NetmapServiceClient, opts ...Option) (*Client, error) {
if c == nil {
return nil, ErrNilNetmapServiceClient
}
cfg := defaultCfg()
for i := range opts {
opts[i](cfg)
}
return &Client{
cfg: cfg,
client: c,
}, nil
}
func (c *Client) LocalNodeInfo(ctx context.Context, req *LocalNodeInfoRequest) (*LocalNodeInfoResponse, error) {
return c.client.LocalNodeInfo(ctx, req, c.callOpts...)
}
func (c *Client) NetworkInfo(ctx context.Context, req *NetworkInfoRequest) (*NetworkInfoResponse, error) {
return c.client.NetworkInfo(ctx, req, c.callOpts...)
}
// WithCallOptions returns Option that configures
// Client to attach call options to each rpc call.
func WithCallOptions(opts []grpc.CallOption) Option {
return func(c *cfg) {
c.callOpts = opts
}
}

View file

@ -1,146 +1,62 @@
package netmap package netmap
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc" netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc"
"google.golang.org/protobuf/encoding/protojson"
) )
func (p *PlacementPolicy) MarshalJSON() ([]byte, error) { func (p *PlacementPolicy) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(p)
EmitUnpopulated: true,
}.Marshal(
PlacementPolicyToGRPCMessage(p),
)
} }
func (p *PlacementPolicy) UnmarshalJSON(data []byte) error { func (p *PlacementPolicy) UnmarshalJSON(data []byte) error {
msg := new(netmap.PlacementPolicy) return message.UnmarshalJSON(p, data, new(netmap.PlacementPolicy))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*p = *PlacementPolicyFromGRPCMessage(msg)
return nil
} }
func (f *Filter) MarshalJSON() ([]byte, error) { func (f *Filter) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(f)
EmitUnpopulated: true,
}.Marshal(
FilterToGRPCMessage(f),
)
} }
func (f *Filter) UnmarshalJSON(data []byte) error { func (f *Filter) UnmarshalJSON(data []byte) error {
msg := new(netmap.Filter) return message.UnmarshalJSON(f, data, new(netmap.Filter))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*f = *FilterFromGRPCMessage(msg)
return nil
} }
func (s *Selector) MarshalJSON() ([]byte, error) { func (s *Selector) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(s)
EmitUnpopulated: true,
}.Marshal(
SelectorToGRPCMessage(s),
)
} }
func (s *Selector) UnmarshalJSON(data []byte) error { func (s *Selector) UnmarshalJSON(data []byte) error {
msg := new(netmap.Selector) return message.UnmarshalJSON(s, data, new(netmap.Selector))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*s = *SelectorFromGRPCMessage(msg)
return nil
} }
func (r *Replica) MarshalJSON() ([]byte, error) { func (r *Replica) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(r)
EmitUnpopulated: true,
}.Marshal(
ReplicaToGRPCMessage(r),
)
} }
func (r *Replica) UnmarshalJSON(data []byte) error { func (r *Replica) UnmarshalJSON(data []byte) error {
msg := new(netmap.Replica) return message.UnmarshalJSON(r, data, new(netmap.Replica))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*r = *ReplicaFromGRPCMessage(msg)
return nil
} }
func (a *Attribute) MarshalJSON() ([]byte, error) { func (a *Attribute) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(a)
EmitUnpopulated: true,
}.Marshal(
AttributeToGRPCMessage(a),
)
} }
func (a *Attribute) UnmarshalJSON(data []byte) error { func (a *Attribute) UnmarshalJSON(data []byte) error {
msg := new(netmap.NodeInfo_Attribute) return message.UnmarshalJSON(a, data, new(netmap.NodeInfo_Attribute))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*a = *AttributeFromGRPCMessage(msg)
return nil
} }
func (ni *NodeInfo) MarshalJSON() ([]byte, error) { func (ni *NodeInfo) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(ni)
EmitUnpopulated: true,
}.Marshal(
NodeInfoToGRPCMessage(ni),
)
} }
func (ni *NodeInfo) UnmarshalJSON(data []byte) error { func (ni *NodeInfo) UnmarshalJSON(data []byte) error {
msg := new(netmap.NodeInfo) return message.UnmarshalJSON(ni, data, new(netmap.NodeInfo))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*ni = *NodeInfoFromGRPCMessage(msg)
return nil
} }
func (i *NetworkInfo) MarshalJSON() ([]byte, error) { func (i *NetworkInfo) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(i)
EmitUnpopulated: true,
}.Marshal(
NetworkInfoToGRPCMessage(i),
)
} }
func (i *NetworkInfo) UnmarshalJSON(data []byte) error { func (i *NetworkInfo) UnmarshalJSON(data []byte) error {
msg := new(netmap.NetworkInfo) return message.UnmarshalJSON(i, data, new(netmap.NetworkInfo))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*i = *NetworkInfoFromGRPCMessage(msg)
return nil
} }

View file

@ -1,80 +0,0 @@
package netmap_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/netmap"
"github.com/stretchr/testify/require"
)
func TestFilterJSON(t *testing.T) {
f := generateFilter("key", "value", false)
d, err := f.MarshalJSON()
require.NoError(t, err)
f2 := new(netmap.Filter)
require.NoError(t, f2.UnmarshalJSON(d))
require.Equal(t, f, f2)
}
func TestSelectorJSON(t *testing.T) {
s := generateSelector("name")
data, err := s.MarshalJSON()
require.NoError(t, err)
s2 := new(netmap.Selector)
require.NoError(t, s2.UnmarshalJSON(data))
require.Equal(t, s, s2)
}
func TestReplicaJSON(t *testing.T) {
s := generateReplica("selector")
data, err := s.MarshalJSON()
require.NoError(t, err)
s2 := new(netmap.Replica)
require.NoError(t, s2.UnmarshalJSON(data))
require.Equal(t, s, s2)
}
func TestAttributeJSON(t *testing.T) {
a := generateAttribute("key", "value")
data, err := a.MarshalJSON()
require.NoError(t, err)
a2 := new(netmap.Attribute)
require.NoError(t, a2.UnmarshalJSON(data))
require.Equal(t, a, a2)
}
func TestNodeInfoJSON(t *testing.T) {
i := generateNodeInfo("key", "value", 3)
data, err := i.MarshalJSON()
require.NoError(t, err)
i2 := new(netmap.NodeInfo)
require.NoError(t, i2.UnmarshalJSON(data))
require.Equal(t, i, i2)
}
func TestNetworkInfoJSON(t *testing.T) {
i := generateNetworkInfo()
data, err := i.MarshalJSON()
require.NoError(t, err)
i2 := new(netmap.NetworkInfo)
require.NoError(t, i2.UnmarshalJSON(data))
require.Equal(t, i, i2)
}

View file

@ -1,9 +1,9 @@
package netmap package netmap
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
protoutil "github.com/nspcc-dev/neofs-api-go/util/proto" protoutil "github.com/nspcc-dev/neofs-api-go/util/proto"
netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc" netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc"
"google.golang.org/protobuf/proto"
) )
const ( const (
@ -107,14 +107,7 @@ func (f *Filter) StableSize() (size int) {
} }
func (f *Filter) Unmarshal(data []byte) error { func (f *Filter) Unmarshal(data []byte) error {
m := new(netmap.Filter) return message.Unmarshal(f, data, new(netmap.Filter))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*f = *FilterFromGRPCMessage(m)
return nil
} }
func (s *Selector) StableMarshal(buf []byte) ([]byte, error) { func (s *Selector) StableMarshal(buf []byte) ([]byte, error) {
@ -178,14 +171,7 @@ func (s *Selector) StableSize() (size int) {
} }
func (s *Selector) Unmarshal(data []byte) error { func (s *Selector) Unmarshal(data []byte) error {
m := new(netmap.Selector) return message.Unmarshal(s, data, new(netmap.Selector))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*s = *SelectorFromGRPCMessage(m)
return nil
} }
func (r *Replica) StableMarshal(buf []byte) ([]byte, error) { func (r *Replica) StableMarshal(buf []byte) ([]byte, error) {
@ -225,14 +211,7 @@ func (r *Replica) StableSize() (size int) {
} }
func (r *Replica) Unmarshal(data []byte) error { func (r *Replica) Unmarshal(data []byte) error {
m := new(netmap.Replica) return message.Unmarshal(r, data, new(netmap.Replica))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*r = *ReplicaFromGRPCMessage(m)
return nil
} }
func (p *PlacementPolicy) StableMarshal(buf []byte) ([]byte, error) { func (p *PlacementPolicy) StableMarshal(buf []byte) ([]byte, error) {
@ -305,14 +284,7 @@ func (p *PlacementPolicy) StableSize() (size int) {
} }
func (p *PlacementPolicy) Unmarshal(data []byte) error { func (p *PlacementPolicy) Unmarshal(data []byte) error {
m := new(netmap.PlacementPolicy) return message.Unmarshal(p, data, new(netmap.PlacementPolicy))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*p = *PlacementPolicyFromGRPCMessage(m)
return nil
} }
func (a *Attribute) StableMarshal(buf []byte) ([]byte, error) { func (a *Attribute) StableMarshal(buf []byte) ([]byte, error) {
@ -371,14 +343,7 @@ func (a *Attribute) StableSize() (size int) {
} }
func (a *Attribute) Unmarshal(data []byte) error { func (a *Attribute) Unmarshal(data []byte) error {
m := new(netmap.NodeInfo_Attribute) return message.Unmarshal(a, data, new(netmap.NodeInfo_Attribute))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*a = *AttributeFromGRPCMessage(m)
return nil
} }
func (ni *NodeInfo) StableMarshal(buf []byte) ([]byte, error) { func (ni *NodeInfo) StableMarshal(buf []byte) ([]byte, error) {
@ -443,14 +408,7 @@ func (ni *NodeInfo) StableSize() (size int) {
} }
func (ni *NodeInfo) Unmarshal(data []byte) error { func (ni *NodeInfo) Unmarshal(data []byte) error {
m := new(netmap.NodeInfo) return message.Unmarshal(ni, data, new(netmap.NodeInfo))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*ni = *NodeInfoFromGRPCMessage(m)
return nil
} }
func (l *LocalNodeInfoRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (l *LocalNodeInfoRequestBody) StableMarshal(buf []byte) ([]byte, error) {
@ -461,6 +419,10 @@ func (l *LocalNodeInfoRequestBody) StableSize() (size int) {
return 0 return 0
} }
func (l *LocalNodeInfoRequestBody) Unmarshal([]byte) error {
return nil
}
func (l *LocalNodeInfoResponseBody) StableMarshal(buf []byte) ([]byte, error) { func (l *LocalNodeInfoResponseBody) StableMarshal(buf []byte) ([]byte, error) {
if l == nil { if l == nil {
return []byte{}, nil return []byte{}, nil
@ -501,6 +463,10 @@ func (l *LocalNodeInfoResponseBody) StableSize() (size int) {
return size return size
} }
func (l *LocalNodeInfoResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(l, data, new(netmap.LocalNodeInfoResponse_Body))
}
const ( const (
_ = iota _ = iota
netInfoCurEpochFNum netInfoCurEpochFNum
@ -548,14 +514,7 @@ func (i *NetworkInfo) StableSize() (size int) {
} }
func (i *NetworkInfo) Unmarshal(data []byte) error { func (i *NetworkInfo) Unmarshal(data []byte) error {
m := new(netmap.NetworkInfo) return message.Unmarshal(i, data, new(netmap.NetworkInfo))
if err := proto.Unmarshal(data, m); err != nil {
return err
}
*i = *NetworkInfoFromGRPCMessage(m)
return nil
} }
func (l *NetworkInfoRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (l *NetworkInfoRequestBody) StableMarshal(buf []byte) ([]byte, error) {
@ -566,6 +525,10 @@ func (l *NetworkInfoRequestBody) StableSize() (size int) {
return 0 return 0
} }
func (l *NetworkInfoRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(l, data, new(netmap.NetworkInfoRequest_Body))
}
const ( const (
_ = iota _ = iota
netInfoRespBodyNetInfoFNum netInfoRespBodyNetInfoFNum
@ -597,3 +560,7 @@ func (i *NetworkInfoResponseBody) StableSize() (size int) {
return size return size
} }
func (i *NetworkInfoResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(i, data, new(netmap.NetworkInfoResponse_Body))
}

View file

@ -1,248 +0,0 @@
package netmap_test
import (
"strconv"
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/netmap"
grpc "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/stretchr/testify/require"
goproto "google.golang.org/protobuf/proto"
)
func TestAttribute_StableMarshal(t *testing.T) {
from := generateAttribute("key", "value")
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
to := new(netmap.Attribute)
require.NoError(t, to.Unmarshal(wire))
require.Equal(t, from, to)
})
}
func TestNodeInfo_StableMarshal(t *testing.T) {
from := generateNodeInfo("publicKey", "/multi/addr", 10)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
to := new(netmap.NodeInfo)
require.NoError(t, to.Unmarshal(wire))
require.Equal(t, from, to)
})
}
func TestFilter_StableMarshal(t *testing.T) {
from := generateFilter("key", "value", false)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
to := new(netmap.Filter)
require.NoError(t, to.Unmarshal(wire))
require.Equal(t, from, to)
})
}
func TestSelector_StableMarshal(t *testing.T) {
from := generateSelector("name")
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
to := new(netmap.Selector)
require.NoError(t, to.Unmarshal(wire))
require.Equal(t, from, to)
})
}
func TestReplica_StableMarshal(t *testing.T) {
from := generateReplica("selector")
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
to := new(netmap.Replica)
require.NoError(t, to.Unmarshal(wire))
require.Equal(t, from, to)
})
}
func TestPlacementPolicy_StableMarshal(t *testing.T) {
from := generatePolicy(3)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
to := new(netmap.PlacementPolicy)
require.NoError(t, to.Unmarshal(wire))
require.Equal(t, from, to)
})
}
func TestLocalNodeInfoResponseBody_StableMarshal(t *testing.T) {
from := generateNodeInfoResponseBody()
transport := new(grpc.LocalNodeInfoResponse_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := netmap.LocalNodeInfoResponseBodyFromGRPCMessage(transport)
require.Equal(t, from, to)
})
}
func TestNetworkInfoResponseBody_StableMarshal(t *testing.T) {
from := generateNetworkInfoResponseBody()
transport := new(grpc.NetworkInfoResponse_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := netmap.NetworkInfoResponseBodyFromGRPCMessage(transport)
require.Equal(t, from, to)
})
}
func generateAttribute(k, v string) *netmap.Attribute {
attr := new(netmap.Attribute)
attr.SetKey(k)
attr.SetValue(v)
attr.SetParents([]string{k, v})
return attr
}
func generateNodeInfo(key, addr string, n int) *netmap.NodeInfo {
nodeInfo := new(netmap.NodeInfo)
nodeInfo.SetPublicKey([]byte(key))
nodeInfo.SetAddress(addr)
nodeInfo.SetState(netmap.Online)
attrs := make([]*netmap.Attribute, n)
for i := 0; i < n; i++ {
j := strconv.Itoa(n)
attrs[i] = generateAttribute("key"+j, "value"+j)
}
nodeInfo.SetAttributes(attrs)
return nodeInfo
}
func generateFilter(key, value string, fin bool) *netmap.Filter {
f := new(netmap.Filter)
f.SetKey(key)
f.SetValue(value)
f.SetName("name")
f.SetOp(netmap.AND)
if !fin {
ff := generateFilter(key+"fin", value+"fin", true)
f.SetFilters([]*netmap.Filter{ff})
} else {
f.SetFilters([]*netmap.Filter{})
}
return f
}
func generateSelector(name string) *netmap.Selector {
s := new(netmap.Selector)
s.SetName(name)
s.SetAttribute("attribute")
s.SetClause(netmap.Distinct)
s.SetCount(10)
s.SetFilter("filter")
return s
}
func generateReplica(selector string) *netmap.Replica {
r := new(netmap.Replica)
r.SetCount(10)
r.SetSelector(selector)
return r
}
func generatePolicy(n int) *netmap.PlacementPolicy {
var (
p = new(netmap.PlacementPolicy)
f = make([]*netmap.Filter, 0, n)
s = make([]*netmap.Selector, 0, n)
r = make([]*netmap.Replica, 0, n)
)
for i := 0; i < n; i++ {
ind := strconv.Itoa(i)
f = append(f, generateFilter("key"+ind, "val"+ind, false))
s = append(s, generateSelector("name"+ind))
r = append(r, generateReplica("selector"+ind))
}
p.SetFilters(f)
p.SetSelectors(s)
p.SetReplicas(r)
p.SetContainerBackupFactor(10)
return p
}
func generateNodeInfoResponseBody() *netmap.LocalNodeInfoResponseBody {
ni := generateNodeInfo("key", "/multi/addr", 2)
r := new(netmap.LocalNodeInfoResponseBody)
r.SetVersion(generateVersion(2, 1))
r.SetNodeInfo(ni)
return r
}
func generateVersion(maj, min uint32) *refs.Version {
version := new(refs.Version)
version.SetMajor(maj)
version.SetMinor(min)
return version
}
func generateNetworkInfo() *netmap.NetworkInfo {
ni := new(netmap.NetworkInfo)
ni.SetCurrentEpoch(13)
ni.SetMagicNumber(666)
return ni
}
func generateNetworkInfoResponseBody() *netmap.NetworkInfoResponseBody {
ni := generateNetworkInfo()
r := new(netmap.NetworkInfoResponseBody)
r.SetNetworkInfo(ni)
return r
}

25
v2/netmap/message_test.go Normal file
View file

@ -0,0 +1,25 @@
package netmap_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/rpc/message"
messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test"
netmaptest "github.com/nspcc-dev/neofs-api-go/v2/netmap/test"
)
func TestMessageConvert(t *testing.T) {
messagetest.TestRPCMessage(t,
func(empty bool) message.Message { return netmaptest.GenerateFilter(empty) },
func(empty bool) message.Message { return netmaptest.GenerateSelector(empty) },
func(empty bool) message.Message { return netmaptest.GenerateReplica(empty) },
func(empty bool) message.Message { return netmaptest.GeneratePlacementPolicy(empty) },
func(empty bool) message.Message { return netmaptest.GenerateAttribute(empty) },
func(empty bool) message.Message { return netmaptest.GenerateNodeInfo(empty) },
func(empty bool) message.Message { return netmaptest.GenerateLocalNodeInfoRequest(empty) },
func(empty bool) message.Message { return netmaptest.GenerateLocalNodeInfoResponseBody(empty) },
func(empty bool) message.Message { return netmaptest.GenerateNetworkInfo(empty) },
func(empty bool) message.Message { return netmaptest.GenerateNetworkInfoRequest(empty) },
func(empty bool) message.Message { return netmaptest.GenerateNetworkInfoResponseBody(empty) },
)
}

View file

@ -1,46 +0,0 @@
package netmap
import (
"context"
"github.com/nspcc-dev/neofs-api-go/v2/session"
)
type Service interface {
LocalNodeInfo(ctx context.Context, request *LocalNodeInfoRequest) (*LocalNodeInfoResponse, error)
NetworkInfo(ctx context.Context, request *NetworkInfoRequest) (*NetworkInfoResponse, error)
}
type LocalNodeInfoRequest struct {
body *LocalNodeInfoRequestBody
metaHeader *session.RequestMetaHeader
verifyHeader *session.RequestVerificationHeader
}
type LocalNodeInfoResponse struct {
body *LocalNodeInfoResponseBody
metaHeader *session.ResponseMetaHeader
verifyHeader *session.ResponseVerificationHeader
}
// NetworkInfoRequest is a structure of NetworkInfo request.
type NetworkInfoRequest struct {
body *NetworkInfoRequestBody
metaHeader *session.RequestMetaHeader
verifyHeader *session.RequestVerificationHeader
}
// NetworkInfoResponse is a structure of NetworkInfo response.
type NetworkInfoResponse struct {
body *NetworkInfoResponseBody
metaHeader *session.ResponseMetaHeader
verifyHeader *session.ResponseVerificationHeader
}

219
v2/netmap/test/generate.go Normal file
View file

@ -0,0 +1,219 @@
package netmaptest
import (
"github.com/nspcc-dev/neofs-api-go/v2/netmap"
refstest "github.com/nspcc-dev/neofs-api-go/v2/refs/test"
sessiontest "github.com/nspcc-dev/neofs-api-go/v2/session/test"
)
func GenerateFilter(empty bool) *netmap.Filter {
return generateFilter(empty, true)
}
func generateFilter(empty, withSub bool) *netmap.Filter {
m := new(netmap.Filter)
if !empty {
m.SetKey("filter key")
m.SetValue("filter value")
m.SetName("filter name")
m.SetOp(1)
if withSub {
m.SetFilters([]*netmap.Filter{
generateFilter(empty, false),
generateFilter(empty, false),
})
}
}
return m
}
func GenerateFilters(empty bool) (res []*netmap.Filter) {
if !empty {
res = append(res,
GenerateFilter(false),
GenerateFilter(false),
)
}
return
}
func GenerateSelector(empty bool) *netmap.Selector {
m := new(netmap.Selector)
if !empty {
m.SetCount(66)
m.SetAttribute("selector attribute")
m.SetFilter("select filter")
m.SetName("select name")
m.SetClause(1)
}
return m
}
func GenerateSelectors(empty bool) (res []*netmap.Selector) {
if !empty {
res = append(res,
GenerateSelector(false),
GenerateSelector(false),
)
}
return
}
func GenerateReplica(empty bool) *netmap.Replica {
m := new(netmap.Replica)
if !empty {
m.SetCount(42)
m.SetSelector("replica selector")
}
return m
}
func GenerateReplicas(empty bool) (res []*netmap.Replica) {
if !empty {
res = append(res,
GenerateReplica(false),
GenerateReplica(false),
)
}
return
}
func GeneratePlacementPolicy(empty bool) *netmap.PlacementPolicy {
m := new(netmap.PlacementPolicy)
if !empty {
m.SetContainerBackupFactor(322)
}
m.SetFilters(GenerateFilters(empty))
m.SetSelectors(GenerateSelectors(empty))
m.SetReplicas(GenerateReplicas(empty))
return m
}
func GenerateAttribute(empty bool) *netmap.Attribute {
m := new(netmap.Attribute)
if !empty {
m.SetKey("attribute key")
m.SetValue("attribute val")
}
return m
}
func GenerateAttributes(empty bool) (res []*netmap.Attribute) {
if !empty {
res = append(res,
GenerateAttribute(false),
GenerateAttribute(false),
)
}
return
}
func GenerateNodeInfo(empty bool) *netmap.NodeInfo {
m := new(netmap.NodeInfo)
if !empty {
m.SetAddress("node address")
m.SetPublicKey([]byte{1, 2, 3})
m.SetState(33)
}
m.SetAttributes(GenerateAttributes(empty))
return m
}
func GenerateLocalNodeInfoRequestBody(empty bool) *netmap.LocalNodeInfoRequestBody {
m := new(netmap.LocalNodeInfoRequestBody)
return m
}
func GenerateLocalNodeInfoRequest(empty bool) *netmap.LocalNodeInfoRequest {
m := new(netmap.LocalNodeInfoRequest)
m.SetBody(GenerateLocalNodeInfoRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateLocalNodeInfoResponseBody(empty bool) *netmap.LocalNodeInfoResponseBody {
m := new(netmap.LocalNodeInfoResponseBody)
m.SetVersion(refstest.GenerateVersion(empty))
m.SetNodeInfo(GenerateNodeInfo(empty))
return m
}
func GenerateLocalNodeInfoResponse(empty bool) *netmap.LocalNodeInfoResponse {
m := new(netmap.LocalNodeInfoResponse)
m.SetBody(GenerateLocalNodeInfoResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateNetworkInfo(empty bool) *netmap.NetworkInfo {
m := new(netmap.NetworkInfo)
if !empty {
m.SetMagicNumber(228)
m.SetCurrentEpoch(666)
}
return m
}
func GenerateNetworkInfoRequestBody(empty bool) *netmap.NetworkInfoRequestBody {
m := new(netmap.NetworkInfoRequestBody)
return m
}
func GenerateNetworkInfoRequest(empty bool) *netmap.NetworkInfoRequest {
m := new(netmap.NetworkInfoRequest)
m.SetBody(GenerateNetworkInfoRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateNetworkInfoResponseBody(empty bool) *netmap.NetworkInfoResponseBody {
m := new(netmap.NetworkInfoResponseBody)
m.SetNetworkInfo(GenerateNetworkInfo(empty))
return m
}
func GenerateNetworkInfoResponse(empty bool) *netmap.NetworkInfoResponse {
m := new(netmap.NetworkInfoResponse)
m.SetBody(GenerateNetworkInfoResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}

View file

@ -5,6 +5,32 @@ import (
"github.com/nspcc-dev/neofs-api-go/v2/session" "github.com/nspcc-dev/neofs-api-go/v2/session"
) )
type LocalNodeInfoRequest struct {
body *LocalNodeInfoRequestBody
session.RequestHeaders
}
type LocalNodeInfoResponse struct {
body *LocalNodeInfoResponseBody
session.ResponseHeaders
}
// NetworkInfoRequest is a structure of NetworkInfo request.
type NetworkInfoRequest struct {
body *NetworkInfoRequestBody
session.RequestHeaders
}
// NetworkInfoResponse is a structure of NetworkInfo response.
type NetworkInfoResponse struct {
body *NetworkInfoResponseBody
session.ResponseHeaders
}
type Filter struct { type Filter struct {
name string name string
key string key string
@ -443,32 +469,6 @@ func (l *LocalNodeInfoRequest) SetBody(body *LocalNodeInfoRequestBody) {
} }
} }
func (l *LocalNodeInfoRequest) GetMetaHeader() *session.RequestMetaHeader {
if l != nil {
return l.metaHeader
}
return nil
}
func (l *LocalNodeInfoRequest) SetMetaHeader(metaHeader *session.RequestMetaHeader) {
if l != nil {
l.metaHeader = metaHeader
}
}
func (l *LocalNodeInfoRequest) GetVerificationHeader() *session.RequestVerificationHeader {
if l != nil {
return l.verifyHeader
}
return nil
}
func (l *LocalNodeInfoRequest) SetVerificationHeader(verifyHeader *session.RequestVerificationHeader) {
if l != nil {
l.verifyHeader = verifyHeader
}
}
func (l *LocalNodeInfoResponse) GetBody() *LocalNodeInfoResponseBody { func (l *LocalNodeInfoResponse) GetBody() *LocalNodeInfoResponseBody {
if l != nil { if l != nil {
return l.body return l.body
@ -482,32 +482,6 @@ func (l *LocalNodeInfoResponse) SetBody(body *LocalNodeInfoResponseBody) {
} }
} }
func (l *LocalNodeInfoResponse) GetMetaHeader() *session.ResponseMetaHeader {
if l != nil {
return l.metaHeader
}
return nil
}
func (l *LocalNodeInfoResponse) SetMetaHeader(metaHeader *session.ResponseMetaHeader) {
if l != nil {
l.metaHeader = metaHeader
}
}
func (l *LocalNodeInfoResponse) GetVerificationHeader() *session.ResponseVerificationHeader {
if l != nil {
return l.verifyHeader
}
return nil
}
func (l *LocalNodeInfoResponse) SetVerificationHeader(verifyHeader *session.ResponseVerificationHeader) {
if l != nil {
l.verifyHeader = verifyHeader
}
}
// NetworkInfo groups information about // NetworkInfo groups information about
// NeoFS network. // NeoFS network.
type NetworkInfo struct { type NetworkInfo struct {
@ -583,32 +557,6 @@ func (l *NetworkInfoRequest) SetBody(body *NetworkInfoRequestBody) {
} }
} }
func (l *NetworkInfoRequest) GetMetaHeader() *session.RequestMetaHeader {
if l != nil {
return l.metaHeader
}
return nil
}
func (l *NetworkInfoRequest) SetMetaHeader(metaHeader *session.RequestMetaHeader) {
if l != nil {
l.metaHeader = metaHeader
}
}
func (l *NetworkInfoRequest) GetVerificationHeader() *session.RequestVerificationHeader {
if l != nil {
return l.verifyHeader
}
return nil
}
func (l *NetworkInfoRequest) SetVerificationHeader(verifyHeader *session.RequestVerificationHeader) {
if l != nil {
l.verifyHeader = verifyHeader
}
}
func (l *NetworkInfoResponse) GetBody() *NetworkInfoResponseBody { func (l *NetworkInfoResponse) GetBody() *NetworkInfoResponseBody {
if l != nil { if l != nil {
return l.body return l.body
@ -621,29 +569,3 @@ func (l *NetworkInfoResponse) SetBody(body *NetworkInfoResponseBody) {
l.body = body l.body = body
} }
} }
func (l *NetworkInfoResponse) GetMetaHeader() *session.ResponseMetaHeader {
if l != nil {
return l.metaHeader
}
return nil
}
func (l *NetworkInfoResponse) SetMetaHeader(metaHeader *session.ResponseMetaHeader) {
if l != nil {
l.metaHeader = metaHeader
}
}
func (l *NetworkInfoResponse) GetVerificationHeader() *session.ResponseVerificationHeader {
if l != nil {
return l.verifyHeader
}
return nil
}
func (l *NetworkInfoResponse) SetVerificationHeader(verifyHeader *session.ResponseVerificationHeader) {
if l != nil {
l.verifyHeader = verifyHeader
}
}

View file

@ -1,408 +0,0 @@
package object
import (
"context"
"github.com/nspcc-dev/neofs-api-go/v2/client"
object "github.com/nspcc-dev/neofs-api-go/v2/object/grpc"
"github.com/pkg/errors"
"google.golang.org/grpc"
)
// Client represents universal object
// transport client.
type Client struct {
getClient *getObjectClient
putClient *putObjectClient
headClient *headObjectClient
searchClient *searchObjectClient
deleteClient *deleteObjectClient
getRangeClient *getRangeObjectClient
getRangeHashClient *getRangeHashObjectClient
}
// Option represents Client option.
type Option func(*cfg)
type cfg struct {
proto client.Protocol
globalOpts []client.Option
gRPC cfgGRPC
}
type cfgGRPC struct {
serviceClient object.ObjectServiceClient
grpcCallOpts []grpc.CallOption
callOpts []object.Option
client *object.Client
}
// types of upper level sub-clients, accessed directly from object.Client
type (
getObjectClient struct {
streamClientGetter func(context.Context, *GetRequest) (interface{}, error)
streamerConstructor func(interface{}) (GetObjectStreamer, error)
}
putObjectClient struct {
streamClientGetter func(context.Context) (interface{}, error)
streamerConstructor func(interface{}) (PutObjectStreamer, error)
}
headObjectClient struct {
requestConverter func(request *HeadRequest) interface{}
caller func(context.Context, interface{}) (interface{}, error)
responseConverter func(interface{}) *HeadResponse
}
deleteObjectClient struct {
requestConverter func(request *DeleteRequest) interface{}
caller func(context.Context, interface{}) (interface{}, error)
responseConverter func(interface{}) *DeleteResponse
}
searchObjectClient struct {
streamClientGetter func(context.Context, *SearchRequest) (interface{}, error)
streamerConstructor func(interface{}) (SearchObjectStreamer, error)
}
getRangeObjectClient struct {
streamClientGetter func(context.Context, *GetRangeRequest) (interface{}, error)
streamerConstructor func(interface{}) (GetRangeObjectStreamer, error)
}
getRangeHashObjectClient struct {
requestConverter func(request *GetRangeHashRequest) interface{}
caller func(context.Context, interface{}) (interface{}, error)
responseConverter func(interface{}) *GetRangeHashResponse
}
)
func (c *Client) Get(ctx context.Context, req *GetRequest) (GetObjectStreamer, error) {
cli, err := c.getClient.streamClientGetter(ctx, req)
if err != nil {
return nil, errors.Wrap(err, "could not send get object request")
}
return c.getClient.streamerConstructor(cli)
}
func (c *Client) Put(ctx context.Context) (PutObjectStreamer, error) {
cli, err := c.putClient.streamClientGetter(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not prepare put object streamer")
}
return c.putClient.streamerConstructor(cli)
}
func (c *Client) Head(ctx context.Context, req *HeadRequest) (*HeadResponse, error) {
resp, err := c.headClient.caller(ctx, c.headClient.requestConverter(req))
if err != nil {
return nil, errors.Wrap(err, "could not send head object request")
}
return c.headClient.responseConverter(resp), nil
}
func (c *Client) Search(ctx context.Context, req *SearchRequest) (SearchObjectStreamer, error) {
cli, err := c.searchClient.streamClientGetter(ctx, req)
if err != nil {
return nil, err
}
return c.searchClient.streamerConstructor(cli)
}
func (c *Client) Delete(ctx context.Context, req *DeleteRequest) (*DeleteResponse, error) {
resp, err := c.deleteClient.caller(ctx, c.deleteClient.requestConverter(req))
if err != nil {
return nil, errors.Wrap(err, "could not send delete object request")
}
return c.deleteClient.responseConverter(resp), nil
}
func (c *Client) GetRange(ctx context.Context, req *GetRangeRequest) (GetRangeObjectStreamer, error) {
cli, err := c.getRangeClient.streamClientGetter(ctx, req)
if err != nil {
return nil, errors.Wrap(err, "could not send get object range request")
}
return c.getRangeClient.streamerConstructor(cli)
}
func (c *Client) GetRangeHash(ctx context.Context, req *GetRangeHashRequest) (*GetRangeHashResponse, error) {
resp, err := c.getRangeHashClient.caller(ctx, c.getRangeHashClient.requestConverter(req))
if err != nil {
return nil, errors.Wrap(err, "could not send get object range hash request")
}
return c.getRangeHashClient.responseConverter(resp), nil
}
func defaultCfg() *cfg {
return &cfg{
proto: client.ProtoGRPC,
}
}
func NewClient(opts ...Option) (*Client, error) {
cfg := defaultCfg()
for i := range opts {
opts[i](cfg)
}
var err error
switch cfg.proto {
case client.ProtoGRPC:
var c *object.Client
if c, err = newGRPCClient(cfg); err != nil {
break
}
return &Client{
getClient: newGRPCGetClient(c),
putClient: newGRPCPutClient(c),
headClient: newGRPCHeadClient(c),
searchClient: newGRPCSearchClient(c),
deleteClient: newGRPCDeleteClient(c),
getRangeClient: newGRPCGetRangeClient(c),
getRangeHashClient: newGRPCGetRangeHashClient(c),
}, nil
default:
err = client.ErrProtoUnsupported
}
return nil, errors.Wrapf(err, "could not create %s object client", cfg.proto)
}
func newGRPCClient(cfg *cfg) (*object.Client, error) {
var err error
if cfg.gRPC.client == nil {
if cfg.gRPC.serviceClient == nil {
conn, err := client.NewGRPCClientConn(cfg.globalOpts...)
if err != nil {
return nil, errors.Wrap(err, "could not open gRPC getClient connection")
}
cfg.gRPC.serviceClient = object.NewObjectServiceClient(conn)
}
cfg.gRPC.client, err = object.NewClient(
cfg.gRPC.serviceClient,
append(
cfg.gRPC.callOpts,
object.WithCallOptions(cfg.gRPC.grpcCallOpts),
)...,
)
}
return cfg.gRPC.client, err
}
func newGRPCGetClient(c *object.Client) *getObjectClient {
cli := &getObjectClient{
streamClientGetter: func(ctx context.Context, request *GetRequest) (interface{}, error) {
return c.Get(ctx, GetRequestToGRPCMessage(request))
},
streamerConstructor: func(i interface{}) (GetObjectStreamer, error) {
cli, ok := i.(object.ObjectService_GetClient)
if !ok {
return nil, errors.New("can't convert interface to grpc get getClient")
}
return &getObjectGRPCStream{
recv: func() (*GetResponse, error) {
resp, err := cli.Recv()
if err != nil {
return nil, err
}
return GetResponseFromGRPCMessage(resp), nil
},
}, nil
},
}
return cli
}
func newGRPCPutClient(c *object.Client) *putObjectClient {
cli := &putObjectClient{
streamClientGetter: func(ctx context.Context) (interface{}, error) {
return c.Put(ctx)
},
streamerConstructor: func(i interface{}) (PutObjectStreamer, error) {
cli, ok := i.(object.ObjectService_PutClient)
if !ok {
return nil, errors.New("can't convert interface to grpc get getClient")
}
return &putObjectGRPCStream{
send: func(request *PutRequest) error {
return cli.Send(PutRequestToGRPCMessage(request))
},
closeAndRecv: func() (*PutResponse, error) {
resp, err := cli.CloseAndRecv()
if err != nil {
return nil, err
}
return PutResponseFromGRPCMessage(resp), nil
},
}, nil
},
}
return cli
}
func newGRPCHeadClient(c *object.Client) *headObjectClient {
return &headObjectClient{
requestConverter: func(req *HeadRequest) interface{} {
return HeadRequestToGRPCMessage(req)
},
caller: func(ctx context.Context, req interface{}) (interface{}, error) {
return c.Head(ctx, req.(*object.HeadRequest))
},
responseConverter: func(resp interface{}) *HeadResponse {
return HeadResponseFromGRPCMessage(resp.(*object.HeadResponse))
},
}
}
func newGRPCSearchClient(c *object.Client) *searchObjectClient {
cli := &searchObjectClient{
streamClientGetter: func(ctx context.Context, request *SearchRequest) (interface{}, error) {
return c.Search(ctx, SearchRequestToGRPCMessage(request))
},
streamerConstructor: func(i interface{}) (SearchObjectStreamer, error) {
cli, ok := i.(object.ObjectService_SearchClient)
if !ok {
return nil, errors.New("can't convert interface to grpc get getClient")
}
return &searchObjectGRPCStream{
recv: func() (*SearchResponse, error) {
resp, err := cli.Recv()
if err != nil {
return nil, err
}
return SearchResponseFromGRPCMessage(resp), nil
},
}, nil
},
}
return cli
}
func newGRPCDeleteClient(c *object.Client) *deleteObjectClient {
return &deleteObjectClient{
requestConverter: func(req *DeleteRequest) interface{} {
return DeleteRequestToGRPCMessage(req)
},
caller: func(ctx context.Context, req interface{}) (interface{}, error) {
return c.Delete(ctx, req.(*object.DeleteRequest))
},
responseConverter: func(resp interface{}) *DeleteResponse {
return DeleteResponseFromGRPCMessage(resp.(*object.DeleteResponse))
},
}
}
func newGRPCGetRangeClient(c *object.Client) *getRangeObjectClient {
cli := &getRangeObjectClient{
streamClientGetter: func(ctx context.Context, request *GetRangeRequest) (interface{}, error) {
return c.GetRange(ctx, GetRangeRequestToGRPCMessage(request))
},
streamerConstructor: func(i interface{}) (GetRangeObjectStreamer, error) {
cli, ok := i.(object.ObjectService_GetRangeClient)
if !ok {
return nil, errors.New("can't convert interface to grpc get getClient")
}
return &getRangeObjectGRPCStream{
recv: func() (*GetRangeResponse, error) {
resp, err := cli.Recv()
if err != nil {
return nil, err
}
return GetRangeResponseFromGRPCMessage(resp), nil
},
}, nil
},
}
return cli
}
func newGRPCGetRangeHashClient(c *object.Client) *getRangeHashObjectClient {
return &getRangeHashObjectClient{
requestConverter: func(req *GetRangeHashRequest) interface{} {
return GetRangeHashRequestToGRPCMessage(req)
},
caller: func(ctx context.Context, req interface{}) (interface{}, error) {
return c.GetRangeHash(ctx, req.(*object.GetRangeHashRequest))
},
responseConverter: func(resp interface{}) *GetRangeHashResponse {
return GetRangeHashResponseFromGRPCMessage(resp.(*object.GetRangeHashResponse))
},
}
}
func WithGlobalOpts(v ...client.Option) Option {
return func(c *cfg) {
if len(v) > 0 {
c.globalOpts = v
}
}
}
func WithGRPCServiceClient(v object.ObjectServiceClient) Option {
return func(c *cfg) {
c.gRPC.serviceClient = v
}
}
func WithGRPCCallOpts(v []grpc.CallOption) Option {
return func(c *cfg) {
c.gRPC.grpcCallOpts = v
}
}
func WithGRPCClientOpts(v []object.Option) Option {
return func(c *cfg) {
c.gRPC.callOpts = v
}
}
func WithGRPCClient(v *object.Client) Option {
return func(c *cfg) {
c.gRPC.client = v
}
}

View file

@ -1,60 +0,0 @@
package object
type (
GetObjectStreamer interface {
Recv() (*GetResponse, error)
}
PutObjectStreamer interface {
Send(*PutRequest) error
CloseAndRecv() (*PutResponse, error)
}
SearchObjectStreamer interface {
Recv() (*SearchResponse, error)
}
GetRangeObjectStreamer interface {
Recv() (*GetRangeResponse, error)
}
)
type (
getObjectGRPCStream struct {
recv func() (*GetResponse, error)
}
putObjectGRPCStream struct {
send func(*PutRequest) error
closeAndRecv func() (*PutResponse, error)
}
searchObjectGRPCStream struct {
recv func() (*SearchResponse, error)
}
getRangeObjectGRPCStream struct {
recv func() (*GetRangeResponse, error)
}
)
func (s *getObjectGRPCStream) Recv() (*GetResponse, error) {
return s.recv()
}
func (p *putObjectGRPCStream) Send(request *PutRequest) error {
return p.send(request)
}
func (p *putObjectGRPCStream) CloseAndRecv() (*PutResponse, error) {
return p.closeAndRecv()
}
func (s *searchObjectGRPCStream) Recv() (*SearchResponse, error) {
return s.recv()
}
func (r *getRangeObjectGRPCStream) Recv() (*GetRangeResponse, error) {
return r.recv()
}

File diff suppressed because it is too large Load diff

View file

@ -1,146 +1,78 @@
package object package object
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
object "github.com/nspcc-dev/neofs-api-go/v2/object/grpc" object "github.com/nspcc-dev/neofs-api-go/v2/object/grpc"
"google.golang.org/protobuf/encoding/protojson"
) )
func (h *ShortHeader) MarshalJSON() ([]byte, error) { func (h *ShortHeader) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(h)
EmitUnpopulated: true,
}.Marshal(
ShortHeaderToGRPCMessage(h),
)
} }
func (h *ShortHeader) UnmarshalJSON(data []byte) error { func (h *ShortHeader) UnmarshalJSON(data []byte) error {
msg := new(object.ShortHeader) return message.UnmarshalJSON(h, data, new(object.ShortHeader))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*h = *ShortHeaderFromGRPCMessage(msg)
return nil
} }
func (a *Attribute) MarshalJSON() ([]byte, error) { func (a *Attribute) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(a)
EmitUnpopulated: true,
}.Marshal(
AttributeToGRPCMessage(a),
)
} }
func (a *Attribute) UnmarshalJSON(data []byte) error { func (a *Attribute) UnmarshalJSON(data []byte) error {
msg := new(object.Header_Attribute) return message.UnmarshalJSON(a, data, new(object.Header_Attribute))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*a = *AttributeFromGRPCMessage(msg)
return nil
} }
func (h *SplitHeader) MarshalJSON() ([]byte, error) { func (h *SplitHeader) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(h)
EmitUnpopulated: true,
}.Marshal(
SplitHeaderToGRPCMessage(h),
)
} }
func (h *SplitHeader) UnmarshalJSON(data []byte) error { func (h *SplitHeader) UnmarshalJSON(data []byte) error {
msg := new(object.Header_Split) return message.UnmarshalJSON(h, data, new(object.Header_Split))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*h = *SplitHeaderFromGRPCMessage(msg)
return nil
} }
func (h *Header) MarshalJSON() ([]byte, error) { func (h *Header) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(h)
EmitUnpopulated: true,
}.Marshal(
HeaderToGRPCMessage(h),
)
} }
func (h *Header) UnmarshalJSON(data []byte) error { func (h *Header) UnmarshalJSON(data []byte) error {
msg := new(object.Header) return message.UnmarshalJSON(h, data, new(object.Header))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*h = *HeaderFromGRPCMessage(msg)
return nil
} }
func (h *HeaderWithSignature) MarshalJSON() ([]byte, error) { func (h *HeaderWithSignature) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(h)
EmitUnpopulated: true,
}.Marshal(
HeaderWithSignatureToGRPCMessage(h),
)
} }
func (h *HeaderWithSignature) UnmarshalJSON(data []byte) error { func (h *HeaderWithSignature) UnmarshalJSON(data []byte) error {
msg := new(object.HeaderWithSignature) return message.UnmarshalJSON(h, data, new(object.HeaderWithSignature))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*h = *HeaderWithSignatureFromGRPCMessage(msg)
return nil
} }
func (o *Object) MarshalJSON() ([]byte, error) { func (o *Object) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(o)
EmitUnpopulated: true,
}.Marshal(
ObjectToGRPCMessage(o),
)
} }
func (o *Object) UnmarshalJSON(data []byte) error { func (o *Object) UnmarshalJSON(data []byte) error {
msg := new(object.Object) return message.UnmarshalJSON(o, data, new(object.Object))
}
if err := protojson.Unmarshal(data, msg); err != nil { func (s *SplitInfo) MarshalJSON() ([]byte, error) {
return err return message.MarshalJSON(s)
} }
*o = *ObjectFromGRPCMessage(msg) func (s *SplitInfo) UnmarshalJSON(data []byte) error {
return message.UnmarshalJSON(s, data, new(object.SplitInfo))
return nil
} }
func (f *SearchFilter) MarshalJSON() ([]byte, error) { func (f *SearchFilter) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(f)
EmitUnpopulated: true,
}.Marshal(
SearchFilterToGRPCMessage(f),
)
} }
func (f *SearchFilter) UnmarshalJSON(data []byte) error { func (f *SearchFilter) UnmarshalJSON(data []byte) error {
msg := new(object.SearchRequest_Body_Filter) return message.UnmarshalJSON(f, data, new(object.SearchRequest_Body_Filter))
}
if err := protojson.Unmarshal(data, msg); err != nil {
return err func (r *Range) MarshalJSON() ([]byte, error) {
} return message.MarshalJSON(r)
}
*f = *SearchFilterFromGRPCMessage(msg)
func (r *Range) UnmarshalJSON(data []byte) error {
return nil return message.UnmarshalJSON(r, data, new(object.Range))
} }

View file

@ -1,92 +0,0 @@
package object_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/object"
"github.com/stretchr/testify/require"
)
func TestShortHeaderJSON(t *testing.T) {
h := generateShortHeader("id")
data, err := h.MarshalJSON()
require.NoError(t, err)
h2 := new(object.ShortHeader)
require.NoError(t, h2.UnmarshalJSON(data))
require.Equal(t, h, h2)
}
func TestAttributeJSON(t *testing.T) {
a := generateAttribute("key", "value")
data, err := a.MarshalJSON()
require.NoError(t, err)
a2 := new(object.Attribute)
require.NoError(t, a2.UnmarshalJSON(data))
require.Equal(t, a, a2)
}
func TestSplitHeaderJSON(t *testing.T) {
h := generateSplit("sig")
data, err := h.MarshalJSON()
require.NoError(t, err)
h2 := new(object.SplitHeader)
require.NoError(t, h2.UnmarshalJSON(data))
require.Equal(t, h, h2)
}
func TestHeaderJSON(t *testing.T) {
h := generateHeader(10)
data, err := h.MarshalJSON()
require.NoError(t, err)
h2 := new(object.Header)
require.NoError(t, h2.UnmarshalJSON(data))
require.Equal(t, h, h2)
}
func TestHeaderWithSignatureJSON(t *testing.T) {
h := generateHeaderWithSignature()
data, err := h.MarshalJSON()
require.NoError(t, err)
h2 := new(object.HeaderWithSignature)
require.NoError(t, h2.UnmarshalJSON(data))
require.Equal(t, h, h2)
}
func TestObjectJSON(t *testing.T) {
o := generateObject("data")
data, err := o.MarshalJSON()
require.NoError(t, err)
o2 := new(object.Object)
require.NoError(t, o2.UnmarshalJSON(data))
require.Equal(t, o, o2)
}
func TestSearchFilterJSON(t *testing.T) {
f := generateFilter("key", "value")
data, err := f.MarshalJSON()
require.NoError(t, err)
f2 := new(object.SearchFilter)
require.NoError(t, f2.UnmarshalJSON(data))
require.Equal(t, f, f2)
}

View file

@ -1,10 +1,10 @@
package object package object
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
"github.com/nspcc-dev/neofs-api-go/util/proto" "github.com/nspcc-dev/neofs-api-go/util/proto"
object "github.com/nspcc-dev/neofs-api-go/v2/object/grpc" object "github.com/nspcc-dev/neofs-api-go/v2/object/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-api-go/v2/refs"
goproto "google.golang.org/protobuf/proto"
) )
const ( const (
@ -193,14 +193,7 @@ func (h *ShortHeader) StableSize() (size int) {
} }
func (h *ShortHeader) Unmarshal(data []byte) error { func (h *ShortHeader) Unmarshal(data []byte) error {
m := new(object.ShortHeader) return message.Unmarshal(h, data, new(object.ShortHeader))
if err := goproto.Unmarshal(data, m); err != nil {
return err
}
*h = *ShortHeaderFromGRPCMessage(m)
return nil
} }
func (a *Attribute) StableMarshal(buf []byte) ([]byte, error) { func (a *Attribute) StableMarshal(buf []byte) ([]byte, error) {
@ -244,14 +237,7 @@ func (a *Attribute) StableSize() (size int) {
} }
func (a *Attribute) Unmarshal(data []byte) error { func (a *Attribute) Unmarshal(data []byte) error {
m := new(object.Header_Attribute) return message.Unmarshal(a, data, new(object.Header_Attribute))
if err := goproto.Unmarshal(data, m); err != nil {
return err
}
*a = *AttributeFromGRPCMessage(m)
return nil
} }
func (h *SplitHeader) StableMarshal(buf []byte) ([]byte, error) { func (h *SplitHeader) StableMarshal(buf []byte) ([]byte, error) {
@ -327,14 +313,7 @@ func (h *SplitHeader) StableSize() (size int) {
} }
func (h *SplitHeader) Unmarshal(data []byte) error { func (h *SplitHeader) Unmarshal(data []byte) error {
m := new(object.Header_Split) return message.Unmarshal(h, data, new(object.Header_Split))
if err := goproto.Unmarshal(data, m); err != nil {
return err
}
*h = *SplitHeaderFromGRPCMessage(m)
return nil
} }
func (h *Header) StableMarshal(buf []byte) ([]byte, error) { func (h *Header) StableMarshal(buf []byte) ([]byte, error) {
@ -454,14 +433,7 @@ func (h *Header) StableSize() (size int) {
} }
func (h *Header) Unmarshal(data []byte) error { func (h *Header) Unmarshal(data []byte) error {
m := new(object.Header) return message.Unmarshal(h, data, new(object.Header))
if err := goproto.Unmarshal(data, m); err != nil {
return err
}
*h = *HeaderFromGRPCMessage(m)
return nil
} }
func (h *HeaderWithSignature) StableMarshal(buf []byte) ([]byte, error) { func (h *HeaderWithSignature) StableMarshal(buf []byte) ([]byte, error) {
@ -505,14 +477,7 @@ func (h *HeaderWithSignature) StableSize() (size int) {
} }
func (h *HeaderWithSignature) Unmarshal(data []byte) error { func (h *HeaderWithSignature) Unmarshal(data []byte) error {
m := new(object.HeaderWithSignature) return message.Unmarshal(h, data, new(object.HeaderWithSignature))
if err := goproto.Unmarshal(data, m); err != nil {
return err
}
*h = *HeaderWithSignatureFromGRPCMessage(m)
return nil
} }
func (o *Object) StableMarshal(buf []byte) ([]byte, error) { func (o *Object) StableMarshal(buf []byte) ([]byte, error) {
@ -571,30 +536,8 @@ func (o *Object) StableSize() (size int) {
return size return size
} }
func (o *Object) StableUnmarshal(data []byte) error {
if o == nil {
return nil
}
objGRPC := new(object.Object)
if err := goproto.Unmarshal(data, objGRPC); err != nil {
return err
}
*o = *ObjectFromGRPCMessage(objGRPC)
return nil
}
func (o *Object) Unmarshal(data []byte) error { func (o *Object) Unmarshal(data []byte) error {
m := new(object.Object) return message.Unmarshal(o, data, new(object.Object))
if err := goproto.Unmarshal(data, m); err != nil {
return err
}
*o = *ObjectFromGRPCMessage(m)
return nil
} }
func (s *SplitInfo) StableMarshal(buf []byte) ([]byte, error) { func (s *SplitInfo) StableMarshal(buf []byte) ([]byte, error) {
@ -646,14 +589,7 @@ func (s *SplitInfo) StableSize() (size int) {
} }
func (s *SplitInfo) Unmarshal(data []byte) error { func (s *SplitInfo) Unmarshal(data []byte) error {
m := new(object.SplitInfo) return message.Unmarshal(s, data, new(object.SplitInfo))
if err := goproto.Unmarshal(data, m); err != nil {
return err
}
*s = *SplitInfoFromGRPCMessage(m)
return nil
} }
func (r *GetRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (r *GetRequestBody) StableMarshal(buf []byte) ([]byte, error) {
@ -696,6 +632,10 @@ func (r *GetRequestBody) StableSize() (size int) {
return size return size
} }
func (r *GetRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(object.GetRequest_Body))
}
func (r *GetObjectPartInit) StableMarshal(buf []byte) ([]byte, error) { func (r *GetObjectPartInit) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -744,6 +684,10 @@ func (r *GetObjectPartInit) StableSize() (size int) {
return size return size
} }
func (r *GetObjectPartInit) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(object.GetResponse_Body_Init))
}
func (r *GetResponseBody) StableMarshal(buf []byte) ([]byte, error) { func (r *GetResponseBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -753,8 +697,8 @@ func (r *GetResponseBody) StableMarshal(buf []byte) ([]byte, error) {
buf = make([]byte, r.StableSize()) buf = make([]byte, r.StableSize())
} }
if r.objPart != nil {
switch v := r.objPart.(type) { switch v := r.objPart.(type) {
case nil:
case *GetObjectPartInit: case *GetObjectPartInit:
_, err := proto.NestedStructureMarshal(getRespBodyInitField, buf, v) _, err := proto.NestedStructureMarshal(getRespBodyInitField, buf, v)
if err != nil { if err != nil {
@ -775,7 +719,6 @@ func (r *GetResponseBody) StableMarshal(buf []byte) ([]byte, error) {
default: default:
panic("unknown one of object get response body type") panic("unknown one of object get response body type")
} }
}
return buf, nil return buf, nil
} }
@ -785,8 +728,8 @@ func (r *GetResponseBody) StableSize() (size int) {
return 0 return 0
} }
if r.objPart != nil {
switch v := r.objPart.(type) { switch v := r.objPart.(type) {
case nil:
case *GetObjectPartInit: case *GetObjectPartInit:
size += proto.NestedStructureSize(getRespBodyInitField, v) size += proto.NestedStructureSize(getRespBodyInitField, v)
case *GetObjectPartChunk: case *GetObjectPartChunk:
@ -798,9 +741,12 @@ func (r *GetResponseBody) StableSize() (size int) {
default: default:
panic("unknown one of object get response body type") panic("unknown one of object get response body type")
} }
}
return size return
}
func (r *GetResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(object.GetResponse_Body))
} }
func (r *PutObjectPartInit) StableMarshal(buf []byte) ([]byte, error) { func (r *PutObjectPartInit) StableMarshal(buf []byte) ([]byte, error) {
@ -859,6 +805,10 @@ func (r *PutObjectPartInit) StableSize() (size int) {
return size return size
} }
func (r *PutObjectPartInit) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(object.PutRequest_Body_Init))
}
func (r *PutRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (r *PutRequestBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -868,8 +818,8 @@ func (r *PutRequestBody) StableMarshal(buf []byte) ([]byte, error) {
buf = make([]byte, r.StableSize()) buf = make([]byte, r.StableSize())
} }
if r.objPart != nil {
switch v := r.objPart.(type) { switch v := r.objPart.(type) {
case nil:
case *PutObjectPartInit: case *PutObjectPartInit:
_, err := proto.NestedStructureMarshal(putReqBodyInitField, buf, v) _, err := proto.NestedStructureMarshal(putReqBodyInitField, buf, v)
if err != nil { if err != nil {
@ -885,7 +835,6 @@ func (r *PutRequestBody) StableMarshal(buf []byte) ([]byte, error) {
default: default:
panic("unknown one of object put request body type") panic("unknown one of object put request body type")
} }
}
return buf, nil return buf, nil
} }
@ -895,8 +844,8 @@ func (r *PutRequestBody) StableSize() (size int) {
return 0 return 0
} }
if r.objPart != nil {
switch v := r.objPart.(type) { switch v := r.objPart.(type) {
case nil:
case *PutObjectPartInit: case *PutObjectPartInit:
size += proto.NestedStructureSize(putReqBodyInitField, v) size += proto.NestedStructureSize(putReqBodyInitField, v)
case *PutObjectPartChunk: case *PutObjectPartChunk:
@ -906,11 +855,14 @@ func (r *PutRequestBody) StableSize() (size int) {
default: default:
panic("unknown one of object get response body type") panic("unknown one of object get response body type")
} }
}
return size return size
} }
func (r *PutRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(object.PutRequest_Body))
}
func (r *PutResponseBody) StableMarshal(buf []byte) ([]byte, error) { func (r *PutResponseBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -938,6 +890,10 @@ func (r *PutResponseBody) StableSize() (size int) {
return size return size
} }
func (r *PutResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(object.PutResponse_Body))
}
func (r *DeleteRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (r *DeleteRequestBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -965,6 +921,10 @@ func (r *DeleteRequestBody) StableSize() (size int) {
return size return size
} }
func (r *DeleteRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(object.DeleteRequest_Body))
}
func (r *DeleteResponseBody) StableMarshal(buf []byte) ([]byte, error) { func (r *DeleteResponseBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -992,6 +952,10 @@ func (r *DeleteResponseBody) StableSize() (size int) {
return size return size
} }
func (r *DeleteResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(object.DeleteResponse_Body))
}
func (r *HeadRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (r *HeadRequestBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -1040,6 +1004,10 @@ func (r *HeadRequestBody) StableSize() (size int) {
return size return size
} }
func (r *HeadRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(object.HeadRequest_Body))
}
func (r *HeadResponseBody) StableMarshal(buf []byte) ([]byte, error) { func (r *HeadResponseBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -1049,8 +1017,8 @@ func (r *HeadResponseBody) StableMarshal(buf []byte) ([]byte, error) {
buf = make([]byte, r.StableSize()) buf = make([]byte, r.StableSize())
} }
if r.hdrPart != nil {
switch v := r.hdrPart.(type) { switch v := r.hdrPart.(type) {
case nil:
case *HeaderWithSignature: case *HeaderWithSignature:
if v != nil { if v != nil {
_, err := proto.NestedStructureMarshal(headRespBodyHeaderField, buf, v) _, err := proto.NestedStructureMarshal(headRespBodyHeaderField, buf, v)
@ -1075,7 +1043,6 @@ func (r *HeadResponseBody) StableMarshal(buf []byte) ([]byte, error) {
default: default:
panic("unknown one of object put request body type") panic("unknown one of object put request body type")
} }
}
return buf, nil return buf, nil
} }
@ -1085,8 +1052,8 @@ func (r *HeadResponseBody) StableSize() (size int) {
return 0 return 0
} }
if r.hdrPart != nil {
switch v := r.hdrPart.(type) { switch v := r.hdrPart.(type) {
case nil:
case *HeaderWithSignature: case *HeaderWithSignature:
if v != nil { if v != nil {
size += proto.NestedStructureSize(headRespBodyHeaderField, v) size += proto.NestedStructureSize(headRespBodyHeaderField, v)
@ -1102,9 +1069,12 @@ func (r *HeadResponseBody) StableSize() (size int) {
default: default:
panic("unknown one of object put request body type") panic("unknown one of object put request body type")
} }
}
return size return
}
func (r *HeadResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(object.HeadResponse_Body))
} }
func (f *SearchFilter) StableMarshal(buf []byte) ([]byte, error) { func (f *SearchFilter) StableMarshal(buf []byte) ([]byte, error) {
@ -1155,6 +1125,10 @@ func (f *SearchFilter) StableSize() (size int) {
return size return size
} }
func (f *SearchFilter) Unmarshal(data []byte) error {
return message.Unmarshal(f, data, new(object.SearchRequest_Body_Filter))
}
func (r *SearchRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (r *SearchRequestBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -1210,6 +1184,10 @@ func (r *SearchRequestBody) StableSize() (size int) {
return size return size
} }
func (r *SearchRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(object.SearchRequest_Body))
}
func (r *SearchResponseBody) StableMarshal(buf []byte) ([]byte, error) { func (r *SearchResponseBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -1242,6 +1220,10 @@ func (r *SearchResponseBody) StableSize() (size int) {
return size return size
} }
func (r *SearchResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(object.SearchResponse_Body))
}
func (r *Range) StableMarshal(buf []byte) ([]byte, error) { func (r *Range) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -1282,6 +1264,10 @@ func (r *Range) StableSize() (size int) {
return size return size
} }
func (r *Range) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(object.Range))
}
func (r *GetRangeRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (r *GetRangeRequestBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -1330,6 +1316,10 @@ func (r *GetRangeRequestBody) StableSize() (size int) {
return size return size
} }
func (r *GetRangeRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(object.GetRangeRequest_Body))
}
func (r *GetRangeResponseBody) StableMarshal(buf []byte) ([]byte, error) { func (r *GetRangeResponseBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -1339,8 +1329,8 @@ func (r *GetRangeResponseBody) StableMarshal(buf []byte) ([]byte, error) {
buf = make([]byte, r.StableSize()) buf = make([]byte, r.StableSize())
} }
if r.rngPart != nil {
switch v := r.rngPart.(type) { switch v := r.rngPart.(type) {
case nil:
case *GetRangePartChunk: case *GetRangePartChunk:
if v != nil { if v != nil {
_, err := proto.BytesMarshal(getRangeRespChunkField, buf, v.chunk) _, err := proto.BytesMarshal(getRangeRespChunkField, buf, v.chunk)
@ -1358,7 +1348,6 @@ func (r *GetRangeResponseBody) StableMarshal(buf []byte) ([]byte, error) {
default: default:
panic("unknown one of object get range request body type") panic("unknown one of object get range request body type")
} }
}
return buf, nil return buf, nil
} }
@ -1368,8 +1357,8 @@ func (r *GetRangeResponseBody) StableSize() (size int) {
return 0 return 0
} }
if r.rngPart != nil {
switch v := r.rngPart.(type) { switch v := r.rngPart.(type) {
case nil:
case *GetRangePartChunk: case *GetRangePartChunk:
if v != nil { if v != nil {
size += proto.BytesSize(getRangeRespChunkField, v.chunk) size += proto.BytesSize(getRangeRespChunkField, v.chunk)
@ -1381,9 +1370,12 @@ func (r *GetRangeResponseBody) StableSize() (size int) {
default: default:
panic("unknown one of object get range request body type") panic("unknown one of object get range request body type")
} }
}
return size return
}
func (r *GetRangeResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(object.GetRangeResponse_Body))
} }
func (r *GetRangeHashRequestBody) StableMarshal(buf []byte) ([]byte, error) { func (r *GetRangeHashRequestBody) StableMarshal(buf []byte) ([]byte, error) {
@ -1448,6 +1440,10 @@ func (r *GetRangeHashRequestBody) StableSize() (size int) {
return size return size
} }
func (r *GetRangeHashRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(object.GetRangeHashRequest_Body))
}
func (r *GetRangeHashResponseBody) StableMarshal(buf []byte) ([]byte, error) { func (r *GetRangeHashResponseBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil { if r == nil {
return []byte{}, nil return []byte{}, nil
@ -1487,3 +1483,7 @@ func (r *GetRangeHashResponseBody) StableSize() (size int) {
return size return size
} }
func (r *GetRangeHashResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(r, data, new(object.GetRangeHashResponse_Body))
}

View file

@ -1,776 +0,0 @@
package object_test
import (
"fmt"
"strconv"
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/object"
grpc "github.com/nspcc-dev/neofs-api-go/v2/object/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-api-go/v2/session"
"github.com/stretchr/testify/require"
goproto "google.golang.org/protobuf/proto"
)
func TestShortHeader_StableMarshal(t *testing.T) {
hdrFrom := generateShortHeader("Owner ID")
t.Run("non empty", func(t *testing.T) {
wire, err := hdrFrom.StableMarshal(nil)
require.NoError(t, err)
hdrTo := new(object.ShortHeader)
require.NoError(t, hdrTo.Unmarshal(wire))
require.Equal(t, hdrFrom, hdrTo)
})
}
func TestAttribute_StableMarshal(t *testing.T) {
from := generateAttribute("Key", "Value")
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
to := new(object.Attribute)
require.NoError(t, to.Unmarshal(wire))
require.Equal(t, from, to)
})
}
func TestSplitHeader_StableMarshal(t *testing.T) {
from := generateSplit("Split Outside")
hdr := generateHeader(123)
from.SetParentHeader(hdr)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
to := new(object.SplitHeader)
require.NoError(t, to.Unmarshal(wire))
require.Equal(t, from, to)
})
}
func TestHeader_StableMarshal(t *testing.T) {
insideHeader := generateHeader(100)
split := generateSplit("Split")
split.SetParentHeader(insideHeader)
from := generateHeader(500)
from.SetSplit(split)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
to := new(object.Header)
require.NoError(t, to.Unmarshal(wire))
require.Equal(t, from, to)
})
}
func TestObject_StableMarshal(t *testing.T) {
from := generateObject("Payload")
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
to := new(object.Object)
require.NoError(t, to.Unmarshal(wire))
require.Equal(t, from, to)
})
}
func TestGetRequestBody_StableMarshal(t *testing.T) {
from := generateGetRequestBody("Container ID", "Object ID")
transport := new(grpc.GetRequest_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.GetRequestBodyFromGRPCMessage(transport)
require.Equal(t, from, to)
})
}
func TestGetResponseBody_StableMarshal(t *testing.T) {
initFrom := generateGetResponseBody(0)
chunkFrom := generateGetResponseBody(1)
splitInfoFrom := generateGetResponseBody(2)
transport := new(grpc.GetResponse_Body)
t.Run("init non empty", func(t *testing.T) {
wire, err := initFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.GetResponseBodyFromGRPCMessage(transport)
require.Equal(t, initFrom, to)
})
t.Run("chunk non empty", func(t *testing.T) {
wire, err := chunkFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.GetResponseBodyFromGRPCMessage(transport)
require.Equal(t, chunkFrom, to)
})
t.Run("split info non empty", func(t *testing.T) {
wire, err := splitInfoFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.GetResponseBodyFromGRPCMessage(transport)
require.Equal(t, splitInfoFrom, to)
})
}
func TestPutRequestBody_StableMarshal(t *testing.T) {
initFrom := generatePutRequestBody(true)
chunkFrom := generatePutRequestBody(false)
transport := new(grpc.PutRequest_Body)
t.Run("init non empty", func(t *testing.T) {
wire, err := initFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.PutRequestBodyFromGRPCMessage(transport)
require.Equal(t, initFrom, to)
})
t.Run("chunk non empty", func(t *testing.T) {
wire, err := chunkFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.PutRequestBodyFromGRPCMessage(transport)
require.Equal(t, chunkFrom, to)
})
}
func TestPutRequestBody_StableSize(t *testing.T) {
from := generatePutResponseBody("Object ID")
transport := new(grpc.PutResponse_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.PutResponseBodyFromGRPCMessage(transport)
require.Equal(t, from, to)
})
}
func TestDeleteRequestBody_StableMarshal(t *testing.T) {
from := generateDeleteRequestBody("Container ID", "Object ID")
transport := new(grpc.DeleteRequest_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.DeleteRequestBodyFromGRPCMessage(transport)
require.Equal(t, from, to)
})
}
func TestDeleteResponseBody_StableMarshal(t *testing.T) {
from := generateDeleteResponseBody("CID", "OID")
transport := new(grpc.DeleteResponse_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.DeleteResponseBodyFromGRPCMessage(transport)
require.Equal(t, from, to)
})
}
func TestSplitHeaderFromGRPCMessage(t *testing.T) {
from := generateHeadRequestBody("Container ID", "Object ID")
transport := new(grpc.HeadRequest_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.HeadRequestBodyFromGRPCMessage(transport)
require.Equal(t, from, to)
})
}
func TestHeadResponseBody_StableMarshal(t *testing.T) {
shortFrom := generateHeadResponseBody(0)
fullFrom := generateHeadResponseBody(1)
splitInfoFrom := generateHeadResponseBody(2)
transport := new(grpc.HeadResponse_Body)
t.Run("short header non empty", func(t *testing.T) {
wire, err := shortFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.HeadResponseBodyFromGRPCMessage(transport)
require.Equal(t, shortFrom, to)
})
t.Run("full header non empty", func(t *testing.T) {
wire, err := fullFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.HeadResponseBodyFromGRPCMessage(transport)
require.Equal(t, fullFrom, to)
})
t.Run("split info non empty", func(t *testing.T) {
wire, err := splitInfoFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.HeadResponseBodyFromGRPCMessage(transport)
require.Equal(t, splitInfoFrom, to)
})
}
func TestSearchRequestBody_StableMarshal(t *testing.T) {
from := generateSearchRequestBody(10, "Container ID")
transport := new(grpc.SearchRequest_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.SearchRequestBodyFromGRPCMessage(transport)
require.Equal(t, from, to)
})
}
func TestSearchResponseBody_StableMarshal(t *testing.T) {
from := generateSearchResponseBody(10)
transport := new(grpc.SearchResponse_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.SearchResponseBodyFromGRPCMessage(transport)
require.Equal(t, from, to)
})
}
func TestGetRangeRequestBody_StableMarshal(t *testing.T) {
from := generateRangeRequestBody("Container ID", "Object ID")
transport := new(grpc.GetRangeRequest_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.GetRangeRequestBodyFromGRPCMessage(transport)
require.Equal(t, from, to)
})
}
func TestGetRangeResponseBody_StableMarshal(t *testing.T) {
dataFrom := generateRangeResponseBody("some data", true)
splitInfoFrom := generateRangeResponseBody("some data", false)
transport := new(grpc.GetRangeResponse_Body)
t.Run("data non empty", func(t *testing.T) {
wire, err := dataFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.GetRangeResponseBodyFromGRPCMessage(transport)
require.Equal(t, dataFrom, to)
})
t.Run("split info non empty", func(t *testing.T) {
wire, err := splitInfoFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.GetRangeResponseBodyFromGRPCMessage(transport)
require.Equal(t, splitInfoFrom, to)
})
}
func TestGetRangeHashRequestBody_StableMarshal(t *testing.T) {
from := generateRangeHashRequestBody("Container ID", "Object ID", 5)
transport := new(grpc.GetRangeHashRequest_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.GetRangeHashRequestBodyFromGRPCMessage(transport)
require.Equal(t, from, to)
})
}
func TestGetRangeHashResponseBody_StableMarshal(t *testing.T) {
from := generateRangeHashResponseBody(5)
transport := new(grpc.GetRangeHashResponse_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
to := object.GetRangeHashResponseBodyFromGRPCMessage(transport)
require.Equal(t, from, to)
})
}
func TestHeaderWithSignature_StableMarshal(t *testing.T) {
from := generateHeaderWithSignature()
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
to := new(object.HeaderWithSignature)
require.NoError(t, to.Unmarshal(wire))
require.Equal(t, from, to)
})
}
func generateOwner(id string) *refs.OwnerID {
owner := new(refs.OwnerID)
owner.SetValue([]byte(id))
return owner
}
func generateObjectID(id string) *refs.ObjectID {
oid := new(refs.ObjectID)
oid.SetValue([]byte(id))
return oid
}
func generateContainerID(id string) *refs.ContainerID {
cid := new(refs.ContainerID)
cid.SetValue([]byte(id))
return cid
}
func generateSignature(k, v string) *refs.Signature {
sig := new(refs.Signature)
sig.SetKey([]byte(k))
sig.SetSign([]byte(v))
return sig
}
func generateVersion(maj, min uint32) *refs.Version {
version := new(refs.Version)
version.SetMajor(maj)
version.SetMinor(min)
return version
}
func generateAddress(cid, oid string) *refs.Address {
addr := new(refs.Address)
addr.SetObjectID(generateObjectID(oid))
addr.SetContainerID(generateContainerID(cid))
return addr
}
func generateSessionToken(id string) *session.SessionToken {
lifetime := new(session.TokenLifetime)
lifetime.SetExp(1)
lifetime.SetNbf(2)
lifetime.SetIat(3)
objectCtx := new(session.ObjectSessionContext)
objectCtx.SetVerb(session.ObjectVerbPut)
objectCtx.SetAddress(generateAddress("Container ID", "Object ID"))
tokenBody := new(session.SessionTokenBody)
tokenBody.SetID([]byte(id))
tokenBody.SetOwnerID(generateOwner("Owner ID"))
tokenBody.SetSessionKey([]byte(id))
tokenBody.SetLifetime(lifetime)
tokenBody.SetContext(objectCtx)
sessionToken := new(session.SessionToken)
sessionToken.SetBody(tokenBody)
sessionToken.SetSignature(generateSignature("public key", id))
return sessionToken
}
func generateShortHeader(id string) *object.ShortHeader {
hdr := new(object.ShortHeader)
hdr.SetOwnerID(generateOwner(id))
hdr.SetVersion(generateVersion(2, 0))
hdr.SetCreationEpoch(200)
hdr.SetObjectType(object.TypeRegular)
hdr.SetPayloadLength(10)
hdr.SetPayloadHash(generateChecksum("payload hash"))
hdr.SetHomomorphicHash(generateChecksum("homomorphic hash"))
return hdr
}
func generateAttribute(k, v string) *object.Attribute {
attr := new(object.Attribute)
attr.SetValue(v)
attr.SetKey(k)
return attr
}
func generateSplit(sig string) *object.SplitHeader {
split := new(object.SplitHeader)
split.SetChildren([]*refs.ObjectID{
generateObjectID("Child 1"),
generateObjectID("Child 2"),
})
split.SetParent(generateObjectID("Parent"))
split.SetParentSignature(generateSignature("Key", sig))
split.SetPrevious(generateObjectID("Previous"))
split.SetSplitID([]byte("UUIDv4"))
return split
}
func generateChecksum(data string) *refs.Checksum {
checksum := new(refs.Checksum)
checksum.SetType(refs.TillichZemor)
checksum.SetSum([]byte(data))
return checksum
}
func generateHeader(ln uint64) *object.Header {
hdr := new(object.Header)
hdr.SetPayloadLength(ln)
hdr.SetCreationEpoch(ln / 2)
hdr.SetVersion(generateVersion(2, 0))
hdr.SetOwnerID(generateOwner("Owner ID"))
hdr.SetContainerID(generateContainerID("Contanier ID"))
hdr.SetAttributes([]*object.Attribute{
generateAttribute("One", "Two"),
generateAttribute("Three", "Four"),
})
hdr.SetHomomorphicHash(generateChecksum("Homomorphic Hash"))
hdr.SetObjectType(object.TypeRegular)
hdr.SetPayloadHash(generateChecksum("Payload Hash"))
hdr.SetSessionToken(generateSessionToken(strconv.Itoa(int(ln))))
return hdr
}
func generateObject(data string) *object.Object {
insideHeader := generateHeader(100)
split := generateSplit("Split")
split.SetParentHeader(insideHeader)
outsideHeader := generateHeader(500)
outsideHeader.SetSplit(split)
obj := new(object.Object)
obj.SetSignature(generateSignature("Public Key", "Signature"))
obj.SetObjectID(generateObjectID("Object ID"))
obj.SetPayload([]byte(data))
obj.SetHeader(outsideHeader)
return obj
}
func generateGetRequestBody(cid, oid string) *object.GetRequestBody {
req := new(object.GetRequestBody)
req.SetAddress(generateAddress(cid, oid))
req.SetRaw(true)
return req
}
func generateGetResponseBody(i int) *object.GetResponseBody {
resp := new(object.GetResponseBody)
var part object.GetObjectPart
switch i {
case 0:
init := new(object.GetObjectPartInit)
init.SetObjectID(generateObjectID("Object ID"))
init.SetSignature(generateSignature("Key", "Signature"))
init.SetHeader(generateHeader(10))
part = init
case 1:
chunk := new(object.GetObjectPartChunk)
chunk.SetChunk([]byte("Some data chunk"))
part = chunk
default:
part = generateSplitInfo()
}
resp.SetObjectPart(part)
return resp
}
func generatePutRequestBody(flag bool) *object.PutRequestBody {
req := new(object.PutRequestBody)
var part object.PutObjectPart
if flag {
init := new(object.PutObjectPartInit)
init.SetObjectID(generateObjectID("Object ID"))
init.SetSignature(generateSignature("Key", "Signature"))
init.SetHeader(generateHeader(10))
init.SetCopiesNumber(1)
part = init
} else {
chunk := new(object.PutObjectPartChunk)
chunk.SetChunk([]byte("Some data chunk"))
part = chunk
}
req.SetObjectPart(part)
return req
}
func generatePutResponseBody(oid string) *object.PutResponseBody {
resp := new(object.PutResponseBody)
resp.SetObjectID(generateObjectID(oid))
return resp
}
func generateDeleteRequestBody(cid, oid string) *object.DeleteRequestBody {
req := new(object.DeleteRequestBody)
req.SetAddress(generateAddress(cid, oid))
return req
}
func generateDeleteResponseBody(cid, oid string) *object.DeleteResponseBody {
resp := new(object.DeleteResponseBody)
resp.SetTombstone(generateAddress(cid, oid))
return resp
}
func generateHeadRequestBody(cid, oid string) *object.HeadRequestBody {
req := new(object.HeadRequestBody)
req.SetAddress(generateAddress(cid, oid))
req.SetRaw(true)
req.SetMainOnly(true)
return req
}
func generateHeadResponseBody(flag int) *object.HeadResponseBody {
req := new(object.HeadResponseBody)
var part object.GetHeaderPart
switch flag {
case 0:
part = generateShortHeader("short id")
case 1:
part = generateHeaderWithSignature()
default:
part = generateSplitInfo()
}
req.SetHeaderPart(part)
return req
}
func generateHeaderWithSignature() *object.HeaderWithSignature {
hdrWithSig := new(object.HeaderWithSignature)
hdrWithSig.SetHeader(generateHeader(30))
hdrWithSig.SetSignature(generateSignature("sig", "key"))
return hdrWithSig
}
func generateFilter(k, v string) *object.SearchFilter {
f := new(object.SearchFilter)
f.SetKey(k)
f.SetValue(v)
f.SetMatchType(object.MatchStringEqual)
return f
}
func generateSearchRequestBody(n int, id string) *object.SearchRequestBody {
req := new(object.SearchRequestBody)
req.SetContainerID(generateContainerID(id))
req.SetVersion(1)
ff := make([]*object.SearchFilter, n)
for i := 0; i < n; i++ {
ff[i] = generateFilter("Some Key", fmt.Sprintf("Value %d", i+1))
}
req.SetFilters(ff)
return req
}
func generateSearchResponseBody(n int) *object.SearchResponseBody {
resp := new(object.SearchResponseBody)
list := make([]*refs.ObjectID, n)
for i := 0; i < n; i++ {
list[i] = generateObjectID(fmt.Sprintf("Object ID %d", i+1))
}
resp.SetIDList(list)
return resp
}
func generateRange(off, ln uint64) *object.Range {
r := new(object.Range)
r.SetOffset(off)
r.SetLength(ln)
return r
}
func generateRangeRequestBody(cid, oid string) *object.GetRangeRequestBody {
req := new(object.GetRangeRequestBody)
req.SetAddress(generateAddress(cid, oid))
req.SetRange(generateRange(10, 20))
req.SetRaw(true)
return req
}
func generateRangeResponseBody(data string, flag bool) *object.GetRangeResponseBody {
resp := new(object.GetRangeResponseBody)
if flag {
p := new(object.GetRangePartChunk)
p.SetChunk([]byte(data))
resp.SetRangePart(p)
} else {
resp.SetRangePart(generateSplitInfo())
}
return resp
}
func generateRangeHashRequestBody(cid, oid string, n int) *object.GetRangeHashRequestBody {
req := new(object.GetRangeHashRequestBody)
req.SetAddress(generateAddress(cid, oid))
rngs := make([]*object.Range, n)
for i := 0; i < n; i++ {
rngs[i] = generateRange(100, 200+uint64(n))
}
req.SetRanges(rngs)
req.SetSalt([]byte("xor salt"))
req.SetType(refs.TillichZemor)
return req
}
func generateRangeHashResponseBody(n int) *object.GetRangeHashResponseBody {
resp := new(object.GetRangeHashResponseBody)
list := make([][]byte, n)
for i := 0; i < n; i++ {
list[i] = []byte("Some homomorphic hash data" + strconv.Itoa(n))
}
resp.SetType(refs.TillichZemor)
resp.SetHashList(list)
return resp
}
func TestObject_StableUnmarshal(t *testing.T) {
obj := generateObject("some data")
data, err := obj.StableMarshal(nil)
require.NoError(t, err)
obj2 := new(object.Object)
require.NoError(t, obj2.StableUnmarshal(data))
require.Equal(t, obj, obj2)
}
func generateSplitInfo() *object.SplitInfo {
splitInfo := new(object.SplitInfo)
splitInfo.SetSplitID([]byte("splitID"))
splitInfo.SetLastPart(generateObjectID("Right ID"))
splitInfo.SetLink(generateObjectID("Link ID"))
return splitInfo
}

54
v2/object/message_test.go Normal file
View file

@ -0,0 +1,54 @@
package object_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/rpc/message"
messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test"
objecttest "github.com/nspcc-dev/neofs-api-go/v2/object/test"
)
func TestMessageConvert(t *testing.T) {
messagetest.TestRPCMessage(t,
func(empty bool) message.Message { return objecttest.GenerateShortHeader(empty) },
func(empty bool) message.Message { return objecttest.GenerateAttribute(empty) },
func(empty bool) message.Message { return objecttest.GenerateSplitHeader(empty) },
func(empty bool) message.Message { return objecttest.GenerateHeader(empty) },
func(empty bool) message.Message { return objecttest.GenerateObject(empty) },
func(empty bool) message.Message { return objecttest.GenerateSplitInfo(empty) },
func(empty bool) message.Message { return objecttest.GenerateGetRequestBody(empty) },
func(empty bool) message.Message { return objecttest.GenerateGetRequest(empty) },
func(empty bool) message.Message { return objecttest.GenerateGetObjectPartInit(empty) },
func(empty bool) message.Message { return objecttest.GenerateGetObjectPartChunk(empty) },
func(empty bool) message.Message { return objecttest.GenerateGetResponseBody(empty) },
func(empty bool) message.Message { return objecttest.GenerateGetResponse(empty) },
func(empty bool) message.Message { return objecttest.GeneratePutObjectPartInit(empty) },
func(empty bool) message.Message { return objecttest.GeneratePutObjectPartChunk(empty) },
func(empty bool) message.Message { return objecttest.GeneratePutRequestBody(empty) },
func(empty bool) message.Message { return objecttest.GeneratePutRequest(empty) },
func(empty bool) message.Message { return objecttest.GeneratePutResponseBody(empty) },
func(empty bool) message.Message { return objecttest.GeneratePutResponse(empty) },
func(empty bool) message.Message { return objecttest.GenerateDeleteRequestBody(empty) },
func(empty bool) message.Message { return objecttest.GenerateDeleteRequest(empty) },
func(empty bool) message.Message { return objecttest.GenerateDeleteResponseBody(empty) },
func(empty bool) message.Message { return objecttest.GenerateDeleteResponse(empty) },
func(empty bool) message.Message { return objecttest.GenerateHeadRequestBody(empty) },
func(empty bool) message.Message { return objecttest.GenerateHeadRequest(empty) },
func(empty bool) message.Message { return objecttest.GenerateHeadResponseBody(empty) },
func(empty bool) message.Message { return objecttest.GenerateHeadResponse(empty) },
func(empty bool) message.Message { return objecttest.GenerateSearchFilter(empty) },
func(empty bool) message.Message { return objecttest.GenerateSearchRequestBody(empty) },
func(empty bool) message.Message { return objecttest.GenerateSearchRequest(empty) },
func(empty bool) message.Message { return objecttest.GenerateSearchResponseBody(empty) },
func(empty bool) message.Message { return objecttest.GenerateSearchResponse(empty) },
func(empty bool) message.Message { return objecttest.GenerateRange(empty) },
func(empty bool) message.Message { return objecttest.GenerateGetRangeRequestBody(empty) },
func(empty bool) message.Message { return objecttest.GenerateGetRangeRequest(empty) },
func(empty bool) message.Message { return objecttest.GenerateGetRangeResponseBody(empty) },
func(empty bool) message.Message { return objecttest.GenerateGetRangeResponse(empty) },
func(empty bool) message.Message { return objecttest.GenerateGetRangeHashRequestBody(empty) },
func(empty bool) message.Message { return objecttest.GenerateGetRangeHashRequest(empty) },
func(empty bool) message.Message { return objecttest.GenerateGetRangeHashResponseBody(empty) },
func(empty bool) message.Message { return objecttest.GenerateGetRangeHashResponse(empty) },
)
}

View file

@ -1,129 +0,0 @@
package object
import (
"context"
"github.com/nspcc-dev/neofs-api-go/v2/session"
)
type Service interface {
Get(context.Context, *GetRequest) (GetObjectStreamer, error)
Put(context.Context) (PutObjectStreamer, error)
Head(context.Context, *HeadRequest) (*HeadResponse, error)
Search(context.Context, *SearchRequest) (SearchObjectStreamer, error)
Delete(context.Context, *DeleteRequest) (*DeleteResponse, error)
GetRange(context.Context, *GetRangeRequest) (GetRangeObjectStreamer, error)
GetRangeHash(context.Context, *GetRangeHashRequest) (*GetRangeHashResponse, error)
}
type GetRequest struct {
body *GetRequestBody
metaHeader *session.RequestMetaHeader
verifyHeader *session.RequestVerificationHeader
}
type GetResponse struct {
body *GetResponseBody
metaHeader *session.ResponseMetaHeader
verifyHeader *session.ResponseVerificationHeader
}
type PutRequest struct {
body *PutRequestBody
metaHeader *session.RequestMetaHeader
verifyHeader *session.RequestVerificationHeader
}
type PutResponse struct {
body *PutResponseBody
metaHeader *session.ResponseMetaHeader
verifyHeader *session.ResponseVerificationHeader
}
type DeleteRequest struct {
body *DeleteRequestBody
metaHeader *session.RequestMetaHeader
verifyHeader *session.RequestVerificationHeader
}
type DeleteResponse struct {
body *DeleteResponseBody
metaHeader *session.ResponseMetaHeader
verifyHeader *session.ResponseVerificationHeader
}
type HeadRequest struct {
body *HeadRequestBody
metaHeader *session.RequestMetaHeader
verifyHeader *session.RequestVerificationHeader
}
type HeadResponse struct {
body *HeadResponseBody
metaHeader *session.ResponseMetaHeader
verifyHeader *session.ResponseVerificationHeader
}
type SearchRequest struct {
body *SearchRequestBody
metaHeader *session.RequestMetaHeader
verifyHeader *session.RequestVerificationHeader
}
type SearchResponse struct {
body *SearchResponseBody
metaHeader *session.ResponseMetaHeader
verifyHeader *session.ResponseVerificationHeader
}
type GetRangeRequest struct {
body *GetRangeRequestBody
metaHeader *session.RequestMetaHeader
verifyHeader *session.RequestVerificationHeader
}
type GetRangeResponse struct {
body *GetRangeResponseBody
metaHeader *session.ResponseMetaHeader
verifyHeader *session.ResponseVerificationHeader
}
type GetRangeHashRequest struct {
body *GetRangeHashRequestBody
metaHeader *session.RequestMetaHeader
verifyHeader *session.RequestVerificationHeader
}
type GetRangeHashResponse struct {
body *GetRangeHashResponseBody
metaHeader *session.ResponseMetaHeader
verifyHeader *session.ResponseVerificationHeader
}

View file

@ -1,471 +0,0 @@
package main
import (
"context"
"crypto/ecdsa"
"errors"
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/object"
objectGRPC "github.com/nspcc-dev/neofs-api-go/v2/object/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-api-go/v2/session"
"github.com/nspcc-dev/neofs-api-go/v2/signature"
"github.com/nspcc-dev/neofs-crypto/test"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
)
type testGRPCClient struct {
server objectGRPC.ObjectServiceServer
}
func (s *testGRPCClient) Get(ctx context.Context, in *objectGRPC.GetRequest, opts ...grpc.CallOption) (objectGRPC.ObjectService_GetClient, error) {
panic("implement me")
}
func (s *testGRPCClient) Put(ctx context.Context, opts ...grpc.CallOption) (objectGRPC.ObjectService_PutClient, error) {
panic("implement me")
}
func (s *testGRPCClient) Delete(ctx context.Context, in *objectGRPC.DeleteRequest, opts ...grpc.CallOption) (*objectGRPC.DeleteResponse, error) {
return s.server.Delete(ctx, in)
}
func (s *testGRPCClient) Head(ctx context.Context, in *objectGRPC.HeadRequest, opts ...grpc.CallOption) (*objectGRPC.HeadResponse, error) {
return s.server.Head(ctx, in)
}
func (s *testGRPCClient) Search(ctx context.Context, in *objectGRPC.SearchRequest, opts ...grpc.CallOption) (objectGRPC.ObjectService_SearchClient, error) {
panic("implement me")
}
func (s *testGRPCClient) GetRange(ctx context.Context, in *objectGRPC.GetRangeRequest, opts ...grpc.CallOption) (objectGRPC.ObjectService_GetRangeClient, error) {
panic("implement me")
}
func (s *testGRPCClient) GetRangeHash(ctx context.Context, in *objectGRPC.GetRangeHashRequest, opts ...grpc.CallOption) (*objectGRPC.GetRangeHashResponse, error) {
return s.server.GetRangeHash(ctx, in)
}
type testGRPCServer struct {
key *ecdsa.PrivateKey
headResp *object.HeadResponse
delResp *object.DeleteResponse
getRangeHashResp *object.GetRangeHashResponse
err error
}
func (s *testGRPCServer) Get(request *objectGRPC.GetRequest, server objectGRPC.ObjectService_GetServer) error {
panic("implement me")
}
func (s *testGRPCServer) Put(server objectGRPC.ObjectService_PutServer) error {
panic("implement me")
}
func (s *testGRPCServer) Delete(ctx context.Context, request *objectGRPC.DeleteRequest) (*objectGRPC.DeleteResponse, error) {
if s.err != nil {
return nil, s.err
}
// verify request structure
if err := signature.VerifyServiceMessage(
object.DeleteRequestFromGRPCMessage(request),
); err != nil {
return nil, err
}
// sign response structure
if err := signature.SignServiceMessage(s.key, s.delResp); err != nil {
return nil, err
}
return object.DeleteResponseToGRPCMessage(s.delResp), nil
}
func (s *testGRPCServer) Head(ctx context.Context, request *objectGRPC.HeadRequest) (*objectGRPC.HeadResponse, error) {
if s.err != nil {
return nil, s.err
}
// verify request structure
if err := signature.VerifyServiceMessage(
object.HeadRequestFromGRPCMessage(request),
); err != nil {
return nil, err
}
// sign response structure
if err := signature.SignServiceMessage(s.key, s.headResp); err != nil {
return nil, err
}
return object.HeadResponseToGRPCMessage(s.headResp), nil
}
func (s *testGRPCServer) Search(request *objectGRPC.SearchRequest, server objectGRPC.ObjectService_SearchServer) error {
panic("implement me")
}
func (s *testGRPCServer) GetRange(request *objectGRPC.GetRangeRequest, server objectGRPC.ObjectService_GetRangeServer) error {
panic("implement me")
}
func (s *testGRPCServer) GetRangeHash(ctx context.Context, request *objectGRPC.GetRangeHashRequest) (*objectGRPC.GetRangeHashResponse, error) {
if s.err != nil {
return nil, s.err
}
// verify request structure
if err := signature.VerifyServiceMessage(
object.GetRangeHashRequestFromGRPCMessage(request),
); err != nil {
return nil, err
}
// sign response structure
if err := signature.SignServiceMessage(s.key, s.getRangeHashResp); err != nil {
return nil, err
}
return object.GetRangeHashResponseToGRPCMessage(s.getRangeHashResp), nil
}
func testHeadRequest() *object.HeadRequest {
cid := new(refs.ContainerID)
cid.SetValue([]byte{1, 2, 3})
oid := new(refs.ObjectID)
oid.SetValue([]byte{4, 5, 6})
addr := new(refs.Address)
addr.SetContainerID(cid)
addr.SetObjectID(oid)
body := new(object.HeadRequestBody)
body.SetAddress(addr)
meta := new(session.RequestMetaHeader)
meta.SetTTL(1)
meta.SetXHeaders([]*session.XHeader{})
req := new(object.HeadRequest)
req.SetBody(body)
req.SetMetaHeader(meta)
return req
}
func testHeadResponse() *object.HeadResponse {
shortHdr := new(object.ShortHeader)
shortHdr.SetCreationEpoch(100)
body := new(object.HeadResponseBody)
body.SetHeaderPart(shortHdr)
meta := new(session.ResponseMetaHeader)
meta.SetTTL(1)
meta.SetXHeaders([]*session.XHeader{})
resp := new(object.HeadResponse)
resp.SetBody(body)
resp.SetMetaHeader(meta)
return resp
}
func testDeleteRequest() *object.DeleteRequest {
cid := new(refs.ContainerID)
cid.SetValue([]byte{1, 2, 3})
oid := new(refs.ObjectID)
oid.SetValue([]byte{4, 5, 6})
addr := new(refs.Address)
addr.SetContainerID(cid)
addr.SetObjectID(oid)
body := new(object.DeleteRequestBody)
body.SetAddress(addr)
meta := new(session.RequestMetaHeader)
meta.SetTTL(1)
meta.SetXHeaders([]*session.XHeader{})
req := new(object.DeleteRequest)
req.SetBody(body)
req.SetMetaHeader(meta)
return req
}
func testDeleteResponse() *object.DeleteResponse {
body := new(object.DeleteResponseBody)
meta := new(session.ResponseMetaHeader)
meta.SetTTL(1)
meta.SetXHeaders([]*session.XHeader{})
resp := new(object.DeleteResponse)
resp.SetBody(body)
resp.SetMetaHeader(meta)
return resp
}
func testGetRangeHashRequest() *object.GetRangeHashRequest {
cid := new(refs.ContainerID)
cid.SetValue([]byte{1, 2, 3})
oid := new(refs.ObjectID)
oid.SetValue([]byte{4, 5, 6})
addr := new(refs.Address)
addr.SetContainerID(cid)
addr.SetObjectID(oid)
body := new(object.GetRangeHashRequestBody)
body.SetAddress(addr)
meta := new(session.RequestMetaHeader)
meta.SetTTL(1)
meta.SetXHeaders([]*session.XHeader{})
req := new(object.GetRangeHashRequest)
req.SetBody(body)
req.SetMetaHeader(meta)
return req
}
func testGetRangeHashResponse() *object.GetRangeHashResponse {
body := new(object.GetRangeHashResponseBody)
body.SetHashList([][]byte{{7, 8, 9}})
meta := new(session.ResponseMetaHeader)
meta.SetTTL(1)
meta.SetXHeaders([]*session.XHeader{})
resp := new(object.GetRangeHashResponse)
resp.SetBody(body)
resp.SetMetaHeader(meta)
return resp
}
func TestGRPCClient_Head(t *testing.T) {
ctx := context.TODO()
cliKey := test.DecodeKey(0)
srvKey := test.DecodeKey(1)
t.Run("gRPC server error", func(t *testing.T) {
srvErr := errors.New("test server error")
srv := &testGRPCServer{
err: srvErr,
}
cli := &testGRPCClient{
server: srv,
}
c, err := object.NewClient(object.WithGRPCServiceClient(cli))
require.NoError(t, err)
resp, err := c.Head(ctx, new(object.HeadRequest))
require.True(t, errors.Is(err, srvErr))
require.Nil(t, resp)
})
t.Run("invalid request structure", func(t *testing.T) {
req := testHeadRequest()
require.Error(t, signature.VerifyServiceMessage(req))
c, err := object.NewClient(
object.WithGRPCServiceClient(
&testGRPCClient{
server: new(testGRPCServer),
},
),
)
require.NoError(t, err)
resp, err := c.Head(ctx, req)
require.Error(t, err)
require.Nil(t, resp)
})
t.Run("correct response", func(t *testing.T) {
req := testHeadRequest()
require.NoError(t, signature.SignServiceMessage(cliKey, req))
resp := testHeadResponse()
c, err := object.NewClient(
object.WithGRPCServiceClient(
&testGRPCClient{
server: &testGRPCServer{
key: srvKey,
headResp: resp,
},
},
),
)
require.NoError(t, err)
r, err := c.Head(ctx, req)
require.NoError(t, err)
require.NoError(t, signature.VerifyServiceMessage(r))
require.Equal(t, resp.GetBody(), r.GetBody())
require.Equal(t, resp.GetMetaHeader(), r.GetMetaHeader())
})
}
func TestGRPCClient_Delete(t *testing.T) {
ctx := context.TODO()
cliKey := test.DecodeKey(0)
srvKey := test.DecodeKey(1)
t.Run("gRPC server error", func(t *testing.T) {
srvErr := errors.New("test server error")
srv := &testGRPCServer{
err: srvErr,
}
cli := &testGRPCClient{
server: srv,
}
c, err := object.NewClient(object.WithGRPCServiceClient(cli))
require.NoError(t, err)
resp, err := c.Delete(ctx, new(object.DeleteRequest))
require.True(t, errors.Is(err, srvErr))
require.Nil(t, resp)
})
t.Run("invalid request structure", func(t *testing.T) {
req := testDeleteRequest()
require.Error(t, signature.VerifyServiceMessage(req))
c, err := object.NewClient(
object.WithGRPCServiceClient(
&testGRPCClient{
server: new(testGRPCServer),
},
),
)
require.NoError(t, err)
resp, err := c.Delete(ctx, req)
require.Error(t, err)
require.Nil(t, resp)
})
t.Run("correct response", func(t *testing.T) {
req := testDeleteRequest()
require.NoError(t, signature.SignServiceMessage(cliKey, req))
resp := testDeleteResponse()
c, err := object.NewClient(
object.WithGRPCServiceClient(
&testGRPCClient{
server: &testGRPCServer{
key: srvKey,
delResp: resp,
},
},
),
)
require.NoError(t, err)
r, err := c.Delete(ctx, req)
require.NoError(t, err)
require.NoError(t, signature.VerifyServiceMessage(r))
require.Equal(t, resp.GetBody(), r.GetBody())
require.Equal(t, resp.GetMetaHeader(), r.GetMetaHeader())
})
}
func TestGRPCClient_GetRangeHash(t *testing.T) {
ctx := context.TODO()
cliKey := test.DecodeKey(0)
srvKey := test.DecodeKey(1)
t.Run("gRPC server error", func(t *testing.T) {
srvErr := errors.New("test server error")
srv := &testGRPCServer{
err: srvErr,
}
cli := &testGRPCClient{
server: srv,
}
c, err := object.NewClient(object.WithGRPCServiceClient(cli))
require.NoError(t, err)
resp, err := c.GetRangeHash(ctx, new(object.GetRangeHashRequest))
require.True(t, errors.Is(err, srvErr))
require.Nil(t, resp)
})
t.Run("invalid request structure", func(t *testing.T) {
req := testGetRangeHashRequest()
require.Error(t, signature.VerifyServiceMessage(req))
c, err := object.NewClient(
object.WithGRPCServiceClient(
&testGRPCClient{
server: new(testGRPCServer),
},
),
)
require.NoError(t, err)
resp, err := c.GetRangeHash(ctx, req)
require.Error(t, err)
require.Nil(t, resp)
})
t.Run("correct response", func(t *testing.T) {
req := testGetRangeHashRequest()
require.NoError(t, signature.SignServiceMessage(cliKey, req))
resp := testGetRangeHashResponse()
c, err := object.NewClient(
object.WithGRPCServiceClient(
&testGRPCClient{
server: &testGRPCServer{
key: srvKey,
getRangeHashResp: resp,
},
},
),
)
require.NoError(t, err)
r, err := c.GetRangeHash(ctx, req)
require.NoError(t, err)
require.NoError(t, signature.VerifyServiceMessage(r))
require.Equal(t, resp.GetBody(), r.GetBody())
require.Equal(t, resp.GetMetaHeader(), r.GetMetaHeader())
})
}

512
v2/object/test/generate.go Normal file
View file

@ -0,0 +1,512 @@
package objecttest
import (
"github.com/nspcc-dev/neofs-api-go/v2/object"
refstest "github.com/nspcc-dev/neofs-api-go/v2/refs/test"
sessiontest "github.com/nspcc-dev/neofs-api-go/v2/session/test"
)
func GenerateShortHeader(empty bool) *object.ShortHeader {
m := new(object.ShortHeader)
if !empty {
m.SetObjectType(13)
m.SetCreationEpoch(100)
m.SetPayloadLength(12321)
}
m.SetVersion(refstest.GenerateVersion(empty))
m.SetOwnerID(refstest.GenerateOwnerID(empty))
m.SetHomomorphicHash(refstest.GenerateChecksum(empty))
m.SetPayloadHash(refstest.GenerateChecksum(empty))
return m
}
func GenerateAttribute(empty bool) *object.Attribute {
m := new(object.Attribute)
if !empty {
m.SetKey("object key")
m.SetValue("object value")
}
return m
}
func GenerateAttributes(empty bool) (res []*object.Attribute) {
if !empty {
res = append(res,
GenerateAttribute(false),
GenerateAttribute(false),
)
}
return
}
func GenerateSplitHeader(empty bool) *object.SplitHeader {
return generateSplitHeader(empty, true)
}
func generateSplitHeader(empty, withPar bool) *object.SplitHeader {
m := new(object.SplitHeader)
if !empty {
m.SetSplitID([]byte{1, 3, 5})
}
m.SetParent(refstest.GenerateObjectID(empty))
m.SetPrevious(refstest.GenerateObjectID(empty))
m.SetParentSignature(refstest.GenerateSignature(empty))
m.SetChildren(refstest.GenerateObjectIDs(empty))
if withPar {
m.SetParentHeader(generateHeader(empty, false))
}
return m
}
func GenerateHeader(empty bool) *object.Header {
return generateHeader(empty, true)
}
func generateHeader(empty, withSplit bool) *object.Header {
m := new(object.Header)
if !empty {
m.SetPayloadLength(777)
m.SetCreationEpoch(432)
m.SetObjectType(111)
}
m.SetVersion(refstest.GenerateVersion(empty))
m.SetPayloadHash(refstest.GenerateChecksum(empty))
m.SetOwnerID(refstest.GenerateOwnerID(empty))
m.SetHomomorphicHash(refstest.GenerateChecksum(empty))
m.SetContainerID(refstest.GenerateContainerID(empty))
m.SetSessionToken(sessiontest.GenerateSessionToken(empty))
m.SetAttributes(GenerateAttributes(empty))
if withSplit {
m.SetSplit(generateSplitHeader(empty, false))
}
return m
}
func GenerateHeaderWithSignature(empty bool) *object.HeaderWithSignature {
m := new(object.HeaderWithSignature)
m.SetSignature(refstest.GenerateSignature(empty))
m.SetHeader(GenerateHeader(empty))
return m
}
func GenerateObject(empty bool) *object.Object {
m := new(object.Object)
if !empty {
m.SetPayload([]byte{7, 8, 9})
}
m.SetObjectID(refstest.GenerateObjectID(empty))
m.SetSignature(refstest.GenerateSignature(empty))
m.SetHeader(GenerateHeader(empty))
return m
}
func GenerateSplitInfo(empty bool) *object.SplitInfo {
m := new(object.SplitInfo)
if !empty {
m.SetSplitID([]byte("splitID"))
}
m.SetLastPart(refstest.GenerateObjectID(empty))
m.SetLink(refstest.GenerateObjectID(empty))
return m
}
func GenerateGetRequestBody(empty bool) *object.GetRequestBody {
m := new(object.GetRequestBody)
if !empty {
m.SetRaw(true)
}
m.SetAddress(refstest.GenerateAddress(empty))
return m
}
func GenerateGetRequest(empty bool) *object.GetRequest {
m := new(object.GetRequest)
m.SetBody(GenerateGetRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateGetObjectPartInit(empty bool) *object.GetObjectPartInit {
m := new(object.GetObjectPartInit)
m.SetObjectID(refstest.GenerateObjectID(empty))
m.SetSignature(refstest.GenerateSignature(empty))
m.SetHeader(GenerateHeader(empty))
return m
}
func GenerateGetObjectPartChunk(empty bool) *object.GetObjectPartChunk {
m := new(object.GetObjectPartChunk)
if !empty {
m.SetChunk([]byte("get chunk"))
}
return m
}
func GenerateGetResponseBody(empty bool) *object.GetResponseBody {
m := new(object.GetResponseBody)
m.SetObjectPart(GenerateGetObjectPartInit(empty))
return m
}
func GenerateGetResponse(empty bool) *object.GetResponse {
m := new(object.GetResponse)
m.SetBody(GenerateGetResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GeneratePutObjectPartInit(empty bool) *object.PutObjectPartInit {
m := new(object.PutObjectPartInit)
if !empty {
m.SetCopiesNumber(234)
}
m.SetObjectID(refstest.GenerateObjectID(empty))
m.SetSignature(refstest.GenerateSignature(empty))
m.SetHeader(GenerateHeader(empty))
return m
}
func GeneratePutObjectPartChunk(empty bool) *object.PutObjectPartChunk {
m := new(object.PutObjectPartChunk)
if !empty {
m.SetChunk([]byte("put chunk"))
}
return m
}
func GeneratePutRequestBody(empty bool) *object.PutRequestBody {
m := new(object.PutRequestBody)
m.SetObjectPart(GeneratePutObjectPartInit(empty))
return m
}
func GeneratePutRequest(empty bool) *object.PutRequest {
m := new(object.PutRequest)
m.SetBody(GeneratePutRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GeneratePutResponseBody(empty bool) *object.PutResponseBody {
m := new(object.PutResponseBody)
m.SetObjectID(refstest.GenerateObjectID(empty))
return m
}
func GeneratePutResponse(empty bool) *object.PutResponse {
m := new(object.PutResponse)
m.SetBody(GeneratePutResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateDeleteRequestBody(empty bool) *object.DeleteRequestBody {
m := new(object.DeleteRequestBody)
m.SetAddress(refstest.GenerateAddress(empty))
return m
}
func GenerateDeleteRequest(empty bool) *object.DeleteRequest {
m := new(object.DeleteRequest)
m.SetBody(GenerateDeleteRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateDeleteResponseBody(empty bool) *object.DeleteResponseBody {
m := new(object.DeleteResponseBody)
m.SetTombstone(refstest.GenerateAddress(empty))
return m
}
func GenerateDeleteResponse(empty bool) *object.DeleteResponse {
m := new(object.DeleteResponse)
m.SetBody(GenerateDeleteResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateHeadRequestBody(empty bool) *object.HeadRequestBody {
m := new(object.HeadRequestBody)
if !empty {
m.SetRaw(true)
m.SetMainOnly(true)
}
m.SetAddress(refstest.GenerateAddress(empty))
return m
}
func GenerateHeadRequest(empty bool) *object.HeadRequest {
m := new(object.HeadRequest)
m.SetBody(GenerateHeadRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateHeadResponseBody(empty bool) *object.HeadResponseBody {
m := new(object.HeadResponseBody)
m.SetHeaderPart(GenerateHeaderWithSignature(empty))
return m
}
func GenerateHeadResponse(empty bool) *object.HeadResponse {
m := new(object.HeadResponse)
m.SetBody(GenerateHeadResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateSearchFilter(empty bool) *object.SearchFilter {
m := new(object.SearchFilter)
if !empty {
m.SetKey("search filter key")
m.SetValue("search filter val")
m.SetMatchType(987)
}
return m
}
func GenerateSearchFilters(empty bool) (res []*object.SearchFilter) {
if !empty {
res = append(res,
GenerateSearchFilter(false),
GenerateSearchFilter(false),
)
}
return
}
func GenerateSearchRequestBody(empty bool) *object.SearchRequestBody {
m := new(object.SearchRequestBody)
if !empty {
m.SetVersion(555)
}
m.SetContainerID(refstest.GenerateContainerID(empty))
m.SetFilters(GenerateSearchFilters(empty))
return m
}
func GenerateSearchRequest(empty bool) *object.SearchRequest {
m := new(object.SearchRequest)
m.SetBody(GenerateSearchRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateSearchResponseBody(empty bool) *object.SearchResponseBody {
m := new(object.SearchResponseBody)
m.SetIDList(refstest.GenerateObjectIDs(empty))
return m
}
func GenerateSearchResponse(empty bool) *object.SearchResponse {
m := new(object.SearchResponse)
m.SetBody(GenerateSearchResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateRange(empty bool) *object.Range {
m := new(object.Range)
if !empty {
m.SetLength(11)
m.SetOffset(22)
}
return m
}
func GenerateRanges(empty bool) (res []*object.Range) {
if !empty {
res = append(res,
GenerateRange(false),
GenerateRange(false),
)
}
return
}
func GenerateGetRangeRequestBody(empty bool) *object.GetRangeRequestBody {
m := new(object.GetRangeRequestBody)
if !empty {
m.SetRaw(true)
}
m.SetAddress(refstest.GenerateAddress(empty))
m.SetRange(GenerateRange(empty))
return m
}
func GenerateGetRangeRequest(empty bool) *object.GetRangeRequest {
m := new(object.GetRangeRequest)
m.SetBody(GenerateGetRangeRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateGetRangePartChunk(empty bool) *object.GetRangePartChunk {
m := new(object.GetRangePartChunk)
if !empty {
m.SetChunk([]byte("get range chunk"))
}
return m
}
func GenerateGetRangeResponseBody(empty bool) *object.GetRangeResponseBody {
m := new(object.GetRangeResponseBody)
m.SetRangePart(GenerateGetRangePartChunk(empty))
return m
}
func GenerateGetRangeResponse(empty bool) *object.GetRangeResponse {
m := new(object.GetRangeResponse)
m.SetBody(GenerateGetRangeResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}
func GenerateGetRangeHashRequestBody(empty bool) *object.GetRangeHashRequestBody {
m := new(object.GetRangeHashRequestBody)
if !empty {
m.SetSalt([]byte("range hash salt"))
m.SetType(455)
}
m.SetAddress(refstest.GenerateAddress(empty))
m.SetRanges(GenerateRanges(empty))
return m
}
func GenerateGetRangeHashRequest(empty bool) *object.GetRangeHashRequest {
m := new(object.GetRangeHashRequest)
m.SetBody(GenerateGetRangeHashRequestBody(empty))
m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))
return m
}
func GenerateGetRangeHashResponseBody(empty bool) *object.GetRangeHashResponseBody {
m := new(object.GetRangeHashResponseBody)
if !empty {
m.SetType(678)
m.SetHashList([][]byte{{1}, {2}})
}
return m
}
func GenerateGetRangeHashResponse(empty bool) *object.GetRangeHashResponse {
m := new(object.GetRangeHashResponse)
m.SetBody(GenerateGetRangeHashResponseBody(empty))
m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))
return m
}

View file

@ -107,6 +107,12 @@ type GetObjectPartChunk struct {
chunk []byte chunk []byte
} }
type GetRequest struct {
body *GetRequestBody
session.RequestHeaders
}
type GetResponseBody struct { type GetResponseBody struct {
objPart GetObjectPart objPart GetObjectPart
} }
@ -129,22 +135,52 @@ type PutObjectPartChunk struct {
chunk []byte chunk []byte
} }
type GetResponse struct {
body *GetResponseBody
session.ResponseHeaders
}
type PutRequestBody struct { type PutRequestBody struct {
objPart PutObjectPart objPart PutObjectPart
} }
type PutRequest struct {
body *PutRequestBody
session.RequestHeaders
}
type PutResponseBody struct { type PutResponseBody struct {
id *refs.ObjectID id *refs.ObjectID
} }
type PutResponse struct {
body *PutResponseBody
session.ResponseHeaders
}
type DeleteRequestBody struct { type DeleteRequestBody struct {
addr *refs.Address addr *refs.Address
} }
type DeleteRequest struct {
body *DeleteRequestBody
session.RequestHeaders
}
type DeleteResponseBody struct { type DeleteResponseBody struct {
tombstone *refs.Address tombstone *refs.Address
} }
type DeleteResponse struct {
body *DeleteResponseBody
session.ResponseHeaders
}
type HeadRequestBody struct { type HeadRequestBody struct {
addr *refs.Address addr *refs.Address
@ -155,10 +191,22 @@ type GetHeaderPart interface {
getHeaderPart() getHeaderPart()
} }
type HeadRequest struct {
body *HeadRequestBody
session.RequestHeaders
}
type HeadResponseBody struct { type HeadResponseBody struct {
hdrPart GetHeaderPart hdrPart GetHeaderPart
} }
type HeadResponse struct {
body *HeadResponseBody
session.ResponseHeaders
}
type SearchFilter struct { type SearchFilter struct {
matchType MatchType matchType MatchType
@ -173,10 +221,22 @@ type SearchRequestBody struct {
filters []*SearchFilter filters []*SearchFilter
} }
type SearchRequest struct {
body *SearchRequestBody
session.RequestHeaders
}
type SearchResponseBody struct { type SearchResponseBody struct {
idList []*refs.ObjectID idList []*refs.ObjectID
} }
type SearchResponse struct {
body *SearchResponseBody
session.ResponseHeaders
}
type Range struct { type Range struct {
off, len uint64 off, len uint64
} }
@ -189,6 +249,12 @@ type GetRangeRequestBody struct {
raw bool raw bool
} }
type GetRangeRequest struct {
body *GetRangeRequestBody
session.RequestHeaders
}
type GetRangePart interface { type GetRangePart interface {
getRangePart() getRangePart()
} }
@ -201,6 +267,12 @@ type GetRangeResponseBody struct {
rngPart GetRangePart rngPart GetRangePart
} }
type GetRangeResponse struct {
body *GetRangeResponseBody
session.ResponseHeaders
}
type GetRangeHashRequestBody struct { type GetRangeHashRequestBody struct {
addr *refs.Address addr *refs.Address
@ -211,12 +283,24 @@ type GetRangeHashRequestBody struct {
typ refs.ChecksumType typ refs.ChecksumType
} }
type GetRangeHashRequest struct {
body *GetRangeHashRequestBody
session.RequestHeaders
}
type GetRangeHashResponseBody struct { type GetRangeHashResponseBody struct {
typ refs.ChecksumType typ refs.ChecksumType
hashList [][]byte hashList [][]byte
} }
type GetRangeHashResponse struct {
body *GetRangeHashResponseBody
session.ResponseHeaders
}
const ( const (
TypeRegular Type = iota TypeRegular Type = iota
TypeTombstone TypeTombstone
@ -772,34 +856,6 @@ func (r *GetRequest) SetBody(v *GetRequestBody) {
} }
} }
func (r *GetRequest) GetMetaHeader() *session.RequestMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *GetRequest) SetMetaHeader(v *session.RequestMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *GetRequest) GetVerificationHeader() *session.RequestVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *GetRequest) SetVerificationHeader(v *session.RequestVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *GetObjectPartInit) GetObjectID() *refs.ObjectID { func (r *GetObjectPartInit) GetObjectID() *refs.ObjectID {
if r != nil { if r != nil {
return r.id return r.id
@ -888,34 +944,6 @@ func (r *GetResponse) SetBody(v *GetResponseBody) {
} }
} }
func (r *GetResponse) GetMetaHeader() *session.ResponseMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *GetResponse) SetMetaHeader(v *session.ResponseMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *GetResponse) GetVerificationHeader() *session.ResponseVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *GetResponse) SetVerificationHeader(v *session.ResponseVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *PutObjectPartInit) GetObjectID() *refs.ObjectID { func (r *PutObjectPartInit) GetObjectID() *refs.ObjectID {
if r != nil { if r != nil {
return r.id return r.id
@ -1018,34 +1046,6 @@ func (r *PutRequest) SetBody(v *PutRequestBody) {
} }
} }
func (r *PutRequest) GetMetaHeader() *session.RequestMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *PutRequest) SetMetaHeader(v *session.RequestMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *PutRequest) GetVerificationHeader() *session.RequestVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *PutRequest) SetVerificationHeader(v *session.RequestVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *PutResponseBody) GetObjectID() *refs.ObjectID { func (r *PutResponseBody) GetObjectID() *refs.ObjectID {
if r != nil { if r != nil {
return r.id return r.id
@ -1074,34 +1074,6 @@ func (r *PutResponse) SetBody(v *PutResponseBody) {
} }
} }
func (r *PutResponse) GetMetaHeader() *session.ResponseMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *PutResponse) SetMetaHeader(v *session.ResponseMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *PutResponse) GetVerificationHeader() *session.ResponseVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *PutResponse) SetVerificationHeader(v *session.ResponseVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *DeleteRequestBody) GetAddress() *refs.Address { func (r *DeleteRequestBody) GetAddress() *refs.Address {
if r != nil { if r != nil {
return r.addr return r.addr
@ -1130,34 +1102,6 @@ func (r *DeleteRequest) SetBody(v *DeleteRequestBody) {
} }
} }
func (r *DeleteRequest) GetMetaHeader() *session.RequestMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *DeleteRequest) SetMetaHeader(v *session.RequestMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *DeleteRequest) GetVerificationHeader() *session.RequestVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *DeleteRequest) SetVerificationHeader(v *session.RequestVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
// GetTombstone returns tombstone address. // GetTombstone returns tombstone address.
func (r *DeleteResponseBody) GetTombstone() *refs.Address { func (r *DeleteResponseBody) GetTombstone() *refs.Address {
if r != nil { if r != nil {
@ -1188,34 +1132,6 @@ func (r *DeleteResponse) SetBody(v *DeleteResponseBody) {
} }
} }
func (r *DeleteResponse) GetMetaHeader() *session.ResponseMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *DeleteResponse) SetMetaHeader(v *session.ResponseMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *DeleteResponse) GetVerificationHeader() *session.ResponseVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *DeleteResponse) SetVerificationHeader(v *session.ResponseVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *HeadRequestBody) GetAddress() *refs.Address { func (r *HeadRequestBody) GetAddress() *refs.Address {
if r != nil { if r != nil {
return r.addr return r.addr
@ -1272,34 +1188,6 @@ func (r *HeadRequest) SetBody(v *HeadRequestBody) {
} }
} }
func (r *HeadRequest) GetMetaHeader() *session.RequestMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *HeadRequest) SetMetaHeader(v *session.RequestMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *HeadRequest) GetVerificationHeader() *session.RequestVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *HeadRequest) SetVerificationHeader(v *session.RequestVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *HeadResponseBody) GetHeaderPart() GetHeaderPart { func (r *HeadResponseBody) GetHeaderPart() GetHeaderPart {
if r != nil { if r != nil {
return r.hdrPart return r.hdrPart
@ -1328,34 +1216,6 @@ func (r *HeadResponse) SetBody(v *HeadResponseBody) {
} }
} }
func (r *HeadResponse) GetMetaHeader() *session.ResponseMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *HeadResponse) SetMetaHeader(v *session.ResponseMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *HeadResponse) GetVerificationHeader() *session.ResponseVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *HeadResponse) SetVerificationHeader(v *session.ResponseVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (f *SearchFilter) GetMatchType() MatchType { func (f *SearchFilter) GetMatchType() MatchType {
if f != nil { if f != nil {
return f.matchType return f.matchType
@ -1454,34 +1314,6 @@ func (r *SearchRequest) SetBody(v *SearchRequestBody) {
} }
} }
func (r *SearchRequest) GetMetaHeader() *session.RequestMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *SearchRequest) SetMetaHeader(v *session.RequestMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *SearchRequest) GetVerificationHeader() *session.RequestVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *SearchRequest) SetVerificationHeader(v *session.RequestVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *SearchResponseBody) GetIDList() []*refs.ObjectID { func (r *SearchResponseBody) GetIDList() []*refs.ObjectID {
if r != nil { if r != nil {
return r.idList return r.idList
@ -1510,34 +1342,6 @@ func (r *SearchResponse) SetBody(v *SearchResponseBody) {
} }
} }
func (r *SearchResponse) GetMetaHeader() *session.ResponseMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *SearchResponse) SetMetaHeader(v *session.ResponseMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *SearchResponse) GetVerificationHeader() *session.ResponseVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *SearchResponse) SetVerificationHeader(v *session.ResponseVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *Range) GetOffset() uint64 { func (r *Range) GetOffset() uint64 {
if r != nil { if r != nil {
return r.off return r.off
@ -1622,34 +1426,6 @@ func (r *GetRangeRequest) SetBody(v *GetRangeRequestBody) {
} }
} }
func (r *GetRangeRequest) GetMetaHeader() *session.RequestMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *GetRangeRequest) SetMetaHeader(v *session.RequestMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *GetRangeRequest) GetVerificationHeader() *session.RequestVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *GetRangeRequest) SetVerificationHeader(v *session.RequestVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *GetRangePartChunk) GetChunk() []byte { func (r *GetRangePartChunk) GetChunk() []byte {
if r != nil { if r != nil {
return r.chunk return r.chunk
@ -1694,34 +1470,6 @@ func (r *GetRangeResponse) SetBody(v *GetRangeResponseBody) {
} }
} }
func (r *GetRangeResponse) GetMetaHeader() *session.ResponseMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *GetRangeResponse) SetMetaHeader(v *session.ResponseMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *GetRangeResponse) GetVerificationHeader() *session.ResponseVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *GetRangeResponse) SetVerificationHeader(v *session.ResponseVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *GetRangeHashRequestBody) GetAddress() *refs.Address { func (r *GetRangeHashRequestBody) GetAddress() *refs.Address {
if r != nil { if r != nil {
return r.addr return r.addr
@ -1792,34 +1540,6 @@ func (r *GetRangeHashRequest) SetBody(v *GetRangeHashRequestBody) {
} }
} }
func (r *GetRangeHashRequest) GetMetaHeader() *session.RequestMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *GetRangeHashRequest) SetMetaHeader(v *session.RequestMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *GetRangeHashRequest) GetVerificationHeader() *session.RequestVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *GetRangeHashRequest) SetVerificationHeader(v *session.RequestVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}
func (r *GetRangeHashResponseBody) GetType() refs.ChecksumType { func (r *GetRangeHashResponseBody) GetType() refs.ChecksumType {
if r != nil { if r != nil {
return r.typ return r.typ
@ -1861,31 +1581,3 @@ func (r *GetRangeHashResponse) SetBody(v *GetRangeHashResponseBody) {
r.body = v r.body = v
} }
} }
func (r *GetRangeHashResponse) GetMetaHeader() *session.ResponseMetaHeader {
if r != nil {
return r.metaHeader
}
return nil
}
func (r *GetRangeHashResponse) SetMetaHeader(v *session.ResponseMetaHeader) {
if r != nil {
r.metaHeader = v
}
}
func (r *GetRangeHashResponse) GetVerificationHeader() *session.ResponseVerificationHeader {
if r != nil {
return r.verifyHeader
}
return nil
}
func (r *GetRangeHashResponse) SetVerificationHeader(v *session.ResponseVerificationHeader) {
if r != nil {
r.verifyHeader = v
}
}

View file

@ -1,221 +1,278 @@
package refs package refs
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/grpc"
"github.com/nspcc-dev/neofs-api-go/rpc/message"
refs "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc" refs "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
) )
func OwnerIDToGRPCMessage(o *OwnerID) *refs.OwnerID { func (o *OwnerID) ToGRPCMessage() grpc.Message {
if o == nil { var m *refs.OwnerID
return nil
if o != nil {
m = new(refs.OwnerID)
m.SetValue(o.val)
} }
m := new(refs.OwnerID)
m.SetValue(o.GetValue())
return m return m
} }
func OwnerIDFromGRPCMessage(m *refs.OwnerID) *OwnerID { func (o *OwnerID) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*refs.OwnerID)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
o := new(OwnerID) o.val = v.GetValue()
o.SetValue(m.GetValue()) return nil
return o
} }
func ContainerIDToGRPCMessage(c *ContainerID) *refs.ContainerID { func (c *ContainerID) ToGRPCMessage() grpc.Message {
if c == nil { var m *refs.ContainerID
return nil
if c != nil {
m = new(refs.ContainerID)
m.SetValue(c.val)
} }
m := new(refs.ContainerID)
m.SetValue(c.GetValue())
return m return m
} }
func ContainerIDFromGRPCMessage(m *refs.ContainerID) *ContainerID { func (c *ContainerID) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*refs.ContainerID)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
c := new(ContainerID) c.val = v.GetValue()
c.SetValue(m.GetValue()) return nil
return c
} }
func ObjectIDToGRPCMessage(o *ObjectID) *refs.ObjectID { func ContainerIDsToGRPCMessage(ids []*ContainerID) (res []*refs.ContainerID) {
if o == nil { if ids != nil {
return nil res = make([]*refs.ContainerID, 0, len(ids))
}
m := new(refs.ObjectID)
m.SetValue(o.GetValue())
return m
}
func ObjectIDFromGRPCMessage(m *refs.ObjectID) *ObjectID {
if m == nil {
return nil
}
o := new(ObjectID)
o.SetValue(m.GetValue())
return o
}
func ObjectIDListToGRPCMessage(ids []*ObjectID) []*refs.ObjectID {
if ids == nil {
return nil
}
idsV2 := make([]*refs.ObjectID, 0, len(ids))
for i := range ids { for i := range ids {
idsV2 = append(idsV2, ObjectIDToGRPCMessage(ids[i])) res = append(res, ids[i].ToGRPCMessage().(*refs.ContainerID))
}
} }
return idsV2 return
} }
func ObjectIDListFromGRPCMessage(idsV2 []*refs.ObjectID) []*ObjectID { func ContainerIDsFromGRPCMessage(idsV2 []*refs.ContainerID) (res []*ContainerID, err error) {
if idsV2 == nil { if idsV2 != nil {
return nil res = make([]*ContainerID, 0, len(idsV2))
}
ids := make([]*ObjectID, 0, len(idsV2))
for i := range idsV2 { for i := range idsV2 {
ids = append(ids, ObjectIDFromGRPCMessage(idsV2[i])) var id *ContainerID
if idsV2[i] != nil {
id = new(ContainerID)
err = id.FromGRPCMessage(idsV2[i])
if err != nil {
return
}
} }
return ids res = append(res, id)
}
}
return
} }
func AddressToGRPCMessage(a *Address) *refs.Address { func (o *ObjectID) ToGRPCMessage() grpc.Message {
if a == nil { var m *refs.ObjectID
return nil
if o != nil {
m = new(refs.ObjectID)
m.SetValue(o.val)
} }
m := new(refs.Address)
m.SetContainerId(
ContainerIDToGRPCMessage(a.GetContainerID()),
)
m.SetObjectId(
ObjectIDToGRPCMessage(a.GetObjectID()),
)
return m return m
} }
func AddressFromGRPCMessage(m *refs.Address) *Address { func (o *ObjectID) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*refs.ObjectID)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
a := new(Address) o.val = v.GetValue()
a.SetContainerID( return nil
ContainerIDFromGRPCMessage(m.GetContainerId()),
)
a.SetObjectID(
ObjectIDFromGRPCMessage(m.GetObjectId()),
)
return a
} }
func ChecksumToGRPCMessage(c *Checksum) *refs.Checksum { func ObjectIDListToGRPCMessage(ids []*ObjectID) (res []*refs.ObjectID) {
if c == nil { if ids != nil {
return nil res = make([]*refs.ObjectID, 0, len(ids))
for i := range ids {
res = append(res, ids[i].ToGRPCMessage().(*refs.ObjectID))
}
} }
m := new(refs.Checksum) return
}
m.SetChecksumType(refs.ChecksumType(c.GetType())) func ObjectIDListFromGRPCMessage(idsV2 []*refs.ObjectID) (res []*ObjectID, err error) {
if idsV2 != nil {
res = make([]*ObjectID, 0, len(idsV2))
m.SetSum(c.GetSum()) for i := range idsV2 {
var id *ObjectID
if idsV2[i] != nil {
id = new(ObjectID)
err = id.FromGRPCMessage(idsV2[i])
if err != nil {
return
}
}
res = append(res, id)
}
}
return
}
func (a *Address) ToGRPCMessage() grpc.Message {
var m *refs.Address
if a != nil {
m = new(refs.Address)
m.SetContainerId(a.cid.ToGRPCMessage().(*refs.ContainerID))
m.SetObjectId(a.oid.ToGRPCMessage().(*refs.ObjectID))
}
return m return m
} }
func ChecksumFromGRPCMessage(m *refs.Checksum) *Checksum { func (a *Address) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*refs.Address)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
c := new(Checksum) var err error
c.SetType(ChecksumType(m.GetType())) cid := v.GetContainerId()
if cid == nil {
a.cid = nil
} else {
if a.cid == nil {
a.cid = new(ContainerID)
}
c.SetSum(m.GetSum()) err = a.cid.FromGRPCMessage(cid)
if err != nil {
return err
}
}
return c oid := v.GetObjectId()
if oid == nil {
a.oid = nil
} else {
if a.oid == nil {
a.oid = new(ObjectID)
}
err = a.oid.FromGRPCMessage(oid)
}
return err
} }
func VersionToGRPCMessage(v *Version) *refs.Version { func ChecksumTypeToGRPC(t ChecksumType) refs.ChecksumType {
if v == nil { return refs.ChecksumType(t)
return nil
}
msg := new(refs.Version)
msg.SetMajor(v.GetMajor())
msg.SetMinor(v.GetMinor())
return msg
} }
func VersionFromGRPCMessage(m *refs.Version) *Version { func ChecksumTypeFromGRPC(t refs.ChecksumType) ChecksumType {
if m == nil { return ChecksumType(t)
return nil
}
v := new(Version)
v.SetMajor(m.GetMajor())
v.SetMinor(m.GetMinor())
return v
} }
func SignatureToGRPCMessage(s *Signature) *refs.Signature { func (c *Checksum) ToGRPCMessage() grpc.Message {
if s == nil { var m *refs.Checksum
return nil
if c != nil {
m = new(refs.Checksum)
m.SetChecksumType(ChecksumTypeToGRPC(c.typ))
m.SetSum(c.sum)
} }
m := new(refs.Signature)
m.SetKey(s.GetKey())
m.SetSign(s.GetSign())
return m return m
} }
func SignatureFromGRPCMessage(m *refs.Signature) *Signature { func (c *Checksum) FromGRPCMessage(m grpc.Message) error {
if m == nil { v, ok := m.(*refs.Checksum)
return nil if !ok {
return message.NewUnexpectedMessageType(m, v)
} }
s := new(Signature) c.typ = ChecksumTypeFromGRPC(v.GetType())
c.sum = v.GetSum()
s.SetKey(m.GetKey()) return nil
s.SetSign(m.GetSign()) }
return s func (v *Version) ToGRPCMessage() grpc.Message {
var m *refs.Version
if v != nil {
m = new(refs.Version)
m.SetMajor(v.major)
m.SetMinor(v.minor)
}
return m
}
func (v *Version) FromGRPCMessage(m grpc.Message) error {
ver, ok := m.(*refs.Version)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
v.major = ver.GetMajor()
v.minor = ver.GetMinor()
return nil
}
func (s *Signature) ToGRPCMessage() grpc.Message {
var m *refs.Signature
if s != nil {
m = new(refs.Signature)
m.SetKey(s.key)
m.SetSign(s.sign)
}
return m
}
func (s *Signature) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*refs.Signature)
if !ok {
return message.NewUnexpectedMessageType(m, s)
}
s.key = v.GetKey()
s.sign = v.GetSign()
return nil
} }

View file

@ -1,146 +1,62 @@
package refs package refs
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
refs "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc" refs "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
"google.golang.org/protobuf/encoding/protojson"
) )
func (a *Address) MarshalJSON() ([]byte, error) { func (a *Address) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(a)
EmitUnpopulated: true,
}.Marshal(
AddressToGRPCMessage(a),
)
} }
func (a *Address) UnmarshalJSON(data []byte) error { func (a *Address) UnmarshalJSON(data []byte) error {
msg := new(refs.Address) return message.UnmarshalJSON(a, data, new(refs.Address))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*a = *AddressFromGRPCMessage(msg)
return nil
} }
func (o *ObjectID) MarshalJSON() ([]byte, error) { func (o *ObjectID) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(o)
EmitUnpopulated: true,
}.Marshal(
ObjectIDToGRPCMessage(o),
)
} }
func (o *ObjectID) UnmarshalJSON(data []byte) error { func (o *ObjectID) UnmarshalJSON(data []byte) error {
msg := new(refs.ObjectID) return message.UnmarshalJSON(o, data, new(refs.ObjectID))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*o = *ObjectIDFromGRPCMessage(msg)
return nil
} }
func (c *ContainerID) MarshalJSON() ([]byte, error) { func (c *ContainerID) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(c)
EmitUnpopulated: true,
}.Marshal(
ContainerIDToGRPCMessage(c),
)
} }
func (c *ContainerID) UnmarshalJSON(data []byte) error { func (c *ContainerID) UnmarshalJSON(data []byte) error {
msg := new(refs.ContainerID) return message.UnmarshalJSON(c, data, new(refs.ContainerID))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*c = *ContainerIDFromGRPCMessage(msg)
return nil
} }
func (o *OwnerID) MarshalJSON() ([]byte, error) { func (o *OwnerID) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(o)
EmitUnpopulated: true,
}.Marshal(
OwnerIDToGRPCMessage(o),
)
} }
func (o *OwnerID) UnmarshalJSON(data []byte) error { func (o *OwnerID) UnmarshalJSON(data []byte) error {
msg := new(refs.OwnerID) return message.UnmarshalJSON(o, data, new(refs.OwnerID))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*o = *OwnerIDFromGRPCMessage(msg)
return nil
} }
func (v *Version) MarshalJSON() ([]byte, error) { func (v *Version) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(v)
EmitUnpopulated: true,
}.Marshal(
VersionToGRPCMessage(v),
)
} }
func (v *Version) UnmarshalJSON(data []byte) error { func (v *Version) UnmarshalJSON(data []byte) error {
msg := new(refs.Version) return message.UnmarshalJSON(v, data, new(refs.Version))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*v = *VersionFromGRPCMessage(msg)
return nil
} }
func (s *Signature) MarshalJSON() ([]byte, error) { func (s *Signature) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(s)
EmitUnpopulated: true,
}.Marshal(
SignatureToGRPCMessage(s),
)
} }
func (s *Signature) UnmarshalJSON(data []byte) error { func (s *Signature) UnmarshalJSON(data []byte) error {
msg := new(refs.Signature) return message.UnmarshalJSON(s, data, new(refs.Signature))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*s = *SignatureFromGRPCMessage(msg)
return nil
} }
func (c *Checksum) MarshalJSON() ([]byte, error) { func (c *Checksum) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(c)
EmitUnpopulated: true,
}.Marshal(
ChecksumToGRPCMessage(c),
)
} }
func (c *Checksum) UnmarshalJSON(data []byte) error { func (c *Checksum) UnmarshalJSON(data []byte) error {
msg := new(refs.Checksum) return message.UnmarshalJSON(c, data, new(refs.Checksum))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*c = *ChecksumFromGRPCMessage(msg)
return nil
} }

View file

@ -1,97 +0,0 @@
package refs_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/stretchr/testify/require"
)
func TestAddressJSON(t *testing.T) {
a := generateAddress([]byte{1}, []byte{2})
data, err := a.MarshalJSON()
require.NoError(t, err)
a2 := new(refs.Address)
require.NoError(t, a2.UnmarshalJSON(data))
require.Equal(t, a, a2)
}
func TestObjectIDJSON(t *testing.T) {
o := new(refs.ObjectID)
o.SetValue([]byte{1})
data, err := o.MarshalJSON()
require.NoError(t, err)
o2 := new(refs.ObjectID)
require.NoError(t, o2.UnmarshalJSON(data))
require.Equal(t, o, o2)
}
func TestContainerIDJSON(t *testing.T) {
cid := new(refs.ContainerID)
cid.SetValue([]byte{1})
data, err := cid.MarshalJSON()
require.NoError(t, err)
cid2 := new(refs.ContainerID)
require.NoError(t, cid2.UnmarshalJSON(data))
require.Equal(t, cid, cid2)
}
func TestOwnerIDJSON(t *testing.T) {
o := new(refs.OwnerID)
o.SetValue([]byte{1})
data, err := o.MarshalJSON()
require.NoError(t, err)
o2 := new(refs.OwnerID)
require.NoError(t, o2.UnmarshalJSON(data))
require.Equal(t, o, o2)
}
func TestVersionSON(t *testing.T) {
v := generateVersion(1, 2)
data, err := v.MarshalJSON()
require.NoError(t, err)
v2 := new(refs.Version)
require.NoError(t, v2.UnmarshalJSON(data))
require.Equal(t, v, v2)
}
func TestSignatureSON(t *testing.T) {
s := generateSignature("key", "sig")
data, err := s.MarshalJSON()
require.NoError(t, err)
s2 := new(refs.Signature)
require.NoError(t, s2.UnmarshalJSON(data))
require.Equal(t, s, s2)
}
func TestChecksumJSON(t *testing.T) {
cs := new(refs.Checksum)
cs.SetType(refs.SHA256)
cs.SetSum([]byte{1, 2, 3})
data, err := cs.MarshalJSON()
require.NoError(t, err)
cs2 := new(refs.Checksum)
require.NoError(t, cs2.UnmarshalJSON(data))
require.Equal(t, cs, cs2)
}

View file

@ -1,9 +1,9 @@
package refs package refs
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
"github.com/nspcc-dev/neofs-api-go/util/proto" "github.com/nspcc-dev/neofs-api-go/util/proto"
refs "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc" refs "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
goproto "google.golang.org/protobuf/proto"
) )
const ( const (
@ -52,14 +52,7 @@ func (o *OwnerID) StableSize() int {
} }
func (o *OwnerID) Unmarshal(data []byte) error { func (o *OwnerID) Unmarshal(data []byte) error {
m := new(refs.OwnerID) return message.Unmarshal(o, data, new(refs.OwnerID))
if err := goproto.Unmarshal(data, m); err != nil {
return err
}
*o = *OwnerIDFromGRPCMessage(m)
return nil
} }
func (c *ContainerID) StableMarshal(buf []byte) ([]byte, error) { func (c *ContainerID) StableMarshal(buf []byte) ([]byte, error) {
@ -88,14 +81,7 @@ func (c *ContainerID) StableSize() int {
} }
func (c *ContainerID) Unmarshal(data []byte) error { func (c *ContainerID) Unmarshal(data []byte) error {
m := new(refs.ContainerID) return message.Unmarshal(c, data, new(refs.ContainerID))
if err := goproto.Unmarshal(data, m); err != nil {
return err
}
*c = *ContainerIDFromGRPCMessage(m)
return nil
} }
func (o *ObjectID) StableMarshal(buf []byte) ([]byte, error) { func (o *ObjectID) StableMarshal(buf []byte) ([]byte, error) {
@ -151,14 +137,7 @@ func ObjectIDNestedListMarshal(fNum int64, buf []byte, ids []*ObjectID) (off int
} }
func (o *ObjectID) Unmarshal(data []byte) error { func (o *ObjectID) Unmarshal(data []byte) error {
m := new(refs.ObjectID) return message.Unmarshal(o, data, new(refs.ObjectID))
if err := goproto.Unmarshal(data, m); err != nil {
return err
}
*o = *ObjectIDFromGRPCMessage(m)
return nil
} }
func (a *Address) StableMarshal(buf []byte) ([]byte, error) { func (a *Address) StableMarshal(buf []byte) ([]byte, error) {
@ -203,14 +182,7 @@ func (a *Address) StableSize() (size int) {
} }
func (a *Address) Unmarshal(data []byte) error { func (a *Address) Unmarshal(data []byte) error {
addrGRPC := new(refs.Address) return message.Unmarshal(a, data, new(refs.Address))
if err := goproto.Unmarshal(data, addrGRPC); err != nil {
return err
}
*a = *AddressFromGRPCMessage(addrGRPC)
return nil
} }
func (c *Checksum) StableMarshal(buf []byte) ([]byte, error) { func (c *Checksum) StableMarshal(buf []byte) ([]byte, error) {
@ -254,14 +226,7 @@ func (c *Checksum) StableSize() (size int) {
} }
func (c *Checksum) Unmarshal(data []byte) error { func (c *Checksum) Unmarshal(data []byte) error {
m := new(refs.Checksum) return message.Unmarshal(c, data, new(refs.Checksum))
if err := goproto.Unmarshal(data, m); err != nil {
return err
}
*c = *ChecksumFromGRPCMessage(m)
return nil
} }
func (s *Signature) StableMarshal(buf []byte) ([]byte, error) { func (s *Signature) StableMarshal(buf []byte) ([]byte, error) {
@ -305,14 +270,7 @@ func (s *Signature) StableSize() (size int) {
} }
func (s *Signature) Unmarshal(data []byte) error { func (s *Signature) Unmarshal(data []byte) error {
m := new(refs.Signature) return message.Unmarshal(s, data, new(refs.Signature))
if err := goproto.Unmarshal(data, m); err != nil {
return err
}
*s = *SignatureFromGRPCMessage(m)
return nil
} }
func (v *Version) StableMarshal(buf []byte) ([]byte, error) { func (v *Version) StableMarshal(buf []byte) ([]byte, error) {
@ -356,12 +314,5 @@ func (v *Version) StableSize() (size int) {
} }
func (v *Version) Unmarshal(data []byte) error { func (v *Version) Unmarshal(data []byte) error {
m := new(refs.Version) return message.Unmarshal(v, data, new(refs.Version))
if err := goproto.Unmarshal(data, m); err != nil {
return err
}
*v = *VersionFromGRPCMessage(m)
return nil
} }

View file

@ -1,146 +0,0 @@
package refs_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/stretchr/testify/require"
)
func TestOwnerID_StableMarshal(t *testing.T) {
ownerFrom := new(refs.OwnerID)
t.Run("non empty", func(t *testing.T) {
ownerFrom.SetValue([]byte("Owner ID"))
wire, err := ownerFrom.StableMarshal(nil)
require.NoError(t, err)
ownerTo := new(refs.OwnerID)
require.NoError(t, ownerTo.Unmarshal(wire))
require.Equal(t, ownerFrom, ownerTo)
})
}
func TestContainerID_StableMarshal(t *testing.T) {
cnrFrom := new(refs.ContainerID)
t.Run("non empty", func(t *testing.T) {
cnrFrom.SetValue([]byte("Container ID"))
wire, err := cnrFrom.StableMarshal(nil)
require.NoError(t, err)
cnrTo := new(refs.ContainerID)
require.NoError(t, cnrTo.Unmarshal(wire))
require.Equal(t, cnrFrom, cnrTo)
})
}
func TestObjectID_StableMarshal(t *testing.T) {
objectIDFrom := new(refs.ObjectID)
t.Run("non empty", func(t *testing.T) {
objectIDFrom.SetValue([]byte("Object ID"))
wire, err := objectIDFrom.StableMarshal(nil)
require.NoError(t, err)
objectIDTo := new(refs.ObjectID)
require.NoError(t, objectIDTo.Unmarshal(wire))
require.Equal(t, objectIDFrom, objectIDTo)
})
}
func TestAddress_StableMarshal(t *testing.T) {
cid := []byte("Container ID")
oid := []byte("Object ID")
addressFrom := generateAddress(cid, oid)
t.Run("non empty", func(t *testing.T) {
wire, err := addressFrom.StableMarshal(nil)
require.NoError(t, err)
addressTo := new(refs.Address)
require.NoError(t, addressTo.Unmarshal(wire))
require.Equal(t, addressFrom, addressTo)
})
}
func TestChecksum_StableMarshal(t *testing.T) {
checksumFrom := new(refs.Checksum)
t.Run("non empty", func(t *testing.T) {
checksumFrom.SetType(refs.TillichZemor)
checksumFrom.SetSum([]byte("Homomorphic Hash"))
wire, err := checksumFrom.StableMarshal(nil)
require.NoError(t, err)
checksumTo := new(refs.Checksum)
require.NoError(t, checksumTo.Unmarshal(wire))
require.Equal(t, checksumFrom, checksumTo)
})
}
func TestSignature_StableMarshal(t *testing.T) {
signatureFrom := generateSignature("Public Key", "Signature")
t.Run("non empty", func(t *testing.T) {
wire, err := signatureFrom.StableMarshal(nil)
require.NoError(t, err)
signatureTo := new(refs.Signature)
require.NoError(t, signatureTo.Unmarshal(wire))
require.Equal(t, signatureFrom, signatureTo)
})
}
func TestVersion_StableMarshal(t *testing.T) {
versionFrom := generateVersion(2, 0)
t.Run("non empty", func(t *testing.T) {
wire, err := versionFrom.StableMarshal(nil)
require.NoError(t, err)
versionTo := new(refs.Version)
require.NoError(t, versionTo.Unmarshal(wire))
require.Equal(t, versionFrom, versionTo)
})
}
func generateSignature(k, v string) *refs.Signature {
sig := new(refs.Signature)
sig.SetKey([]byte(k))
sig.SetSign([]byte(v))
return sig
}
func generateVersion(maj, min uint32) *refs.Version {
version := new(refs.Version)
version.SetMajor(maj)
version.SetMinor(min)
return version
}
func generateAddress(bCid, bOid []byte) *refs.Address {
addr := new(refs.Address)
cid := new(refs.ContainerID)
cid.SetValue(bCid)
oid := new(refs.ObjectID)
oid.SetValue(bOid)
return addr
}

21
v2/refs/message_test.go Normal file
View file

@ -0,0 +1,21 @@
package refs_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/rpc/message"
messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test"
refstest "github.com/nspcc-dev/neofs-api-go/v2/refs/test"
)
func TestMessageConvert(t *testing.T) {
messagetest.TestRPCMessage(t,
func(empty bool) message.Message { return refstest.GenerateOwnerID(empty) },
func(empty bool) message.Message { return refstest.GenerateObjectID(empty) },
func(empty bool) message.Message { return refstest.GenerateContainerID(empty) },
func(empty bool) message.Message { return refstest.GenerateAddress(empty) },
func(empty bool) message.Message { return refstest.GenerateChecksum(empty) },
func(empty bool) message.Message { return refstest.GenerateSignature(empty) },
func(empty bool) message.Message { return refstest.GenerateVersion(empty) },
)
}

101
v2/refs/test/generate.go Normal file
View file

@ -0,0 +1,101 @@
package refstest
import (
"github.com/nspcc-dev/neofs-api-go/v2/refs"
)
func GenerateVersion(empty bool) *refs.Version {
m := new(refs.Version)
if !empty {
m.SetMajor(2)
m.SetMinor(1)
}
return m
}
func GenerateOwnerID(empty bool) *refs.OwnerID {
m := new(refs.OwnerID)
if !empty {
m.SetValue([]byte{1, 2, 3})
}
return m
}
func GenerateAddress(empty bool) *refs.Address {
m := new(refs.Address)
m.SetObjectID(GenerateObjectID(empty))
m.SetContainerID(GenerateContainerID(empty))
return m
}
func GenerateObjectID(empty bool) *refs.ObjectID {
m := new(refs.ObjectID)
if !empty {
m.SetValue([]byte{1, 2, 3})
}
return m
}
func GenerateObjectIDs(empty bool) []*refs.ObjectID {
ids := make([]*refs.ObjectID, 0)
if !empty {
ids = append(ids,
GenerateObjectID(false),
GenerateObjectID(false),
)
}
return ids
}
func GenerateContainerID(empty bool) *refs.ContainerID {
m := new(refs.ContainerID)
if !empty {
m.SetValue([]byte{1, 2, 3})
}
return m
}
func GenerateContainerIDs(empty bool) (res []*refs.ContainerID) {
if !empty {
res = append(res,
GenerateContainerID(false),
GenerateContainerID(false),
)
}
return
}
func GenerateSignature(empty bool) *refs.Signature {
m := new(refs.Signature)
if !empty {
m.SetKey([]byte{1})
m.SetSign([]byte{2})
}
return m
}
func GenerateChecksum(empty bool) *refs.Checksum {
m := new(refs.Checksum)
if !empty {
m.SetType(1)
m.SetSum([]byte{1, 2, 3})
}
return m
}

29
v2/rpc/accounting.go Normal file
View file

@ -0,0 +1,29 @@
package rpc
import (
"github.com/nspcc-dev/neofs-api-go/rpc/client"
"github.com/nspcc-dev/neofs-api-go/rpc/common"
"github.com/nspcc-dev/neofs-api-go/v2/accounting"
)
const serviceAccounting = serviceNamePrefix + "accounting.AccountingService"
const (
rpcAccountingBalance = "Balance"
)
// Balance executes AccountingService.Balance RPC.
func Balance(
cli *client.Client,
req *accounting.BalanceRequest,
opts ...client.CallOption,
) (*accounting.BalanceResponse, error) {
resp := new(accounting.BalanceResponse)
err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceAccounting, rpcAccountingBalance), req, resp, opts...)
if err != nil {
return nil, err
}
return resp, nil
}

3
v2/rpc/common.go Normal file
View file

@ -0,0 +1,3 @@
package rpc
const serviceNamePrefix = "neo.fs.v2."

131
v2/rpc/container.go Normal file
View file

@ -0,0 +1,131 @@
package rpc
import (
"github.com/nspcc-dev/neofs-api-go/rpc/client"
"github.com/nspcc-dev/neofs-api-go/rpc/common"
"github.com/nspcc-dev/neofs-api-go/v2/container"
)
const serviceContainer = serviceNamePrefix + "container.ContainerService"
const (
rpcContainerPut = "Put"
rpcContainerGet = "Get"
rpcContainerDel = "Delete"
rpcContainerList = "List"
rpcContainerSetEACL = "SetExtendedACL"
rpcContainerGetEACL = "GetExtendedACL"
rpcContainerUsedSpace = "AnnounceUsedSpace"
)
// PutContainer executes ContainerService.Put RPC.
func PutContainer(
cli *client.Client,
req *container.PutRequest,
opts ...client.CallOption,
) (*container.PutResponse, error) {
resp := new(container.PutResponse)
err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceContainer, rpcContainerPut), req, resp, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// GetContainer executes ContainerService.Get RPC.
func GetContainer(
cli *client.Client,
req *container.GetRequest,
opts ...client.CallOption,
) (*container.GetResponse, error) {
resp := new(container.GetResponse)
err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceContainer, rpcContainerGet), req, resp, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// DeleteContainer executes ContainerService.Delete RPC.
func DeleteContainer(
cli *client.Client,
req *container.DeleteRequest,
opts ...client.CallOption,
) (*container.PutResponse, error) {
resp := new(container.PutResponse)
err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceContainer, rpcContainerDel), req, resp, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// ListContainers executes ContainerService.List RPC.
func ListContainers(
cli *client.Client,
req *container.ListRequest,
opts ...client.CallOption,
) (*container.ListResponse, error) {
resp := new(container.ListResponse)
err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceContainer, rpcContainerList), req, resp, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// SetEACL executes ContainerService.SetExtendedACL RPC.
func SetEACL(
cli *client.Client,
req *container.SetExtendedACLRequest,
opts ...client.CallOption,
) (*container.PutResponse, error) {
resp := new(container.PutResponse)
err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceContainer, rpcContainerSetEACL), req, resp, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// GetEACL executes ContainerService.GetExtendedACL RPC.
func GetEACL(
cli *client.Client,
req *container.GetExtendedACLRequest,
opts ...client.CallOption,
) (*container.GetExtendedACLResponse, error) {
resp := new(container.GetExtendedACLResponse)
err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceContainer, rpcContainerGetEACL), req, resp, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// AnnounceUsedSpace executes ContainerService.AnnounceUsedSpace RPC.
func AnnounceUsedSpace(
cli *client.Client,
req *container.AnnounceUsedSpaceRequest,
opts ...client.CallOption,
) (*container.PutResponse, error) {
resp := new(container.PutResponse)
err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceContainer, rpcContainerUsedSpace), req, resp, opts...)
if err != nil {
return nil, err
}
return resp, nil
}

46
v2/rpc/netmap.go Normal file
View file

@ -0,0 +1,46 @@
package rpc
import (
"github.com/nspcc-dev/neofs-api-go/rpc/client"
"github.com/nspcc-dev/neofs-api-go/rpc/common"
"github.com/nspcc-dev/neofs-api-go/v2/netmap"
)
const serviceNetmap = serviceNamePrefix + "netmap.NetmapService"
const (
rpcNetmapNodeInfo = "LocalNodeInfo"
rpcNetmapNetInfo = "NetworkInfo"
)
// LocalNodeInfo executes NetmapService.LocalNodeInfo RPC.
func LocalNodeInfo(
cli *client.Client,
req *netmap.LocalNodeInfoRequest,
opts ...client.CallOption,
) (*netmap.LocalNodeInfoResponse, error) {
resp := new(netmap.LocalNodeInfoResponse)
err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceNetmap, rpcNetmapNodeInfo), req, resp, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// NetworkInfo executes NetmapService.NetworkInfo RPC.
func NetworkInfo(
cli *client.Client,
req *netmap.NetworkInfoRequest,
opts ...client.CallOption,
) (*netmap.NetworkInfoResponse, error) {
resp := new(netmap.NetworkInfoResponse)
err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceNetmap, rpcNetmapNetInfo), req, resp, opts...)
if err != nil {
return nil, err
}
return resp, nil
}

190
v2/rpc/object.go Normal file
View file

@ -0,0 +1,190 @@
package rpc
import (
"github.com/nspcc-dev/neofs-api-go/rpc/client"
"github.com/nspcc-dev/neofs-api-go/rpc/common"
"github.com/nspcc-dev/neofs-api-go/rpc/message"
"github.com/nspcc-dev/neofs-api-go/v2/object"
)
const serviceObject = serviceNamePrefix + "object.ObjectService"
const (
rpcObjectPut = "Put"
rpcObjectGet = "Get"
rpcObjectSearch = "Search"
rpcObjectRange = "GetRange"
rpcObjectHash = "GetRangeHash"
rpcObjectHead = "Head"
rpcObjectDelete = "Delete"
)
// PutRequestWriter is an object.PutRequest
// message streaming component.
type PutRequestWriter struct {
wc client.MessageWriterCloser
resp message.Message
}
// Write writes req to the stream.
func (w *PutRequestWriter) Write(req *object.PutRequest) error {
return w.wc.WriteMessage(req)
}
// Close closes the stream.
func (w *PutRequestWriter) Close() error {
return w.wc.Close()
}
// PutObject executes ObjectService.Put RPC.
func PutObject(
cli *client.Client,
resp *object.PutResponse,
opts ...client.CallOption,
) (*PutRequestWriter, error) {
wc, err := client.OpenClientStream(cli, common.CallMethodInfoClientStream(serviceObject, rpcObjectPut), resp, opts...)
if err != nil {
return nil, err
}
return &PutRequestWriter{
wc: wc,
resp: resp,
}, nil
}
// GetResponseReader is an object.GetResponse
// stream reader.
type GetResponseReader struct {
r client.MessageReader
}
// Read reads response from the stream.
//
// Returns io.EOF of streaming is finished.
func (r *GetResponseReader) Read(resp *object.GetResponse) error {
return r.r.ReadMessage(resp)
}
// GetObject executes ObjectService.Get RPC.
func GetObject(
cli *client.Client,
req *object.GetRequest,
opts ...client.CallOption,
) (*GetResponseReader, error) {
wc, err := client.OpenServerStream(cli, common.CallMethodInfoServerStream(serviceObject, rpcObjectGet), req, opts...)
if err != nil {
return nil, err
}
return &GetResponseReader{
r: wc,
}, nil
}
// GetResponseReader is an object.SearchResponse
// stream reader.
type SearchResponseReader struct {
r client.MessageReader
}
// Read reads response from the stream.
//
// Returns io.EOF of streaming is finished.
func (r *SearchResponseReader) Read(resp *object.SearchResponse) error {
return r.r.ReadMessage(resp)
}
// SearchObjects executes ObjectService.Search RPC.
func SearchObjects(
cli *client.Client,
req *object.SearchRequest,
opts ...client.CallOption,
) (*SearchResponseReader, error) {
wc, err := client.OpenServerStream(cli, common.CallMethodInfoServerStream(serviceObject, rpcObjectSearch), req, opts...)
if err != nil {
return nil, err
}
return &SearchResponseReader{
r: wc,
}, nil
}
// GetResponseReader is an object.GetRangeResponse
// stream reader.
type ObjectRangeResponseReader struct {
r client.MessageReader
}
// Read reads response from the stream.
//
// Returns io.EOF of streaming is finished.
func (r *ObjectRangeResponseReader) Read(resp *object.GetRangeResponse) error {
return r.r.ReadMessage(resp)
}
// GetObjectRange executes ObjectService.GetRange RPC.
func GetObjectRange(
cli *client.Client,
req *object.GetRangeRequest,
opts ...client.CallOption,
) (*ObjectRangeResponseReader, error) {
wc, err := client.OpenServerStream(cli, common.CallMethodInfoServerStream(serviceObject, rpcObjectRange), req, opts...)
if err != nil {
return nil, err
}
return &ObjectRangeResponseReader{
r: wc,
}, nil
}
// HeadObject executes ObjectService.Head RPC.
func HeadObject(
cli *client.Client,
req *object.HeadRequest,
opts ...client.CallOption,
) (*object.HeadResponse, error) {
resp := new(object.HeadResponse)
err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceObject, rpcObjectHead), req, resp, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// DeleteObject executes ObjectService.Delete RPC.
func DeleteObject(
cli *client.Client,
req *object.DeleteRequest,
opts ...client.CallOption,
) (*object.DeleteResponse, error) {
resp := new(object.DeleteResponse)
err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceObject, rpcObjectDelete), req, resp, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// HashObjectRange executes ObjectService.GetRangeHash RPC.
func HashObjectRange(
cli *client.Client,
req *object.GetRangeHashRequest,
opts ...client.CallOption,
) (*object.GetRangeHashResponse, error) {
resp := new(object.GetRangeHashResponse)
err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceObject, rpcObjectHash), req, resp, opts...)
if err != nil {
return nil, err
}
return resp, nil
}

28
v2/rpc/session.go Normal file
View file

@ -0,0 +1,28 @@
package rpc
import (
"github.com/nspcc-dev/neofs-api-go/rpc/client"
"github.com/nspcc-dev/neofs-api-go/rpc/common"
"github.com/nspcc-dev/neofs-api-go/v2/session"
)
const serviceSession = serviceNamePrefix + "session.SessionService"
const (
rpcSessionCreate = "Create"
)
func CreateSession(
cli *client.Client,
req *session.CreateRequest,
opts ...client.CallOption,
) (*session.CreateResponse, error) {
resp := new(session.CreateResponse)
err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceSession, rpcSessionCreate), req, resp, opts...)
if err != nil {
return nil, err
}
return resp, nil
}

View file

@ -1,156 +0,0 @@
package session
import (
"context"
"github.com/nspcc-dev/neofs-api-go/v2/client"
session "github.com/nspcc-dev/neofs-api-go/v2/session/grpc"
"github.com/pkg/errors"
"google.golang.org/grpc"
)
// Client represents universal session
// transport client.
type Client struct {
client *createClient
}
// Option represents Client option.
type Option func(*cfg)
type cfg struct {
proto client.Protocol
globalOpts []client.Option
gRPC cfgGRPC
}
type cfgGRPC struct {
serviceClient session.SessionServiceClient
grpcCallOpts []grpc.CallOption
callOpts []session.Option
client *session.Client
}
type createClient struct {
requestConverter func(*CreateRequest) interface{}
caller func(context.Context, interface{}) (interface{}, error)
responseConverter func(interface{}) *CreateResponse
}
// Create sends CreateRequest over the network and returns CreateResponse.
//
// It returns any error encountered during the call.
func (c *Client) Create(ctx context.Context, req *CreateRequest) (*CreateResponse, error) {
resp, err := c.client.caller(ctx, c.client.requestConverter(req))
if err != nil {
return nil, errors.Wrap(err, "could not send session init request")
}
return c.client.responseConverter(resp), nil
}
func defaultCfg() *cfg {
return &cfg{
proto: client.ProtoGRPC,
}
}
func NewClient(opts ...Option) (*Client, error) {
cfg := defaultCfg()
for i := range opts {
opts[i](cfg)
}
var err error
switch cfg.proto {
case client.ProtoGRPC:
var c *session.Client
if c, err = newGRPCClient(cfg); err != nil {
break
}
return &Client{
client: &createClient{
requestConverter: func(req *CreateRequest) interface{} {
return CreateRequestToGRPCMessage(req)
},
caller: func(ctx context.Context, req interface{}) (interface{}, error) {
return c.Create(ctx, req.(*session.CreateRequest))
},
responseConverter: func(resp interface{}) *CreateResponse {
return CreateResponseFromGRPCMessage(resp.(*session.CreateResponse))
},
},
}, nil
default:
err = client.ErrProtoUnsupported
}
return nil, errors.Wrapf(err, "could not create %s Session client", cfg.proto)
}
func newGRPCClient(cfg *cfg) (*session.Client, error) {
var err error
if cfg.gRPC.client == nil {
if cfg.gRPC.serviceClient == nil {
conn, err := client.NewGRPCClientConn(cfg.globalOpts...)
if err != nil {
return nil, errors.Wrap(err, "could not open gRPC client connection")
}
cfg.gRPC.serviceClient = session.NewSessionServiceClient(conn)
}
cfg.gRPC.client, err = session.NewClient(
cfg.gRPC.serviceClient,
append(
cfg.gRPC.callOpts,
session.WithCallOptions(cfg.gRPC.grpcCallOpts),
)...,
)
}
return cfg.gRPC.client, err
}
func WithGlobalOpts(v ...client.Option) Option {
return func(c *cfg) {
if len(v) > 0 {
c.globalOpts = v
}
}
}
func WithGRPCServiceClient(v session.SessionServiceClient) Option {
return func(c *cfg) {
c.gRPC.serviceClient = v
}
}
func WithGRPCCallOpts(v []grpc.CallOption) Option {
return func(c *cfg) {
c.gRPC.grpcCallOpts = v
}
}
func WithGRPCClientOpts(v []session.Option) Option {
return func(c *cfg) {
c.gRPC.callOpts = v
}
}
func WithGRPCClient(v *session.Client) Option {
return func(c *cfg) {
c.gRPC.client = v
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,56 +1,29 @@
package session package session
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
session "github.com/nspcc-dev/neofs-api-go/v2/session/grpc" session "github.com/nspcc-dev/neofs-api-go/v2/session/grpc"
"google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/encoding/protojson"
) )
func (c *ObjectSessionContext) MarshalJSON() ([]byte, error) { func (c *ObjectSessionContext) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(c)
EmitUnpopulated: true,
}.Marshal(
ObjectSessionContextToGRPCMessage(c),
)
} }
func (c *ObjectSessionContext) UnmarshalJSON(data []byte) error { func (c *ObjectSessionContext) UnmarshalJSON(data []byte) error {
msg := new(session.ObjectSessionContext) return message.UnmarshalJSON(c, data, new(session.ObjectSessionContext))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*c = *ObjectSessionContextFromGRPCMessage(msg)
return nil
} }
func (l *TokenLifetime) MarshalJSON() ([]byte, error) { func (l *TokenLifetime) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(l)
EmitUnpopulated: true,
}.Marshal(
TokenLifetimeToGRPCMessage(l),
)
} }
func (l *TokenLifetime) UnmarshalJSON(data []byte) error { func (l *TokenLifetime) UnmarshalJSON(data []byte) error {
msg := new(session.SessionToken_Body_TokenLifetime) return message.UnmarshalJSON(l, data, new(session.SessionToken_Body_TokenLifetime))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*l = *TokenLifetimeFromGRPCMessage(msg)
return nil
} }
func (t *SessionTokenBody) MarshalJSON() ([]byte, error) { func (t *SessionTokenBody) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(t)
EmitUnpopulated: true,
}.Marshal(
SessionTokenBodyToGRPCMessage(t),
)
} }
func (t *SessionTokenBody) UnmarshalJSON(data []byte) error { func (t *SessionTokenBody) UnmarshalJSON(data []byte) error {
@ -60,17 +33,11 @@ func (t *SessionTokenBody) UnmarshalJSON(data []byte) error {
return err return err
} }
*t = *SessionTokenBodyFromGRPCMessage(msg) return t.FromGRPCMessage(msg)
return nil
} }
func (t *SessionToken) MarshalJSON() ([]byte, error) { func (t *SessionToken) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(t)
EmitUnpopulated: true,
}.Marshal(
SessionTokenToGRPCMessage(t),
)
} }
func (t *SessionToken) UnmarshalJSON(data []byte) error { func (t *SessionToken) UnmarshalJSON(data []byte) error {
@ -80,17 +47,11 @@ func (t *SessionToken) UnmarshalJSON(data []byte) error {
return err return err
} }
*t = *SessionTokenFromGRPCMessage(msg) return t.FromGRPCMessage(msg)
return nil
} }
func (x *XHeader) MarshalJSON() ([]byte, error) { func (x *XHeader) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(x)
EmitUnpopulated: true,
}.Marshal(
XHeaderToGRPCMessage(x),
)
} }
func (x *XHeader) UnmarshalJSON(data []byte) error { func (x *XHeader) UnmarshalJSON(data []byte) error {
@ -100,17 +61,11 @@ func (x *XHeader) UnmarshalJSON(data []byte) error {
return err return err
} }
*x = *XHeaderFromGRPCMessage(msg) return x.FromGRPCMessage(msg)
return nil
} }
func (r *RequestMetaHeader) MarshalJSON() ([]byte, error) { func (r *RequestMetaHeader) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(r)
EmitUnpopulated: true,
}.Marshal(
RequestMetaHeaderToGRPCMessage(r),
)
} }
func (r *RequestMetaHeader) UnmarshalJSON(data []byte) error { func (r *RequestMetaHeader) UnmarshalJSON(data []byte) error {
@ -120,17 +75,11 @@ func (r *RequestMetaHeader) UnmarshalJSON(data []byte) error {
return err return err
} }
*r = *RequestMetaHeaderFromGRPCMessage(msg) return r.FromGRPCMessage(msg)
return nil
} }
func (r *RequestVerificationHeader) MarshalJSON() ([]byte, error) { func (r *RequestVerificationHeader) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(r)
EmitUnpopulated: true,
}.Marshal(
RequestVerificationHeaderToGRPCMessage(r),
)
} }
func (r *RequestVerificationHeader) UnmarshalJSON(data []byte) error { func (r *RequestVerificationHeader) UnmarshalJSON(data []byte) error {
@ -140,17 +89,11 @@ func (r *RequestVerificationHeader) UnmarshalJSON(data []byte) error {
return err return err
} }
*r = *RequestVerificationHeaderFromGRPCMessage(msg) return r.FromGRPCMessage(msg)
return nil
} }
func (r *ResponseMetaHeader) MarshalJSON() ([]byte, error) { func (r *ResponseMetaHeader) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(r)
EmitUnpopulated: true,
}.Marshal(
ResponseMetaHeaderToGRPCMessage(r),
)
} }
func (r *ResponseMetaHeader) UnmarshalJSON(data []byte) error { func (r *ResponseMetaHeader) UnmarshalJSON(data []byte) error {
@ -160,17 +103,11 @@ func (r *ResponseMetaHeader) UnmarshalJSON(data []byte) error {
return err return err
} }
*r = *ResponseMetaHeaderFromGRPCMessage(msg) return r.FromGRPCMessage(msg)
return nil
} }
func (r *ResponseVerificationHeader) MarshalJSON() ([]byte, error) { func (r *ResponseVerificationHeader) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(r)
EmitUnpopulated: true,
}.Marshal(
ResponseVerificationHeaderToGRPCMessage(r),
)
} }
func (r *ResponseVerificationHeader) UnmarshalJSON(data []byte) error { func (r *ResponseVerificationHeader) UnmarshalJSON(data []byte) error {
@ -180,7 +117,5 @@ func (r *ResponseVerificationHeader) UnmarshalJSON(data []byte) error {
return err return err
} }
*r = *ResponseVerificationHeaderFromGRPCMessage(msg) return r.FromGRPCMessage(msg)
return nil
} }

View file

@ -1,116 +0,0 @@
package session_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/session"
"github.com/stretchr/testify/require"
)
func TestChecksumJSON(t *testing.T) {
ctx := generateObjectCtx("id")
data, err := ctx.MarshalJSON()
require.NoError(t, err)
ctx2 := new(session.ObjectSessionContext)
require.NoError(t, ctx2.UnmarshalJSON(data))
require.Equal(t, ctx, ctx2)
}
func TestTokenLifetimeJSON(t *testing.T) {
l := generateLifetime(1, 2, 3)
data, err := l.MarshalJSON()
require.NoError(t, err)
l2 := new(session.TokenLifetime)
require.NoError(t, l2.UnmarshalJSON(data))
require.Equal(t, l, l2)
}
func TestSessionTokenBodyJSON(t *testing.T) {
b := generateSessionTokenBody("id")
data, err := b.MarshalJSON()
require.NoError(t, err)
b2 := new(session.SessionTokenBody)
require.NoError(t, b2.UnmarshalJSON(data))
require.Equal(t, b, b2)
}
func TestSessionTokenJSON(t *testing.T) {
tok := generateSessionToken("id")
data, err := tok.MarshalJSON()
require.NoError(t, err)
tok2 := new(session.SessionToken)
require.NoError(t, tok2.UnmarshalJSON(data))
require.Equal(t, tok, tok2)
}
func TestXHeaderJSON(t *testing.T) {
x := generateXHeader("key", "value")
data, err := x.MarshalJSON()
require.NoError(t, err)
x2 := new(session.XHeader)
require.NoError(t, x2.UnmarshalJSON(data))
require.Equal(t, x, x2)
}
func TestRequestMetaHeaderJSON(t *testing.T) {
r := generateRequestMetaHeader(1, "bearer", "session")
data, err := r.MarshalJSON()
require.NoError(t, err)
r2 := new(session.RequestMetaHeader)
require.NoError(t, r2.UnmarshalJSON(data))
require.Equal(t, r, r2)
}
func TestRequestVerificationHeaderJSON(t *testing.T) {
r := generateRequestVerificationHeader("key", "value")
data, err := r.MarshalJSON()
require.NoError(t, err)
r2 := new(session.RequestVerificationHeader)
require.NoError(t, r2.UnmarshalJSON(data))
require.Equal(t, r, r2)
}
func TestResponseMetaHeaderJSON(t *testing.T) {
r := generateResponseMetaHeader(1)
data, err := r.MarshalJSON()
require.NoError(t, err)
r2 := new(session.ResponseMetaHeader)
require.NoError(t, r2.UnmarshalJSON(data))
require.Equal(t, r, r2)
}
func TestResponseVerificationHeaderJSON(t *testing.T) {
r := generateResponseVerificationHeader("key", "value")
data, err := r.MarshalJSON()
require.NoError(t, err)
r2 := new(session.ResponseVerificationHeader)
require.NoError(t, r2.UnmarshalJSON(data))
require.Equal(t, r, r2)
}

View file

@ -1,6 +1,7 @@
package session package session
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
"github.com/nspcc-dev/neofs-api-go/util/proto" "github.com/nspcc-dev/neofs-api-go/util/proto"
session "github.com/nspcc-dev/neofs-api-go/v2/session/grpc" session "github.com/nspcc-dev/neofs-api-go/v2/session/grpc"
goproto "google.golang.org/protobuf/proto" goproto "google.golang.org/protobuf/proto"
@ -97,6 +98,10 @@ func (c *CreateRequestBody) StableSize() (size int) {
return size return size
} }
func (c *CreateRequestBody) Unmarshal(data []byte) error {
return message.Unmarshal(c, data, new(session.CreateRequest_Body))
}
func (c *CreateResponseBody) StableMarshal(buf []byte) ([]byte, error) { func (c *CreateResponseBody) StableMarshal(buf []byte) ([]byte, error) {
if c == nil { if c == nil {
return []byte{}, nil return []byte{}, nil
@ -137,6 +142,10 @@ func (c *CreateResponseBody) StableSize() (size int) {
return size return size
} }
func (c *CreateResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(c, data, new(session.CreateResponse_Body))
}
func (x *XHeader) StableMarshal(buf []byte) ([]byte, error) { func (x *XHeader) StableMarshal(buf []byte) ([]byte, error) {
if x == nil { if x == nil {
return []byte{}, nil return []byte{}, nil
@ -183,9 +192,7 @@ func (x *XHeader) Unmarshal(data []byte) error {
return err return err
} }
*x = *XHeaderFromGRPCMessage(m) return x.FromGRPCMessage(m)
return nil
} }
func (l *TokenLifetime) StableMarshal(buf []byte) ([]byte, error) { func (l *TokenLifetime) StableMarshal(buf []byte) ([]byte, error) {
@ -242,9 +249,7 @@ func (l *TokenLifetime) Unmarshal(data []byte) error {
return err return err
} }
*l = *TokenLifetimeFromGRPCMessage(m) return l.FromGRPCMessage(m)
return nil
} }
func (c *ObjectSessionContext) StableMarshal(buf []byte) ([]byte, error) { func (c *ObjectSessionContext) StableMarshal(buf []byte) ([]byte, error) {
@ -293,9 +298,7 @@ func (c *ObjectSessionContext) Unmarshal(data []byte) error {
return err return err
} }
*c = *ObjectSessionContextFromGRPCMessage(m) return c.FromGRPCMessage(m)
return nil
} }
func (t *SessionTokenBody) StableMarshal(buf []byte) ([]byte, error) { func (t *SessionTokenBody) StableMarshal(buf []byte) ([]byte, error) {
@ -383,9 +386,7 @@ func (t *SessionTokenBody) Unmarshal(data []byte) error {
return err return err
} }
*t = *SessionTokenBodyFromGRPCMessage(m) return t.FromGRPCMessage(m)
return nil
} }
func (t *SessionToken) StableMarshal(buf []byte) ([]byte, error) { func (t *SessionToken) StableMarshal(buf []byte) ([]byte, error) {
@ -434,9 +435,7 @@ func (t *SessionToken) Unmarshal(data []byte) error {
return err return err
} }
*t = *SessionTokenFromGRPCMessage(m) return t.FromGRPCMessage(m)
return nil
} }
func (r *RequestMetaHeader) StableMarshal(buf []byte) ([]byte, error) { func (r *RequestMetaHeader) StableMarshal(buf []byte) ([]byte, error) {
@ -534,9 +533,7 @@ func (r *RequestMetaHeader) Unmarshal(data []byte) error {
return err return err
} }
*r = *RequestMetaHeaderFromGRPCMessage(m) return r.FromGRPCMessage(m)
return nil
} }
func (r *RequestVerificationHeader) StableMarshal(buf []byte) ([]byte, error) { func (r *RequestVerificationHeader) StableMarshal(buf []byte) ([]byte, error) {
@ -601,9 +598,7 @@ func (r *RequestVerificationHeader) Unmarshal(data []byte) error {
return err return err
} }
*r = *RequestVerificationHeaderFromGRPCMessage(m) return r.FromGRPCMessage(m)
return nil
} }
func (r *ResponseMetaHeader) StableMarshal(buf []byte) ([]byte, error) { func (r *ResponseMetaHeader) StableMarshal(buf []byte) ([]byte, error) {
@ -685,9 +680,7 @@ func (r *ResponseMetaHeader) Unmarshal(data []byte) error {
return err return err
} }
*r = *ResponseMetaHeaderFromGRPCMessage(m) return r.FromGRPCMessage(m)
return nil
} }
func (r *ResponseVerificationHeader) StableMarshal(buf []byte) ([]byte, error) { func (r *ResponseVerificationHeader) StableMarshal(buf []byte) ([]byte, error) {
@ -752,7 +745,5 @@ func (r *ResponseVerificationHeader) Unmarshal(data []byte) error {
return err return err
} }
*r = *ResponseVerificationHeaderFromGRPCMessage(m) return r.FromGRPCMessage(m)
return nil
} }

View file

@ -1,385 +0,0 @@
package session_test
import (
"fmt"
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/acl"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-api-go/v2/session"
grpc "github.com/nspcc-dev/neofs-api-go/v2/session/grpc"
"github.com/stretchr/testify/require"
goproto "google.golang.org/protobuf/proto"
)
func TestCreateRequestBody_StableMarshal(t *testing.T) {
requestFrom := generateCreateSessionRequestBody("Owner ID")
transport := new(grpc.CreateRequest_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := requestFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
requestTo := session.CreateRequestBodyFromGRPCMessage(transport)
require.Equal(t, requestFrom, requestTo)
})
}
func TestCreateResponseBody_StableMarshal(t *testing.T) {
responseFrom := generateCreateSessionResponseBody("ID", "Session Public Key")
transport := new(grpc.CreateResponse_Body)
t.Run("non empty", func(t *testing.T) {
wire, err := responseFrom.StableMarshal(nil)
require.NoError(t, err)
err = goproto.Unmarshal(wire, transport)
require.NoError(t, err)
responseTo := session.CreateResponseBodyFromGRPCMessage(transport)
require.Equal(t, responseFrom, responseTo)
})
}
func TestXHeader_StableMarshal(t *testing.T) {
xheaderFrom := generateXHeader("X-Header-Key", "X-Header-Value")
t.Run("non empty", func(t *testing.T) {
wire, err := xheaderFrom.StableMarshal(nil)
require.NoError(t, err)
xheaderTo := new(session.XHeader)
require.NoError(t, xheaderTo.Unmarshal(wire))
require.Equal(t, xheaderFrom, xheaderTo)
})
}
func TestTokenLifetime_StableMarshal(t *testing.T) {
lifetimeFrom := generateLifetime(10, 20, 30)
t.Run("non empty", func(t *testing.T) {
wire, err := lifetimeFrom.StableMarshal(nil)
require.NoError(t, err)
lifetimeTo := new(session.TokenLifetime)
require.NoError(t, lifetimeTo.Unmarshal(wire))
require.Equal(t, lifetimeFrom, lifetimeTo)
})
}
func TestObjectSessionContext_StableMarshal(t *testing.T) {
objectCtxFrom := generateObjectCtx("Object ID")
t.Run("non empty", func(t *testing.T) {
wire, err := objectCtxFrom.StableMarshal(nil)
require.NoError(t, err)
objectCtxTo := new(session.ObjectSessionContext)
require.NoError(t, objectCtxTo.Unmarshal(wire))
require.Equal(t, objectCtxFrom, objectCtxTo)
})
}
func TestSessionTokenBody_StableMarshal(t *testing.T) {
sessionTokenBodyFrom := generateSessionTokenBody("Session Token Body")
t.Run("non empty", func(t *testing.T) {
wire, err := sessionTokenBodyFrom.StableMarshal(nil)
require.NoError(t, err)
sessionTokenBodyTo := new(session.SessionTokenBody)
require.NoError(t, sessionTokenBodyTo.Unmarshal(wire))
require.Equal(t, sessionTokenBodyFrom, sessionTokenBodyTo)
})
}
func TestSessionToken_StableMarshal(t *testing.T) {
sessionTokenFrom := generateSessionToken("Session Token")
t.Run("non empty", func(t *testing.T) {
wire, err := sessionTokenFrom.StableMarshal(nil)
require.NoError(t, err)
sessionTokenTo := new(session.SessionToken)
require.NoError(t, sessionTokenTo.Unmarshal(wire))
require.Equal(t, sessionTokenFrom, sessionTokenTo)
})
}
func TestRequestMetaHeader_StableMarshal(t *testing.T) {
metaHeaderOrigin := generateRequestMetaHeader(10, "Bearer One", "Session One")
metaHeaderFrom := generateRequestMetaHeader(20, "Bearer Two", "Session Two")
metaHeaderFrom.SetOrigin(metaHeaderOrigin)
t.Run("non empty", func(t *testing.T) {
wire, err := metaHeaderFrom.StableMarshal(nil)
require.NoError(t, err)
metaHeaderTo := new(session.RequestMetaHeader)
require.NoError(t, metaHeaderTo.Unmarshal(wire))
require.Equal(t, metaHeaderFrom, metaHeaderTo)
})
}
func TestRequestVerificationHeader_StableMarshal(t *testing.T) {
verifHeaderOrigin := generateRequestVerificationHeader("Key", "Inside")
verifHeaderFrom := generateRequestVerificationHeader("Value", "Outside")
verifHeaderFrom.SetOrigin(verifHeaderOrigin)
t.Run("non empty", func(t *testing.T) {
wire, err := verifHeaderFrom.StableMarshal(nil)
require.NoError(t, err)
verifHeaderTo := new(session.RequestVerificationHeader)
require.NoError(t, verifHeaderTo.Unmarshal(wire))
require.Equal(t, verifHeaderFrom, verifHeaderTo)
})
}
func TestResponseMetaHeader_StableMarshal(t *testing.T) {
metaHeaderOrigin := generateResponseMetaHeader(10)
metaHeaderFrom := generateResponseMetaHeader(20)
metaHeaderFrom.SetOrigin(metaHeaderOrigin)
t.Run("non empty", func(t *testing.T) {
wire, err := metaHeaderFrom.StableMarshal(nil)
require.NoError(t, err)
metaHeaderTo := new(session.ResponseMetaHeader)
require.NoError(t, metaHeaderTo.Unmarshal(wire))
require.Equal(t, metaHeaderFrom, metaHeaderTo)
})
}
func TestResponseVerificationHeader_StableMarshal(t *testing.T) {
verifHeaderOrigin := generateResponseVerificationHeader("Key", "Inside")
verifHeaderFrom := generateResponseVerificationHeader("Value", "Outside")
verifHeaderFrom.SetOrigin(verifHeaderOrigin)
t.Run("non empty", func(t *testing.T) {
wire, err := verifHeaderFrom.StableMarshal(nil)
require.NoError(t, err)
verifHeaderTo := new(session.ResponseVerificationHeader)
require.NoError(t, verifHeaderTo.Unmarshal(wire))
require.Equal(t, verifHeaderFrom, verifHeaderTo)
})
}
func generateCreateSessionRequestBody(id string) *session.CreateRequestBody {
lifetime := new(session.TokenLifetime)
lifetime.SetIat(1)
lifetime.SetNbf(2)
lifetime.SetExp(3)
owner := new(refs.OwnerID)
owner.SetValue([]byte(id))
s := new(session.CreateRequestBody)
s.SetOwnerID(owner)
s.SetExpiration(10)
return s
}
func generateCreateSessionResponseBody(id, key string) *session.CreateResponseBody {
s := new(session.CreateResponseBody)
s.SetID([]byte(id))
s.SetSessionKey([]byte(key))
return s
}
func generateSignature(k, v string) *refs.Signature {
sig := new(refs.Signature)
sig.SetKey([]byte(k))
sig.SetSign([]byte(v))
return sig
}
func generateVersion(maj, min uint32) *refs.Version {
version := new(refs.Version)
version.SetMajor(maj)
version.SetMinor(min)
return version
}
func generateXHeader(k, v string) *session.XHeader {
xheader := new(session.XHeader)
xheader.SetKey(k)
xheader.SetValue(v)
return xheader
}
func generateLifetime(exp, nbf, iat uint64) *session.TokenLifetime {
lifetime := new(session.TokenLifetime)
lifetime.SetExp(exp)
lifetime.SetNbf(nbf)
lifetime.SetIat(iat)
return lifetime
}
func generateBearerLifetime(exp, nbf, iat uint64) *acl.TokenLifetime {
lifetime := new(acl.TokenLifetime)
lifetime.SetExp(exp)
lifetime.SetNbf(nbf)
lifetime.SetIat(iat)
return lifetime
}
func generateObjectCtx(id string) *session.ObjectSessionContext {
objectCtx := new(session.ObjectSessionContext)
objectCtx.SetVerb(session.ObjectVerbPut)
cid := new(refs.ContainerID)
cid.SetValue([]byte("ContainerID"))
oid := new(refs.ObjectID)
oid.SetValue([]byte(id))
addr := new(refs.Address)
addr.SetContainerID(cid)
addr.SetObjectID(oid)
objectCtx.SetAddress(addr)
return objectCtx
}
func generateEACL(n int, k, v string) *acl.Table {
target := new(acl.Target)
target.SetRole(acl.RoleUser)
keys := make([][]byte, n)
for i := 0; i < n; i++ {
s := fmt.Sprintf("Public Key %d", i+1)
keys[i] = []byte(s)
}
filter := new(acl.HeaderFilter)
filter.SetHeaderType(acl.HeaderTypeObject)
filter.SetMatchType(acl.MatchTypeStringEqual)
filter.SetKey(k)
filter.SetValue(v)
record := new(acl.Record)
record.SetOperation(acl.OperationHead)
record.SetAction(acl.ActionDeny)
record.SetTargets([]*acl.Target{target})
record.SetFilters([]*acl.HeaderFilter{filter})
table := new(acl.Table)
cid := new(refs.ContainerID)
cid.SetValue([]byte("Container ID"))
table.SetContainerID(cid)
table.SetRecords([]*acl.Record{record})
return table
}
func generateSessionTokenBody(id string) *session.SessionTokenBody {
owner := new(refs.OwnerID)
owner.SetValue([]byte("Owner ID"))
tokenBody := new(session.SessionTokenBody)
tokenBody.SetID([]byte(id))
tokenBody.SetOwnerID(owner)
tokenBody.SetSessionKey([]byte(id))
tokenBody.SetLifetime(generateLifetime(1, 2, 3))
tokenBody.SetContext(generateObjectCtx(id))
return tokenBody
}
func generateSessionToken(id string) *session.SessionToken {
sessionToken := new(session.SessionToken)
sessionToken.SetBody(generateSessionTokenBody(id))
sessionToken.SetSignature(generateSignature("id", id))
return sessionToken
}
func generateBearerTokenBody(id string) *acl.BearerTokenBody {
owner := new(refs.OwnerID)
owner.SetValue([]byte(id))
tokenBody := new(acl.BearerTokenBody)
tokenBody.SetOwnerID(owner)
tokenBody.SetLifetime(generateBearerLifetime(1, 2, 3))
tokenBody.SetEACL(generateEACL(10, "id", id))
return tokenBody
}
func generateBearerToken(id string) *acl.BearerToken {
bearerToken := new(acl.BearerToken)
bearerToken.SetBody(generateBearerTokenBody(id))
bearerToken.SetSignature(generateSignature("id", id))
return bearerToken
}
func generateRequestMetaHeader(n int, b, s string) *session.RequestMetaHeader {
reqMetaHeader := new(session.RequestMetaHeader)
reqMetaHeader.SetVersion(generateVersion(2, 0))
reqMetaHeader.SetEpoch(uint64(n))
reqMetaHeader.SetTTL(uint32(n))
reqMetaHeader.SetXHeaders([]*session.XHeader{
generateXHeader("key-one", "val-one"),
generateXHeader("key-two", "val-two"),
})
reqMetaHeader.SetBearerToken(generateBearerToken(b))
reqMetaHeader.SetSessionToken(generateSessionToken(s))
return reqMetaHeader
}
func generateRequestVerificationHeader(k, v string) *session.RequestVerificationHeader {
reqVerifHeader := new(session.RequestVerificationHeader)
reqVerifHeader.SetBodySignature(generateSignature(k+"body", v+"body"))
reqVerifHeader.SetMetaSignature(generateSignature(k+"meta", v+"meta"))
reqVerifHeader.SetOriginSignature(generateSignature(k+"orig", v+"orig"))
return reqVerifHeader
}
func generateResponseMetaHeader(n int) *session.ResponseMetaHeader {
respMetaHeader := new(session.ResponseMetaHeader)
respMetaHeader.SetVersion(generateVersion(2, 0))
respMetaHeader.SetEpoch(uint64(n))
respMetaHeader.SetTTL(uint32(n))
respMetaHeader.SetXHeaders([]*session.XHeader{
generateXHeader("key-one", "val-one"),
generateXHeader("key-two", "val-two"),
})
return respMetaHeader
}
func generateResponseVerificationHeader(k, v string) *session.ResponseVerificationHeader {
respVerifHeader := new(session.ResponseVerificationHeader)
respVerifHeader.SetBodySignature(generateSignature(k+"body", v+"body"))
respVerifHeader.SetMetaSignature(generateSignature(k+"meta", v+"meta"))
respVerifHeader.SetOriginSignature(generateSignature(k+"orig", v+"orig"))
return respVerifHeader
}

View file

@ -0,0 +1,26 @@
package session_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/rpc/message"
rpctest "github.com/nspcc-dev/neofs-api-go/rpc/message/test"
sessiontest "github.com/nspcc-dev/neofs-api-go/v2/session/test"
)
func TestMessageConvert(t *testing.T) {
rpctest.TestRPCMessage(t,
func(empty bool) message.Message { return sessiontest.GenerateCreateRequestBody(empty) },
func(empty bool) message.Message { return sessiontest.GenerateCreateRequest(empty) },
func(empty bool) message.Message { return sessiontest.GenerateCreateResponseBody(empty) },
func(empty bool) message.Message { return sessiontest.GenerateCreateResponse(empty) },
func(empty bool) message.Message { return sessiontest.GenerateTokenLifetime(empty) },
func(empty bool) message.Message { return sessiontest.GenerateXHeader(empty) },
func(empty bool) message.Message { return sessiontest.GenerateSessionTokenBody(empty) },
func(empty bool) message.Message { return sessiontest.GenerateSessionToken(empty) },
func(empty bool) message.Message { return sessiontest.GenerateRequestMetaHeader(empty) },
func(empty bool) message.Message { return sessiontest.GenerateRequestVerificationHeader(empty) },
func(empty bool) message.Message { return sessiontest.GenerateResponseMetaHeader(empty) },
func(empty bool) message.Message { return sessiontest.GenerateResponseVerificationHeader(empty) },
)
}

View file

@ -1,25 +0,0 @@
package session
import (
"context"
)
type Service interface {
Create(context.Context, *CreateRequest) (*CreateResponse, error)
}
type CreateRequest struct {
body *CreateRequestBody
metaHeader *RequestMetaHeader
verifyHeader *RequestVerificationHeader
}
type CreateResponse struct {
body *CreateResponseBody
metaHeader *ResponseMetaHeader
verifyHeader *ResponseVerificationHeader
}

View file

@ -1,159 +0,0 @@
package main
import (
"context"
"crypto/ecdsa"
"errors"
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-api-go/v2/session"
sessionGRPC "github.com/nspcc-dev/neofs-api-go/v2/session/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/signature"
"github.com/nspcc-dev/neofs-crypto/test"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
)
type testGRPCClient struct {
server *testGRPCServer
}
type testGRPCServer struct {
key *ecdsa.PrivateKey
resp *session.CreateResponse
err error
}
func (s *testGRPCClient) Create(ctx context.Context, in *sessionGRPC.CreateRequest, opts ...grpc.CallOption) (*sessionGRPC.CreateResponse, error) {
return s.server.Create(ctx, in)
}
func (s *testGRPCServer) Create(_ context.Context, req *sessionGRPC.CreateRequest) (*sessionGRPC.CreateResponse, error) {
if s.err != nil {
return nil, s.err
}
// verify request structure
if err := signature.VerifyServiceMessage(
session.CreateRequestFromGRPCMessage(req),
); err != nil {
return nil, err
}
// sign response structure
if err := signature.SignServiceMessage(s.key, s.resp); err != nil {
return nil, err
}
return session.CreateResponseToGRPCMessage(s.resp), nil
}
func testRequest() *session.CreateRequest {
ownerID := new(refs.OwnerID)
ownerID.SetValue([]byte{1, 2, 3})
body := new(session.CreateRequestBody)
body.SetOwnerID(ownerID)
meta := new(session.RequestMetaHeader)
meta.SetTTL(1)
req := new(session.CreateRequest)
req.SetBody(body)
req.SetMetaHeader(meta)
return req
}
func testResponse() *session.CreateResponse {
body := new(session.CreateResponseBody)
body.SetID([]byte{1, 2, 3})
meta := new(session.ResponseMetaHeader)
meta.SetTTL(1)
resp := new(session.CreateResponse)
resp.SetBody(body)
resp.SetMetaHeader(meta)
return resp
}
func TestGRPCClient(t *testing.T) {
ctx := context.TODO()
cliKey := test.DecodeKey(0)
srvKey := test.DecodeKey(1)
t.Run("gRPC server error", func(t *testing.T) {
srvErr := errors.New("test server error")
srv := &testGRPCServer{
err: srvErr,
}
cli := &testGRPCClient{
server: srv,
}
c, err := session.NewClient(session.WithGRPCServiceClient(cli))
require.NoError(t, err)
resp, err := c.Create(ctx, new(session.CreateRequest))
require.True(t, errors.Is(err, srvErr))
require.Nil(t, resp)
})
t.Run("invalid request structure", func(t *testing.T) {
req := testRequest()
require.Error(t, signature.VerifyServiceMessage(req))
c, err := session.NewClient(
session.WithGRPCServiceClient(
&testGRPCClient{
server: new(testGRPCServer),
},
),
)
require.NoError(t, err)
resp, err := c.Create(ctx, req)
require.Error(t, err)
require.Nil(t, resp)
})
t.Run("correct response", func(t *testing.T) {
req := testRequest()
require.NoError(t, signature.SignServiceMessage(cliKey, req))
resp := testResponse()
{ // w/o this require.Equal fails due to nil and []T{} difference
meta := new(session.ResponseMetaHeader)
meta.SetXHeaders([]*session.XHeader{})
resp.SetMetaHeader(meta)
}
c, err := session.NewClient(
session.WithGRPCServiceClient(
&testGRPCClient{
server: &testGRPCServer{
key: srvKey,
resp: resp,
},
},
),
)
require.NoError(t, err)
r, err := c.Create(ctx, req)
require.NoError(t, err)
require.NoError(t, signature.VerifyServiceMessage(r))
require.Equal(t, resp.GetBody(), r.GetBody())
require.Equal(t, resp.GetMetaHeader(), r.GetMetaHeader())
})
}

204
v2/session/test/generate.go Normal file
View file

@ -0,0 +1,204 @@
package sessiontest
import (
acltest "github.com/nspcc-dev/neofs-api-go/v2/acl/test"
refstest "github.com/nspcc-dev/neofs-api-go/v2/refs/test"
"github.com/nspcc-dev/neofs-api-go/v2/session"
)
func GenerateCreateRequestBody(empty bool) *session.CreateRequestBody {
m := new(session.CreateRequestBody)
if !empty {
m.SetExpiration(555)
}
m.SetOwnerID(refstest.GenerateOwnerID(empty))
return m
}
func GenerateCreateRequest(empty bool) *session.CreateRequest {
m := new(session.CreateRequest)
m.SetBody(GenerateCreateRequestBody(empty))
m.SetMetaHeader(GenerateRequestMetaHeader(empty))
m.SetVerificationHeader(GenerateRequestVerificationHeader(empty))
return m
}
func GenerateCreateResponseBody(empty bool) *session.CreateResponseBody {
m := new(session.CreateResponseBody)
if !empty {
m.SetID([]byte{1, 2, 3})
m.SetSessionKey([]byte{4, 5, 6})
}
return m
}
func GenerateCreateResponse(empty bool) *session.CreateResponse {
m := new(session.CreateResponse)
m.SetBody(GenerateCreateResponseBody(empty))
m.SetMetaHeader(GenerateResponseMetaHeader(empty))
m.SetVerificationHeader(GenerateResponseVerificationHeader(empty))
return m
}
func GenerateResponseVerificationHeader(empty bool) *session.ResponseVerificationHeader {
return generateResponseVerificationHeader(empty, true)
}
func generateResponseVerificationHeader(empty, withOrigin bool) *session.ResponseVerificationHeader {
m := new(session.ResponseVerificationHeader)
m.SetBodySignature(refstest.GenerateSignature(empty))
m.SetMetaSignature(refstest.GenerateSignature(empty))
m.SetOriginSignature(refstest.GenerateSignature(empty))
if withOrigin {
m.SetOrigin(generateResponseVerificationHeader(empty, false))
}
return m
}
func GenerateResponseMetaHeader(empty bool) *session.ResponseMetaHeader {
return generateResponseMetaHeader(empty, true)
}
func generateResponseMetaHeader(empty, withOrigin bool) *session.ResponseMetaHeader {
m := new(session.ResponseMetaHeader)
if !empty {
m.SetEpoch(13)
m.SetTTL(100)
}
m.SetXHeaders(GenerateXHeaders(empty))
m.SetVersion(refstest.GenerateVersion(empty))
if withOrigin {
m.SetOrigin(generateResponseMetaHeader(empty, false))
}
return m
}
func GenerateRequestVerificationHeader(empty bool) *session.RequestVerificationHeader {
return generateRequestVerificationHeader(empty, true)
}
func generateRequestVerificationHeader(empty, withOrigin bool) *session.RequestVerificationHeader {
m := new(session.RequestVerificationHeader)
m.SetBodySignature(refstest.GenerateSignature(empty))
m.SetMetaSignature(refstest.GenerateSignature(empty))
m.SetOriginSignature(refstest.GenerateSignature(empty))
if withOrigin {
m.SetOrigin(generateRequestVerificationHeader(empty, false))
}
return m
}
func GenerateRequestMetaHeader(empty bool) *session.RequestMetaHeader {
return generateRequestMetaHeader(empty, true)
}
func generateRequestMetaHeader(empty, withOrigin bool) *session.RequestMetaHeader {
m := new(session.RequestMetaHeader)
if !empty {
m.SetEpoch(13)
m.SetTTL(100)
}
m.SetXHeaders(GenerateXHeaders(empty))
m.SetVersion(refstest.GenerateVersion(empty))
m.SetSessionToken(GenerateSessionToken(empty))
m.SetBearerToken(acltest.GenerateBearerToken(empty))
if withOrigin {
m.SetOrigin(generateRequestMetaHeader(empty, false))
}
return m
}
func GenerateSessionToken(empty bool) *session.SessionToken {
m := new(session.SessionToken)
m.SetBody(GenerateSessionTokenBody(empty))
m.SetSignature(refstest.GenerateSignature(empty))
return m
}
func GenerateSessionTokenBody(empty bool) *session.SessionTokenBody {
m := new(session.SessionTokenBody)
if !empty {
m.SetID([]byte{1})
m.SetSessionKey([]byte{2})
}
m.SetOwnerID(refstest.GenerateOwnerID(empty))
m.SetLifetime(GenerateTokenLifetime(empty))
m.SetContext(GenerateObjectSessionContext(empty))
return m
}
func GenerateTokenLifetime(empty bool) *session.TokenLifetime {
m := new(session.TokenLifetime)
if !empty {
m.SetExp(1)
m.SetIat(2)
m.SetExp(3)
}
return m
}
func GenerateObjectSessionContext(empty bool) *session.ObjectSessionContext {
m := new(session.ObjectSessionContext)
if !empty {
m.SetVerb(session.ObjectVerbHead)
}
m.SetAddress(refstest.GenerateAddress(empty))
return m
}
func GenerateXHeader(empty bool) *session.XHeader {
m := new(session.XHeader)
if !empty {
m.SetKey("key")
m.SetValue("val")
}
return m
}
func GenerateXHeaders(empty bool) []*session.XHeader {
xs := make([]*session.XHeader, 0)
if !empty {
xs = append(xs,
GenerateXHeader(false),
GenerateXHeader(false),
)
}
return xs
}

View file

@ -11,12 +11,24 @@ type CreateRequestBody struct {
expiration uint64 expiration uint64
} }
type CreateRequest struct {
body *CreateRequestBody
RequestHeaders
}
type CreateResponseBody struct { type CreateResponseBody struct {
id []byte id []byte
sessionKey []byte sessionKey []byte
} }
type CreateResponse struct {
body *CreateResponseBody
ResponseHeaders
}
type XHeader struct { type XHeader struct {
key, val string key, val string
} }

View file

@ -1,5 +1,9 @@
package session package session
import (
session "github.com/nspcc-dev/neofs-api-go/v2/session/grpc"
)
// RequestHeaders represents common part of // RequestHeaders represents common part of
// all NeoFS requests including headers. // all NeoFS requests including headers.
type RequestHeaders struct { type RequestHeaders struct {
@ -40,6 +44,49 @@ func (c *RequestHeaders) SetVerificationHeader(v *RequestVerificationHeader) {
} }
} }
func (c *RequestHeaders) ToMessage(m interface {
SetMetaHeader(*session.RequestMetaHeader)
SetVerifyHeader(*session.RequestVerificationHeader)
}) {
m.SetMetaHeader(c.metaHeader.ToGRPCMessage().(*session.RequestMetaHeader))
m.SetVerifyHeader(c.verifyHeader.ToGRPCMessage().(*session.RequestVerificationHeader))
}
func (c *RequestHeaders) FromMessage(m interface {
GetMetaHeader() *session.RequestMetaHeader
GetVerifyHeader() *session.RequestVerificationHeader
}) error {
metaHdr := m.GetMetaHeader()
if metaHdr == nil {
c.metaHeader = nil
} else {
if c.metaHeader == nil {
c.metaHeader = new(RequestMetaHeader)
}
err := c.metaHeader.FromGRPCMessage(metaHdr)
if err != nil {
return err
}
}
verifyHdr := m.GetVerifyHeader()
if verifyHdr == nil {
c.verifyHeader = nil
} else {
if c.verifyHeader == nil {
c.verifyHeader = new(RequestVerificationHeader)
}
err := c.verifyHeader.FromGRPCMessage(verifyHdr)
if err != nil {
return err
}
}
return nil
}
// ResponseHeaders represents common part of // ResponseHeaders represents common part of
// all NeoFS responses including headers. // all NeoFS responses including headers.
type ResponseHeaders struct { type ResponseHeaders struct {
@ -79,3 +126,46 @@ func (c *ResponseHeaders) SetVerificationHeader(v *ResponseVerificationHeader) {
c.verifyHeader = v c.verifyHeader = v
} }
} }
func (c *ResponseHeaders) ToMessage(m interface {
SetMetaHeader(*session.ResponseMetaHeader)
SetVerifyHeader(*session.ResponseVerificationHeader)
}) {
m.SetMetaHeader(c.metaHeader.ToGRPCMessage().(*session.ResponseMetaHeader))
m.SetVerifyHeader(c.verifyHeader.ToGRPCMessage().(*session.ResponseVerificationHeader))
}
func (c *ResponseHeaders) FromMessage(m interface {
GetMetaHeader() *session.ResponseMetaHeader
GetVerifyHeader() *session.ResponseVerificationHeader
}) error {
metaHdr := m.GetMetaHeader()
if metaHdr == nil {
c.metaHeader = nil
} else {
if c.metaHeader == nil {
c.metaHeader = new(ResponseMetaHeader)
}
err := c.metaHeader.FromGRPCMessage(metaHdr)
if err != nil {
return err
}
}
verifyHdr := m.GetVerifyHeader()
if verifyHdr == nil {
c.verifyHeader = nil
} else {
if c.verifyHeader == nil {
c.verifyHeader = new(ResponseVerificationHeader)
}
err := c.verifyHeader.FromGRPCMessage(verifyHdr)
if err != nil {
return err
}
}
return nil
}

View file

@ -1,48 +1,57 @@
package storagegroup package storagegroup
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/grpc"
"github.com/nspcc-dev/neofs-api-go/rpc/message"
"github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-api-go/v2/refs"
refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
sg "github.com/nspcc-dev/neofs-api-go/v2/storagegroup/grpc" sg "github.com/nspcc-dev/neofs-api-go/v2/storagegroup/grpc"
) )
// StorageGroupToGRPCMessage converts unified proto structure into grpc structure. func (s *StorageGroup) ToGRPCMessage() grpc.Message {
func StorageGroupToGRPCMessage(s *StorageGroup) *sg.StorageGroup {
if s == nil {
return nil
}
m := new(sg.StorageGroup) m := new(sg.StorageGroup)
m.SetValidationDataSize(s.GetValidationDataSize()) if s != nil {
m.SetValidationHash( m = new(sg.StorageGroup)
refs.ChecksumToGRPCMessage(s.GetValidationHash()),
)
m.SetExpirationEpoch(s.GetExpirationEpoch())
m.SetMembers( m.SetMembers(refs.ObjectIDListToGRPCMessage(s.members))
refs.ObjectIDListToGRPCMessage(s.GetMembers()), m.SetExpirationEpoch(s.exp)
) m.SetValidationDataSize(s.size)
m.SetValidationHash(s.hash.ToGRPCMessage().(*refsGRPC.Checksum))
}
return m return m
} }
// StorageGroupFromGRPCMessage converts grpc structure into unified proto structure. func (s *StorageGroup) FromGRPCMessage(m grpc.Message) error {
func StorageGroupFromGRPCMessage(m *sg.StorageGroup) *StorageGroup { v, ok := m.(*sg.StorageGroup)
if m == nil { if !ok {
return nil return message.NewUnexpectedMessageType(m, v)
} }
s := new(StorageGroup) var err error
s.SetValidationDataSize(m.GetValidationDataSize()) hash := v.GetValidationHash()
s.SetValidationHash( if hash == nil {
refs.ChecksumFromGRPCMessage(m.GetValidationHash()), s.hash = nil
) } else {
s.SetExpirationEpoch(m.GetExpirationEpoch()) if s.hash == nil {
s.hash = new(refs.Checksum)
}
s.SetMembers( err = s.hash.FromGRPCMessage(hash)
refs.ObjectIDListFromGRPCMessage(m.GetMembers()), if err != nil {
) return err
}
}
return s s.members, err = refs.ObjectIDListFromGRPCMessage(v.GetMembers())
if err != nil {
return err
}
s.exp = v.GetExpirationEpoch()
s.size = v.GetValidationDataSize()
return nil
} }

View file

@ -1,26 +1,14 @@
package storagegroup package storagegroup
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
storagegroup "github.com/nspcc-dev/neofs-api-go/v2/storagegroup/grpc" storagegroup "github.com/nspcc-dev/neofs-api-go/v2/storagegroup/grpc"
"google.golang.org/protobuf/encoding/protojson"
) )
func (s *StorageGroup) MarshalJSON() ([]byte, error) { func (s *StorageGroup) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(s)
EmitUnpopulated: true,
}.Marshal(
StorageGroupToGRPCMessage(s),
)
} }
func (s *StorageGroup) UnmarshalJSON(data []byte) error { func (s *StorageGroup) UnmarshalJSON(data []byte) error {
msg := new(storagegroup.StorageGroup) return message.UnmarshalJSON(s, data, new(storagegroup.StorageGroup))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*s = *StorageGroupFromGRPCMessage(msg)
return nil
} }

View file

@ -1,20 +0,0 @@
package storagegroup_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/storagegroup"
"github.com/stretchr/testify/require"
)
func TestStorageGroupJSON(t *testing.T) {
sg := generateSG()
data, err := sg.MarshalJSON()
require.NoError(t, err)
sg2 := new(storagegroup.StorageGroup)
require.NoError(t, sg2.UnmarshalJSON(data))
require.Equal(t, sg, sg2)
}

View file

@ -1,10 +1,10 @@
package storagegroup package storagegroup
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
"github.com/nspcc-dev/neofs-api-go/util/proto" "github.com/nspcc-dev/neofs-api-go/util/proto"
"github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-api-go/v2/refs"
storagegroup "github.com/nspcc-dev/neofs-api-go/v2/storagegroup/grpc" storagegroup "github.com/nspcc-dev/neofs-api-go/v2/storagegroup/grpc"
goproto "google.golang.org/protobuf/proto"
) )
const ( const (
@ -74,12 +74,5 @@ func (s *StorageGroup) StableSize() (size int) {
} }
func (s *StorageGroup) Unmarshal(data []byte) error { func (s *StorageGroup) Unmarshal(data []byte) error {
m := new(storagegroup.StorageGroup) return message.Unmarshal(s, data, new(storagegroup.StorageGroup))
if err := goproto.Unmarshal(data, m); err != nil {
return err
}
*s = *StorageGroupFromGRPCMessage(m)
return nil
} }

View file

@ -1,48 +0,0 @@
package storagegroup_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-api-go/v2/storagegroup"
"github.com/stretchr/testify/require"
)
func TestStorageGroup_StableMarshal(t *testing.T) {
storageGroupFrom := generateSG()
t.Run("non empty", func(t *testing.T) {
wire, err := storageGroupFrom.StableMarshal(nil)
require.NoError(t, err)
storageGroupTo := new(storagegroup.StorageGroup)
require.NoError(t, storageGroupTo.Unmarshal(wire))
require.Equal(t, storageGroupFrom, storageGroupTo)
})
}
func generateChecksum(data string) *refs.Checksum {
checksum := new(refs.Checksum)
checksum.SetType(refs.TillichZemor)
checksum.SetSum([]byte(data))
return checksum
}
func generateSG() *storagegroup.StorageGroup {
sg := new(storagegroup.StorageGroup)
oid1 := new(refs.ObjectID)
oid1.SetValue([]byte("Object ID 1"))
oid2 := new(refs.ObjectID)
oid2.SetValue([]byte("Object ID 2"))
sg.SetValidationDataSize(300)
sg.SetValidationHash(generateChecksum("Homomorphic hash"))
sg.SetExpirationEpoch(100)
sg.SetMembers([]*refs.ObjectID{oid1, oid2})
return sg
}

View file

@ -0,0 +1,15 @@
package storagegroup_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/rpc/message"
messagetest "github.com/nspcc-dev/neofs-api-go/rpc/message/test"
storagegrouptest "github.com/nspcc-dev/neofs-api-go/v2/storagegroup/test"
)
func TestMessageConvert(t *testing.T) {
messagetest.TestRPCMessage(t,
func(empty bool) message.Message { return storagegrouptest.GenerateStorageGroup(empty) },
)
}

View file

@ -0,0 +1,20 @@
package storagegrouptest
import (
refstest "github.com/nspcc-dev/neofs-api-go/v2/refs/test"
"github.com/nspcc-dev/neofs-api-go/v2/storagegroup"
)
func GenerateStorageGroup(empty bool) *storagegroup.StorageGroup {
m := new(storagegroup.StorageGroup)
if !empty {
m.SetValidationDataSize(44)
m.SetExpirationEpoch(55)
}
m.SetValidationHash(refstest.GenerateChecksum(empty))
m.SetMembers(refstest.GenerateObjectIDs(empty))
return m
}

View file

@ -1,53 +1,41 @@
package tombstone package tombstone
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/grpc"
"github.com/nspcc-dev/neofs-api-go/rpc/message"
"github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-api-go/v2/refs"
refsGRPC "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc"
tombstone "github.com/nspcc-dev/neofs-api-go/v2/tombstone/grpc" tombstone "github.com/nspcc-dev/neofs-api-go/v2/tombstone/grpc"
) )
// TombstoneToGRPCMessage converts unified tombstone message into gRPC message. func (s *Tombstone) ToGRPCMessage() grpc.Message {
func TombstoneToGRPCMessage(t *Tombstone) *tombstone.Tombstone { var m *tombstone.Tombstone
if t == nil {
return nil if s != nil {
m = new(tombstone.Tombstone)
m.SetMembers(refs.ObjectIDListToGRPCMessage(s.members))
m.SetExpirationEpoch(s.exp)
m.SetSplitId(s.splitID)
} }
m := new(tombstone.Tombstone)
m.SetExpirationEpoch(t.GetExpirationEpoch())
m.SetSplitId(t.GetSplitID())
members := t.GetMembers()
memberMsg := make([]*refsGRPC.ObjectID, 0, len(members))
for i := range members {
memberMsg = append(memberMsg, refs.ObjectIDToGRPCMessage(members[i]))
}
m.SetMembers(memberMsg)
return m return m
} }
// TombstoneFromGRPCMessage converts gRPC message into unified tombstone message. func (s *Tombstone) FromGRPCMessage(m grpc.Message) error {
func TombstoneFromGRPCMessage(m *tombstone.Tombstone) *Tombstone { v, ok := m.(*tombstone.Tombstone)
if m == nil { if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var err error
s.members, err = refs.ObjectIDListFromGRPCMessage(v.GetMembers())
if err != nil {
return err
}
s.exp = v.GetExpirationEpoch()
s.splitID = v.GetSplitId()
return nil return nil
}
t := new(Tombstone)
t.SetExpirationEpoch(m.GetExpirationEpoch())
t.SetSplitID(m.GetSplitId())
memberMsg := m.GetMembers()
members := make([]*refs.ObjectID, 0, len(memberMsg))
for i := range memberMsg {
members = append(members, refs.ObjectIDFromGRPCMessage(memberMsg[i]))
}
t.SetMembers(members)
return t
} }

View file

@ -1,26 +1,14 @@
package tombstone package tombstone
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
tombstone "github.com/nspcc-dev/neofs-api-go/v2/tombstone/grpc" tombstone "github.com/nspcc-dev/neofs-api-go/v2/tombstone/grpc"
"google.golang.org/protobuf/encoding/protojson"
) )
func (s *Tombstone) MarshalJSON() ([]byte, error) { func (s *Tombstone) MarshalJSON() ([]byte, error) {
return protojson.MarshalOptions{ return message.MarshalJSON(s)
EmitUnpopulated: true,
}.Marshal(
TombstoneToGRPCMessage(s),
)
} }
func (s *Tombstone) UnmarshalJSON(data []byte) error { func (s *Tombstone) UnmarshalJSON(data []byte) error {
msg := new(tombstone.Tombstone) return message.UnmarshalJSON(s, data, new(tombstone.Tombstone))
if err := protojson.Unmarshal(data, msg); err != nil {
return err
}
*s = *TombstoneFromGRPCMessage(msg)
return nil
} }

View file

@ -1,20 +0,0 @@
package tombstone_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/tombstone"
"github.com/stretchr/testify/require"
)
func TestTombstoneJSON(t *testing.T) {
from := generateTombstone()
data, err := from.MarshalJSON()
require.NoError(t, err)
to := new(tombstone.Tombstone)
require.NoError(t, to.UnmarshalJSON(data))
require.Equal(t, from, to)
}

View file

@ -1,9 +1,9 @@
package tombstone package tombstone
import ( import (
"github.com/nspcc-dev/neofs-api-go/rpc/message"
"github.com/nspcc-dev/neofs-api-go/util/proto" "github.com/nspcc-dev/neofs-api-go/util/proto"
tombstone "github.com/nspcc-dev/neofs-api-go/v2/tombstone/grpc" tombstone "github.com/nspcc-dev/neofs-api-go/v2/tombstone/grpc"
goproto "google.golang.org/protobuf/proto"
) )
const ( const (
@ -72,12 +72,5 @@ func (s *Tombstone) StableSize() (size int) {
// Unmarshal unmarshal tombstone message from its binary representation. // Unmarshal unmarshal tombstone message from its binary representation.
func (s *Tombstone) Unmarshal(data []byte) error { func (s *Tombstone) Unmarshal(data []byte) error {
m := new(tombstone.Tombstone) return message.Unmarshal(s, data, new(tombstone.Tombstone))
if err := goproto.Unmarshal(data, m); err != nil {
return err
}
*s = *TombstoneFromGRPCMessage(m)
return nil
} }

View file

@ -1,39 +0,0 @@
package tombstone_test
import (
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-api-go/v2/tombstone"
"github.com/stretchr/testify/require"
)
func TestTombstone_StableMarshal(t *testing.T) {
from := generateTombstone()
t.Run("non empty", func(t *testing.T) {
wire, err := from.StableMarshal(nil)
require.NoError(t, err)
to := new(tombstone.Tombstone)
require.NoError(t, to.Unmarshal(wire))
require.Equal(t, from, to)
})
}
func generateTombstone() *tombstone.Tombstone {
t := new(tombstone.Tombstone)
oid1 := new(refs.ObjectID)
oid1.SetValue([]byte("Object ID 1"))
oid2 := new(refs.ObjectID)
oid2.SetValue([]byte("Object ID 2"))
t.SetExpirationEpoch(100)
t.SetSplitID([]byte("split ID"))
t.SetMembers([]*refs.ObjectID{oid1, oid2})
return t
}

Some files were not shown because too many files have changed in this diff Show more