[#245] v2/container: Add AnnounceUsedSpace method

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2021-01-21 17:57:04 +03:00 committed by Alex Vanin
parent 5d9ef5feec
commit d2ee6b469a
11 changed files with 718 additions and 8 deletions

View file

@ -23,6 +23,8 @@ type Client struct {
cSetEACL *setEACLClient
cGetEACL *getEACLClient
cAnnounce *announceUsedSpaceClient
}
// Option represents Client option.
@ -94,6 +96,14 @@ type getEACLClient struct {
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.
@ -166,6 +176,19 @@ func (c *Client) GetExtendedACL(ctx context.Context, req *GetExtendedACLRequest)
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,
@ -255,6 +278,17 @@ func NewClient(opts ...Option) (*Client, error) {
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

View file

@ -849,3 +849,163 @@ func GetExtendedACLResponseFromGRPCMessage(m *container.GetExtendedACLResponse)
return r
}
func UsedSpaceAnnouncementToGRPCMessage(a *UsedSpaceAnnouncement) *container.AnnounceUsedSpaceRequest_Body_Announcement {
if a == nil {
return nil
}
m := new(container.AnnounceUsedSpaceRequest_Body_Announcement)
m.SetContainerId(
refs.ContainerIDToGRPCMessage(a.GetContainerID()),
)
m.SetUsedSpace(a.GetUsedSpace())
return m
}
func UsedSpaceAnnouncementFromGRPCMessage(m *container.AnnounceUsedSpaceRequest_Body_Announcement) *UsedSpaceAnnouncement {
if m == nil {
return nil
}
a := new(UsedSpaceAnnouncement)
a.SetContainerID(
refs.ContainerIDFromGRPCMessage(m.GetContainerId()),
)
a.SetUsedSpace(m.GetUsedSpace())
return a
}
func AnnounceUsedSpaceRequestBodyToGRPCMessage(r *AnnounceUsedSpaceRequestBody) *container.AnnounceUsedSpaceRequest_Body {
if r == nil {
return nil
}
m := new(container.AnnounceUsedSpaceRequest_Body)
announcements := r.GetAnnouncements()
msgAnnouncements := make([]*container.AnnounceUsedSpaceRequest_Body_Announcement, 0, len(announcements))
for i := range announcements {
msgAnnouncements = append(
msgAnnouncements,
UsedSpaceAnnouncementToGRPCMessage(announcements[i]),
)
}
m.SetAnnouncements(msgAnnouncements)
return m
}
func AnnounceUsedSpaceRequestBodyFromGRPCMessage(m *container.AnnounceUsedSpaceRequest_Body) *AnnounceUsedSpaceRequestBody {
if m == nil {
return nil
}
r := new(AnnounceUsedSpaceRequestBody)
msgAnnouncements := m.GetAnnouncements()
announcements := make([]*UsedSpaceAnnouncement, 0, len(msgAnnouncements))
for i := range msgAnnouncements {
announcements = append(
announcements,
UsedSpaceAnnouncementFromGRPCMessage(msgAnnouncements[i]),
)
}
r.SetAnnouncements(announcements)
return r
}
func AnnounceUsedSpaceRequestToGRPCMessage(r *AnnounceUsedSpaceRequest) *container.AnnounceUsedSpaceRequest {
if r == nil {
return nil
}
m := new(container.AnnounceUsedSpaceRequest)
m.SetBody(
AnnounceUsedSpaceRequestBodyToGRPCMessage(r.GetBody()),
)
session.RequestHeadersToGRPC(r, m)
return m
}
func AnnounceUsedSpaceRequestFromGRPCMessage(m *container.AnnounceUsedSpaceRequest) *AnnounceUsedSpaceRequest {
if m == nil {
return nil
}
r := new(AnnounceUsedSpaceRequest)
r.SetBody(
AnnounceUsedSpaceRequestBodyFromGRPCMessage(m.GetBody()),
)
session.RequestHeadersFromGRPC(m, r)
return r
}
func AnnounceUsedSpaceResponseBodyToGRPCMessage(r *AnnounceUsedSpaceResponseBody) *container.AnnounceUsedSpaceResponse_Body {
if r == nil {
return nil
}
m := new(container.AnnounceUsedSpaceResponse_Body)
return m
}
func AnnounceUsedSpaceResponseBodyFromGRPCMessage(m *container.AnnounceUsedSpaceResponse_Body) *AnnounceUsedSpaceResponseBody {
if m == nil {
return nil
}
r := new(AnnounceUsedSpaceResponseBody)
return r
}
func AnnounceUsedSpaceResponseToGRPCMessage(r *AnnounceUsedSpaceResponse) *container.AnnounceUsedSpaceResponse {
if r == nil {
return nil
}
m := new(container.AnnounceUsedSpaceResponse)
m.SetBody(
AnnounceUsedSpaceResponseBodyToGRPCMessage(r.GetBody()),
)
session.ResponseHeadersToGRPC(r, m)
return m
}
func AnnounceUsedSpaceResponseFromGRPCMessage(m *container.AnnounceUsedSpaceResponse) *AnnounceUsedSpaceResponse {
if m == nil {
return nil
}
r := new(AnnounceUsedSpaceResponse)
r.SetBody(
AnnounceUsedSpaceResponseBodyFromGRPCMessage(m.GetBody()),
)
session.ResponseHeadersFromGRPC(m, r)
return r
}

View file

@ -73,6 +73,10 @@ func (c *Client) GetExtendedACL(ctx context.Context, req *GetExtendedACLRequest)
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 {

View file

@ -353,3 +353,66 @@ func (m *GetExtendedACLResponse) SetVerifyHeader(v *session.ResponseVerification
m.VerifyHeader = v
}
}
// SetContainerId sets identifier of the container.
func (m *AnnounceUsedSpaceRequest_Body_Announcement) SetContainerId(v *refs.ContainerID) {
if m != nil {
m.ContainerId = v
}
}
// SetUsedSpace sets used space value of the container.
func (m *AnnounceUsedSpaceRequest_Body_Announcement) SetUsedSpace(v uint64) {
if m != nil {
m.UsedSpace = v
}
}
// SetAnnouncements sets list of announcement for shared containers between nodes.
func (m *AnnounceUsedSpaceRequest_Body) SetAnnouncements(v []*AnnounceUsedSpaceRequest_Body_Announcement) {
if m != nil {
m.Announcements = v
}
}
// SetBody sets body of the request.
func (m *AnnounceUsedSpaceRequest) SetBody(v *AnnounceUsedSpaceRequest_Body) {
if m != nil {
m.Body = v
}
}
// SetMetaHeader sets meta header of the request.
func (m *AnnounceUsedSpaceRequest) SetMetaHeader(v *session.RequestMetaHeader) {
if m != nil {
m.MetaHeader = v
}
}
// SetVerifyHeader sets verification header of the request.
func (m *AnnounceUsedSpaceRequest) SetVerifyHeader(v *session.RequestVerificationHeader) {
if m != nil {
m.VerifyHeader = v
}
}
// SetBody sets body of the response.
func (m *AnnounceUsedSpaceResponse) SetBody(v *AnnounceUsedSpaceResponse_Body) {
if m != nil {
m.Body = v
}
}
// SetMetaHeader sets meta header of the response.
func (m *AnnounceUsedSpaceResponse) SetMetaHeader(v *session.ResponseMetaHeader) {
if m != nil {
m.MetaHeader = v
}
}
// SetVerifyHeader sets verification header of the response.
func (m *AnnounceUsedSpaceResponse) SetVerifyHeader(v *session.ResponseVerificationHeader) {
if m != nil {
m.VerifyHeader = v
}
}

Binary file not shown.

View file

@ -40,6 +40,11 @@ const (
getEACLRespBodyTableField = 1
getEACLRespBodySignatureField = 2
usedSpaceAnnounceCIDField = 1
usedSpaceAnnounceUsedSpaceField = 2
usedSpaceReqBodyAnnouncementsField = 1
)
func (a *Attribute) StableMarshal(buf []byte) ([]byte, error) {
@ -534,3 +539,89 @@ func (r *GetExtendedACLResponseBody) StableSize() (size int) {
return size
}
func (a *UsedSpaceAnnouncement) StableMarshal(buf []byte) ([]byte, error) {
if a == nil {
return []byte{}, nil
}
if buf == nil {
buf = make([]byte, a.StableSize())
}
var (
offset, n int
err error
)
n, err = protoutil.NestedStructureMarshal(usedSpaceAnnounceCIDField, buf[offset:], a.cid)
if err != nil {
return nil, err
}
offset += n
_, err = protoutil.UInt64Marshal(usedSpaceAnnounceUsedSpaceField, buf[offset:], a.usedSpace)
if err != nil {
return nil, err
}
return buf, nil
}
func (a *UsedSpaceAnnouncement) StableSize() (size int) {
if a == nil {
return 0
}
size += protoutil.NestedStructureSize(usedSpaceAnnounceCIDField, a.cid)
size += protoutil.UInt64Size(usedSpaceAnnounceUsedSpaceField, a.usedSpace)
return size
}
func (r *AnnounceUsedSpaceRequestBody) StableMarshal(buf []byte) ([]byte, error) {
if r == nil {
return []byte{}, nil
}
if buf == nil {
buf = make([]byte, r.StableSize())
}
var (
offset, n int
err error
)
for i := range r.announcements {
n, err = protoutil.NestedStructureMarshal(usedSpaceReqBodyAnnouncementsField, buf[offset:], r.announcements[i])
if err != nil {
return nil, err
}
offset += n
}
return buf, nil
}
func (r *AnnounceUsedSpaceRequestBody) StableSize() (size int) {
if r == nil {
return 0
}
for i := range r.announcements {
size += protoutil.NestedStructureSize(usedSpaceReqBodyAnnouncementsField, r.announcements[i])
}
return size
}
func (r *AnnounceUsedSpaceResponseBody) StableMarshal(buf []byte) ([]byte, error) {
return nil, nil
}
func (r *AnnounceUsedSpaceResponseBody) StableSize() (size int) {
return 0
}

View file

@ -1,7 +1,9 @@
package container_test
import (
"crypto/sha256"
"fmt"
"math/rand"
"testing"
"github.com/nspcc-dev/neofs-api-go/v2/acl"
@ -232,6 +234,38 @@ func TestGetEACLResponseBody_StableMarshal(t *testing.T) {
})
}
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)
@ -408,3 +442,28 @@ func generateGetEACLResponseBody(n int, k, v string) *container.GetExtendedACLRe
return resp
}
func generateAnnounceRequestBody(n int) *container.AnnounceUsedSpaceRequestBody {
resp := new(container.AnnounceUsedSpaceRequestBody)
buf := make([]byte, sha256.Size)
announcements := make([]*container.UsedSpaceAnnouncement, 0, n)
for i := 0; i < n; i++ {
rand.Read(buf)
cid := new(refs.ContainerID)
cid.SetValue(buf)
a := new(container.UsedSpaceAnnouncement)
a.SetContainerID(cid)
a.SetUsedSpace(rand.Uint64())
}
resp.SetAnnouncements(announcements)
return resp
}
func generateAnnounceResponseBody() *container.AnnounceUsedSpaceResponseBody {
return new(container.AnnounceUsedSpaceResponseBody)
}

