From f251645def39a09ddb0273a607bb1ed0801bfbb0 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Thu, 1 Oct 2020 13:54:18 +0300 Subject: [PATCH] [#58] object/delete: Process linking object in Delete service Signed-off-by: Leonard Lyubich --- pkg/services/object/delete/service.go | 34 ++++++++++++++++++++-- pkg/services/object/head/relation.go | 40 ++++++++++++++++++++++++++ pkg/services/object/search/relation.go | 9 ++++++ 3 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 pkg/services/object/head/relation.go diff --git a/pkg/services/object/delete/service.go b/pkg/services/object/delete/service.go index 593c51677..97ffa9a8d 100644 --- a/pkg/services/object/delete/service.go +++ b/pkg/services/object/delete/service.go @@ -3,7 +3,9 @@ package deletesvc import ( "context" + objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object" "github.com/nspcc-dev/neofs-api-go/pkg/owner" + "github.com/nspcc-dev/neofs-node/pkg/core/object" headsvc "github.com/nspcc-dev/neofs-node/pkg/services/object/head" putsvc "github.com/nspcc-dev/neofs-node/pkg/services/object/put" objutil "github.com/nspcc-dev/neofs-node/pkg/services/object/util" @@ -16,6 +18,10 @@ type Service struct { type Option func(*cfg) +type RelationHeader interface { + HeadRelation(context.Context, *objectSDK.Address) (*object.Object, error) +} + type cfg struct { ownerID *owner.ID @@ -24,6 +30,8 @@ type cfg struct { putSvc *putsvc.Service headSvc *headsvc.Service + + hdrLinking RelationHeader } func defaultCfg() *cfg { @@ -60,8 +68,24 @@ func (s *Service) Delete(ctx context.Context, prm *Prm) (*Response, error) { commonPrm: prm.common, } - if err := s.deleteAll(tool); err != nil { - return nil, errors.Wrapf(err, "(%T) could not delete all objcet relations", s) + if linking, err := s.hdrLinking.HeadRelation(ctx, prm.addr); err != nil { + if err := s.deleteAll(tool); err != nil { + return nil, errors.Wrapf(err, "(%T) could not delete all object relations", s) + } + } else { + if err := tool.delete(prm.addr.GetObjectID()); err != nil { + return nil, errors.Wrapf(err, "(%T) could not delete object", s) + } + + for _, child := range linking.GetChildren() { + if err := tool.delete(child); err != nil { + return nil, errors.Wrapf(err, "(%T) could not delete child object", s) + } + } + + if err := tool.delete(linking.GetID()); err != nil { + return nil, errors.Wrapf(err, "(%T) could not delete linking object", s) + } } return new(Response), nil @@ -124,3 +148,9 @@ func WitHeadService(v *headsvc.Service) Option { c.headSvc = v } } + +func WithLinkingHeader(v RelationHeader) Option { + return func(c *cfg) { + c.hdrLinking = v + } +} diff --git a/pkg/services/object/head/relation.go b/pkg/services/object/head/relation.go new file mode 100644 index 000000000..276d3c1f4 --- /dev/null +++ b/pkg/services/object/head/relation.go @@ -0,0 +1,40 @@ +package headsvc + +import ( + "context" + + objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object" + "github.com/nspcc-dev/neofs-node/pkg/core/object" + "github.com/pkg/errors" +) + +type RelationHeader struct { + srch RelationSearcher + + svc *Service +} + +func NewRelationHeader(srch RelationSearcher, svc *Service) *RelationHeader { + return &RelationHeader{ + srch: srch, + svc: svc, + } +} + +func (h *RelationHeader) HeadRelation(ctx context.Context, addr *objectSDK.Address) (*object.Object, error) { + id, err := h.srch.SearchRelation(ctx, addr) + if err != nil { + return nil, errors.Wrapf(err, "(%T) could not find relation", h) + } + + a := objectSDK.NewAddress() + a.SetContainerID(addr.GetContainerID()) + a.SetObjectID(id) + + r, err := h.svc.Head(ctx, new(Prm).WithAddress(a)) + if err != nil { + return nil, errors.Wrapf(err, "(%T) could not receive relation header", h) + } + + return r.Header(), nil +} diff --git a/pkg/services/object/search/relation.go b/pkg/services/object/search/relation.go index 99da04c26..c6eeec5a3 100644 --- a/pkg/services/object/search/relation.go +++ b/pkg/services/object/search/relation.go @@ -62,3 +62,12 @@ func NewRightChildSearcher(svc *Service) *RelationSearcher { }, } } + +func NewLinkingSearcher(svc *Service) *RelationSearcher { + return &RelationSearcher{ + svc: svc, + queryGenerator: func(addr *object.Address) query.Query { + return queryV1.NewLinkingQuery(addr.GetObjectID()) + }, + } +}