frostfs-node/pkg/services/object/delete/service.go
Leonard Lyubich 0ec8f529ab [#842] object/delete: Set tombstone local node as tombstone owner
All objects in NeoFS must have owner ID. In previous implementation Object
Delete service handler set owner ID from request session token. If removal
was executed w/o a session, object with tombstone was prepared incorrectly.
In order to fix this node should set its own ID and become an owner of the
tombstone object.

Extend `NetworkInfo` interface required by Object.Delete handler with
`LocalNodeID` method which returns `owner.ID` of the local node. Implement
the method on `networkState` component of storage node application which is
updated on each node state change in NeoFS network map. Set owner returned
by `LocalNodeID` call as tombstone object's owner in Delete handler.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2021-11-10 16:18:02 +03:00

113 lines
2.6 KiB
Go

package deletesvc
import (
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/netmap"
getsvc "github.com/nspcc-dev/neofs-node/pkg/services/object/get"
putsvc "github.com/nspcc-dev/neofs-node/pkg/services/object/put"
searchsvc "github.com/nspcc-dev/neofs-node/pkg/services/object/search"
"github.com/nspcc-dev/neofs-node/pkg/util/logger"
"go.uber.org/zap"
)
// Service utility serving requests of Object.Get service.
type Service struct {
*cfg
}
// Option is a Service's constructor option.
type Option func(*cfg)
// NetworkInfo wraps network state and configurations.
type NetworkInfo interface {
netmap.State
// Must return the lifespan of the tombstones
// in the NeoFS epochs.
TombstoneLifetime() (uint64, error)
// Returns user ID of the local storage node. Result must not be nil.
// New tombstone objects will have the result as an owner ID if removal is executed w/o a session.
LocalNodeID() *owner.ID
}
type cfg struct {
log *logger.Logger
header interface {
// must return (nil, nil) for PHY objects
splitInfo(*execCtx) (*objectSDK.SplitInfo, error)
children(*execCtx) ([]*objectSDK.ID, error)
// must return (nil, nil) for 1st object in chain
previous(*execCtx, *objectSDK.ID) (*objectSDK.ID, error)
}
searcher interface {
splitMembers(*execCtx) ([]*objectSDK.ID, error)
}
placer interface {
put(*execCtx, bool) (*objectSDK.ID, error)
}
netInfo NetworkInfo
}
func defaultCfg() *cfg {
return &cfg{
log: zap.L(),
}
}
// New creates, initializes and returns utility serving
// Object.Get service requests.
func New(opts ...Option) *Service {
c := defaultCfg()
for i := range opts {
opts[i](c)
}
return &Service{
cfg: c,
}
}
// WithLogger returns option to specify Delete service's logger.
func WithLogger(l *logger.Logger) Option {
return func(c *cfg) {
c.log = l.With(zap.String("component", "Object.Delete service"))
}
}
// WithHeadService returns option to set Head service
// to work with object headers.
func WithHeadService(h *getsvc.Service) Option {
return func(c *cfg) {
c.header = (*headSvcWrapper)(h)
}
}
// WithSearchService returns option to set search service.
func WithSearchService(s *searchsvc.Service) Option {
return func(c *cfg) {
c.searcher = (*searchSvcWrapper)(s)
}
}
// WithPutService returns option to specify put service.
func WithPutService(p *putsvc.Service) Option {
return func(c *cfg) {
c.placer = (*putSvcWrapper)(p)
}
}
// WithNetworkInfo returns option to set network information source.
func WithNetworkInfo(netInfo NetworkInfo) Option {
return func(c *cfg) {
c.netInfo = netInfo
}
}