forked from TrueCloudLab/frostfs-api-go
[#245] pkg/client: Add AnnounceContainerUsedSpace method
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
parent
d2ee6b469a
commit
5566081d2d
3 changed files with 159 additions and 0 deletions
|
@ -153,6 +153,20 @@ func (c Client) SetEACL(ctx context.Context, eacl *eacl.Table, opts ...CallOptio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AnnounceContainerUsedSpace used by storage nodes to estimate their container
|
||||||
|
// sizes during lifetime. Use it only in storage node applications.
|
||||||
|
func (c Client) AnnounceContainerUsedSpace(
|
||||||
|
ctx context.Context,
|
||||||
|
announce []container.UsedSpaceAnnouncement,
|
||||||
|
opts ...CallOption) error {
|
||||||
|
switch c.remoteNode.Version.Major() {
|
||||||
|
case 2:
|
||||||
|
return c.announceContainerUsedSpaceV2(ctx, announce, opts...)
|
||||||
|
default:
|
||||||
|
return errUnsupportedProtocol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c Client) putContainerV2(ctx context.Context, cnr *container.Container, opts ...CallOption) (*container.ID, error) {
|
func (c Client) putContainerV2(ctx context.Context, cnr *container.Container, opts ...CallOption) (*container.ID, error) {
|
||||||
// apply all available options
|
// apply all available options
|
||||||
callOptions := c.defaultCallOptions()
|
callOptions := c.defaultCallOptions()
|
||||||
|
@ -495,6 +509,60 @@ func (c Client) setEACLV2(ctx context.Context, eacl *eacl.Table, opts ...CallOpt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c Client) announceContainerUsedSpaceV2(
|
||||||
|
ctx context.Context,
|
||||||
|
announce []container.UsedSpaceAnnouncement,
|
||||||
|
opts ...CallOption) error {
|
||||||
|
callOptions := c.defaultCallOptions() // apply all available options
|
||||||
|
|
||||||
|
for i := range opts {
|
||||||
|
opts[i].apply(&callOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert list of SDK announcement structures into NeoFS-API v2 list
|
||||||
|
v2announce := make([]*v2container.UsedSpaceAnnouncement, 0, len(announce))
|
||||||
|
for i := range announce {
|
||||||
|
v2announce = append(v2announce, announce[i].ToV2())
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare body of the NeoFS-API v2 request and request itself
|
||||||
|
reqBody := new(v2container.AnnounceUsedSpaceRequestBody)
|
||||||
|
reqBody.SetAnnouncements(v2announce)
|
||||||
|
|
||||||
|
req := new(v2container.AnnounceUsedSpaceRequest)
|
||||||
|
req.SetBody(reqBody)
|
||||||
|
req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions))
|
||||||
|
|
||||||
|
// sign the request
|
||||||
|
err := v2signature.SignServiceMessage(c.key, req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// choose underline transport protocol and send message over it
|
||||||
|
switch c.remoteNode.Protocol {
|
||||||
|
case GRPC:
|
||||||
|
cli, err := v2ContainerClientFromOptions(c.opts)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "can't create grpc client")
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := cli.AnnounceUsedSpace(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "transport error")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = v2signature.VerifyServiceMessage(resp)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "can't verify response message")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return errUnsupportedProtocol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func v2ContainerClientFromOptions(opts *clientOptions) (cli *v2container.Client, err error) {
|
func v2ContainerClientFromOptions(opts *clientOptions) (cli *v2container.Client, err error) {
|
||||||
switch {
|
switch {
|
||||||
case opts.grpcOpts.v2ContainerClient != nil:
|
case opts.grpcOpts.v2ContainerClient != nil:
|
||||||
|
|
47
pkg/container/announcement.go
Normal file
47
pkg/container/announcement.go
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package container
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/container"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UsedSpaceAnnouncement is an announcement message used by storage nodes to
|
||||||
|
// estimate actual container sizes.
|
||||||
|
type UsedSpaceAnnouncement container.UsedSpaceAnnouncement
|
||||||
|
|
||||||
|
// NewAnnouncement initialize empty UsedSpaceAnnouncement message.
|
||||||
|
func NewAnnouncement() *UsedSpaceAnnouncement {
|
||||||
|
return NewAnnouncementFromV2(new(container.UsedSpaceAnnouncement))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAnnouncementFromV2 wraps protocol dependent version of
|
||||||
|
// UsedSpaceAnnouncement message.
|
||||||
|
func NewAnnouncementFromV2(v *container.UsedSpaceAnnouncement) *UsedSpaceAnnouncement {
|
||||||
|
return (*UsedSpaceAnnouncement)(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainerID of the announcement.
|
||||||
|
func (a *UsedSpaceAnnouncement) ContainerID() *ID {
|
||||||
|
return NewIDFromV2(
|
||||||
|
(*container.UsedSpaceAnnouncement)(a).GetContainerID(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetContainerID sets announcement container value.
|
||||||
|
func (a *UsedSpaceAnnouncement) SetContainerID(cid *ID) {
|
||||||
|
(*container.UsedSpaceAnnouncement)(a).SetContainerID(cid.ToV2())
|
||||||
|
}
|
||||||
|
|
||||||
|
// UsedSpace in container.
|
||||||
|
func (a *UsedSpaceAnnouncement) UsedSpace() uint64 {
|
||||||
|
return (*container.UsedSpaceAnnouncement)(a).GetUsedSpace()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUsedSpace sets used space value by specified container.
|
||||||
|
func (a *UsedSpaceAnnouncement) SetUsedSpace(value uint64) {
|
||||||
|
(*container.UsedSpaceAnnouncement)(a).SetUsedSpace(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToV2 returns protocol dependent version of UsedSpaceAnnouncement message.
|
||||||
|
func (a *UsedSpaceAnnouncement) ToV2() *container.UsedSpaceAnnouncement {
|
||||||
|
return (*container.UsedSpaceAnnouncement)(a)
|
||||||
|
}
|
44
pkg/container/announcement_test.go
Normal file
44
pkg/container/announcement_test.go
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
package container_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg/container"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAnnouncement(t *testing.T) {
|
||||||
|
const usedSpace uint64 = 100
|
||||||
|
|
||||||
|
cidValue := [32]byte{1, 2, 3}
|
||||||
|
cid := container.NewID()
|
||||||
|
cid.SetSHA256(cidValue)
|
||||||
|
|
||||||
|
a := container.NewAnnouncement()
|
||||||
|
a.SetContainerID(cid)
|
||||||
|
a.SetUsedSpace(usedSpace)
|
||||||
|
|
||||||
|
require.Equal(t, usedSpace, a.UsedSpace())
|
||||||
|
require.Equal(t, cid, a.ContainerID())
|
||||||
|
|
||||||
|
t.Run("test v2", func(t *testing.T) {
|
||||||
|
const newUsedSpace uint64 = 200
|
||||||
|
|
||||||
|
newCidValue := [32]byte{4, 5, 6}
|
||||||
|
newCID := new(refs.ContainerID)
|
||||||
|
newCID.SetValue(newCidValue[:])
|
||||||
|
|
||||||
|
v2 := a.ToV2()
|
||||||
|
require.Equal(t, usedSpace, v2.GetUsedSpace())
|
||||||
|
require.Equal(t, cidValue[:], v2.GetContainerID().GetValue())
|
||||||
|
|
||||||
|
v2.SetUsedSpace(newUsedSpace)
|
||||||
|
v2.SetContainerID(newCID)
|
||||||
|
|
||||||
|
newA := container.NewAnnouncementFromV2(v2)
|
||||||
|
|
||||||
|
require.Equal(t, newUsedSpace, newA.UsedSpace())
|
||||||
|
require.Equal(t, container.NewIDFromV2(newCID), newA.ContainerID())
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in a new issue