View file

@ -13,6 +13,7 @@ type Service interface {
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 {
@ -94,3 +95,19 @@ type GetExtendedACLResponse struct {
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

@ -29,6 +29,7 @@ type testGRPCServer struct {
listResp *container.ListResponse
sEaclResp *container.SetExtendedACLResponse
gEaclResp *container.GetExtendedACLResponse
announceResp *container.AnnounceUsedSpaceResponse
err error
}
@ -56,6 +57,10 @@ func (s *testGRPCClient) GetExtendedACL(ctx context.Context, in *containerGRPC.G
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
@ -176,6 +181,26 @@ func (s *testGRPCServer) GetExtendedACL(_ context.Context, req *containerGRPC.Ge
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)
@ -385,6 +410,50 @@ func testGetEACLResponse() *container.GetExtendedACLResponse {
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.SetUsedSpace(10)
a1.SetContainerID(cid1)
a2 := new(container.UsedSpaceAnnouncement)
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()
@ -814,3 +883,74 @@ func TestGRPCClient_GetEACL(t *testing.T) {
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

@ -93,6 +93,18 @@ type GetExtendedACLResponseBody struct {
sig *refs.Signature
}
type UsedSpaceAnnouncement struct {
cid *refs.ContainerID
usedSpace uint64
}
type AnnounceUsedSpaceRequestBody struct {
announcements []*UsedSpaceAnnouncement
}
type AnnounceUsedSpaceResponseBody struct{}
func (a *Attribute) GetKey() string {
if a != nil {
return a.key
@ -904,3 +916,129 @@ func (r *GetExtendedACLResponse) SetVerificationHeader(v *session.ResponseVerifi
r.verifyHeader = v
}
}
func (a *UsedSpaceAnnouncement) GetUsedSpace() uint64 {
if a != nil {
return a.usedSpace
}
return 0
}
func (a *UsedSpaceAnnouncement) SetUsedSpace(v uint64) {
if a != nil {
a.usedSpace = v
}
}
func (a *UsedSpaceAnnouncement) GetContainerID() *refs.ContainerID {
if a != nil {
return a.cid
}
return nil
}
func (a *UsedSpaceAnnouncement) SetContainerID(v *refs.ContainerID) {
if a != nil {
a.cid = v
}
}
func (r *AnnounceUsedSpaceRequestBody) GetAnnouncements() []*UsedSpaceAnnouncement {
if r != nil {
return r.announcements
}
return nil
}
func (r *AnnounceUsedSpaceRequestBody) SetAnnouncements(v []*UsedSpaceAnnouncement) {
if r != nil {
r.announcements = v
}
}
func (r *AnnounceUsedSpaceRequest) GetBody() *AnnounceUsedSpaceRequestBody {
if r != nil {
return r.body
}
return nil
}
func (r *AnnounceUsedSpaceRequest) SetBody(v *AnnounceUsedSpaceRequestBody) {
if r != nil {
r.body = v
}
}
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 {
if r != nil {
return r.body
}
return nil
}
func (r *AnnounceUsedSpaceResponse) SetBody(v *AnnounceUsedSpaceResponseBody) {
if r != nil {
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

@ -330,6 +330,10 @@ func serviceMessageBody(req interface{}) stableMarshaler {
return v.GetBody()
case *container.GetExtendedACLResponse:
return v.GetBody()
case *container.AnnounceUsedSpaceRequest:
return v.GetBody()
case *container.AnnounceUsedSpaceResponse:
return v.GetBody()
/* Object */
case *object.PutRequest: