forked from TrueCloudLab/frostfs-api-go
[#226] sdk/client: Add tombstone address to the return of DeleteObject
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
4567986682
commit
803c91b3eb
2 changed files with 73 additions and 10 deletions
|
@ -25,8 +25,20 @@ type PutObjectParams struct {
|
||||||
r io.Reader
|
r io.Reader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ObjectAddressWriter is an interface of the
|
||||||
|
// component that writes the object address.
|
||||||
|
type ObjectAddressWriter interface {
|
||||||
|
SetAddress(*object.Address)
|
||||||
|
}
|
||||||
|
|
||||||
|
type objectAddressWriter struct {
|
||||||
|
addr *object.Address
|
||||||
|
}
|
||||||
|
|
||||||
type DeleteObjectParams struct {
|
type DeleteObjectParams struct {
|
||||||
addr *object.Address
|
addr *object.Address
|
||||||
|
|
||||||
|
tombTgt ObjectAddressWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetObjectParams struct {
|
type GetObjectParams struct {
|
||||||
|
@ -97,6 +109,10 @@ const searchQueryVersion uint32 = 1
|
||||||
|
|
||||||
var errNilObjectPart = errors.New("received nil object part")
|
var errNilObjectPart = errors.New("received nil object part")
|
||||||
|
|
||||||
|
func (w objectAddressWriter) SetAddress(addr *object.Address) {
|
||||||
|
w.addr = addr
|
||||||
|
}
|
||||||
|
|
||||||
func rangesToV2(rs []*object.Range) []*v2object.Range {
|
func rangesToV2(rs []*object.Range) []*v2object.Range {
|
||||||
r2 := make([]*v2object.Range, 0, len(rs))
|
r2 := make([]*v2object.Range, 0, len(rs))
|
||||||
|
|
||||||
|
@ -295,21 +311,68 @@ func (p *DeleteObjectParams) Address() *object.Address {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithTombstoneAddressTarget sets target component to write tombstone address.
|
||||||
|
func (p *DeleteObjectParams) WithTombstoneAddressTarget(v ObjectAddressWriter) *DeleteObjectParams {
|
||||||
|
if p != nil {
|
||||||
|
p.tombTgt = v
|
||||||
|
}
|
||||||
|
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// TombstoneAddressTarget returns target component to write tombstone address.
|
||||||
|
func (p *DeleteObjectParams) TombstoneAddressTarget() ObjectAddressWriter {
|
||||||
|
if p != nil {
|
||||||
|
return p.tombTgt
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteObject is a wrapper over Client.DeleteObject method
|
||||||
|
// that provides the ability to receive tombstone address
|
||||||
|
// without setting a target in the parameters.
|
||||||
|
func DeleteObject(c *Client, ctx context.Context, p *DeleteObjectParams, opts ...CallOption) (*object.Address, error) {
|
||||||
|
w := new(objectAddressWriter)
|
||||||
|
|
||||||
|
err := c.DeleteObject(ctx, p.WithTombstoneAddressTarget(w), opts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return w.addr, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteObject removes object by address.
|
||||||
|
//
|
||||||
|
// If target of tombstone address is not set, the address is ignored.
|
||||||
func (c *Client) DeleteObject(ctx context.Context, p *DeleteObjectParams, opts ...CallOption) error {
|
func (c *Client) DeleteObject(ctx context.Context, p *DeleteObjectParams, opts ...CallOption) error {
|
||||||
// check remote node version
|
// check remote node version
|
||||||
switch c.remoteNode.Version.Major() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
case 2:
|
||||||
return c.deleteObjectV2(ctx, p, opts...)
|
if p.tombTgt == nil {
|
||||||
|
p.tombTgt = new(objectAddressWriter)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := c.deleteObjectV2(ctx, p, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
addrV2 := resp.GetBody().GetTombstone()
|
||||||
|
p.tombTgt.SetAddress(object.NewAddressFromV2(addrV2))
|
||||||
|
|
||||||
|
return nil
|
||||||
default:
|
default:
|
||||||
return errUnsupportedProtocol
|
return errUnsupportedProtocol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) deleteObjectV2(ctx context.Context, p *DeleteObjectParams, opts ...CallOption) error {
|
func (c *Client) deleteObjectV2(ctx context.Context, p *DeleteObjectParams, opts ...CallOption) (*v2object.DeleteResponse, error) {
|
||||||
// create V2 Object client
|
// create V2 Object client
|
||||||
cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts)
|
cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "could not create Object V2 client")
|
return nil, errors.Wrap(err, "could not create Object V2 client")
|
||||||
}
|
}
|
||||||
|
|
||||||
callOpts := c.defaultCallOptions()
|
callOpts := c.defaultCallOptions()
|
||||||
|
@ -333,7 +396,7 @@ func (c *Client) deleteObjectV2(ctx context.Context, p *DeleteObjectParams, opts
|
||||||
addr: p.addr.ToV2(),
|
addr: p.addr.ToV2(),
|
||||||
verb: v2session.ObjectVerbDelete,
|
verb: v2session.ObjectVerbDelete,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return errors.Wrap(err, "could not sign session token")
|
return nil, errors.Wrap(err, "could not sign session token")
|
||||||
}
|
}
|
||||||
|
|
||||||
req.SetMetaHeader(meta)
|
req.SetMetaHeader(meta)
|
||||||
|
@ -343,21 +406,21 @@ func (c *Client) deleteObjectV2(ctx context.Context, p *DeleteObjectParams, opts
|
||||||
|
|
||||||
// sign the request
|
// sign the request
|
||||||
if err := signature.SignServiceMessage(c.key, req); err != nil {
|
if err := signature.SignServiceMessage(c.key, req); err != nil {
|
||||||
return errors.Wrapf(err, "could not sign %T", req)
|
return nil, errors.Wrapf(err, "could not sign %T", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// send request
|
// send request
|
||||||
resp, err := cli.Delete(ctx, req)
|
resp, err := cli.Delete(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "could not send %T", req)
|
return nil, errors.Wrapf(err, "could not send %T", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify response structure
|
// verify response structure
|
||||||
if err := signature.VerifyServiceMessage(resp); err != nil {
|
if err := signature.VerifyServiceMessage(resp); err != nil {
|
||||||
return errors.Wrapf(err, "could not verify %T", resp)
|
return nil, errors.Wrapf(err, "could not verify %T", resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GetObjectParams) WithAddress(v *object.Address) *GetObjectParams {
|
func (p *GetObjectParams) WithAddress(v *object.Address) *GetObjectParams {
|
||||||
|
|
|
@ -44,7 +44,7 @@ func (t *Tombstone) SetSplitID(v *SplitID) {
|
||||||
SetSplitID(v.ToV2())
|
SetSplitID(v.ToV2())
|
||||||
}
|
}
|
||||||
|
|
||||||
// SplitID returns identifier of object split hierarchy.
|
// Members returns list of objects to be deleted.
|
||||||
func (t *Tombstone) Members() []*ID {
|
func (t *Tombstone) Members() []*ID {
|
||||||
msV2 := (*tombstone.Tombstone)(t).
|
msV2 := (*tombstone.Tombstone)(t).
|
||||||
GetMembers()
|
GetMembers()
|
||||||
|
@ -62,7 +62,7 @@ func (t *Tombstone) Members() []*ID {
|
||||||
return ms
|
return ms
|
||||||
}
|
}
|
||||||
|
|
||||||
// SplitID returns identifier of object split hierarchy.
|
// SetMembers sets list of objects to be deleted.
|
||||||
func (t *Tombstone) SetMembers(v []*ID) {
|
func (t *Tombstone) SetMembers(v []*ID) {
|
||||||
var ms []*refs.ObjectID
|
var ms []*refs.ObjectID
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue