diff --git a/pkg/services/object/head/distributed.go b/pkg/services/object/head/distributed.go index 6ca3b5905f..da5f6b9fbb 100644 --- a/pkg/services/object/head/distributed.go +++ b/pkg/services/object/head/distributed.go @@ -5,7 +5,6 @@ import ( "sync" "github.com/nspcc-dev/neofs-node/pkg/core/netmap" - "github.com/nspcc-dev/neofs-node/pkg/core/object" "github.com/nspcc-dev/neofs-node/pkg/network" "github.com/nspcc-dev/neofs-node/pkg/services/object/util" "github.com/nspcc-dev/neofs-node/pkg/services/object_manager/placement" @@ -105,25 +104,24 @@ loop: if err := h.workerPool.Submit(func() { defer wg.Done() - var header interface { - head(context.Context, *Prm, func(*object.Object)) error - } - if network.IsLocalAddress(h.localAddrSrc, addr) { - header = &localHeader{ - storage: h.localStore, - } - } else { - header = &remoteHeader{ - keyStorage: h.keyStorage, - node: addr, + if err := h.localHeader.head(ctx, prm, h.w.write); err != nil { + // TODO: log error } + + return } - if err := header.head(ctx, prm, h.w.write); err != nil { + head, err := h.remoteHeader.Head(ctx, &RemoteHeadPrm{ + commonHeadPrm: prm, + node: addr, + }) + if err != nil { // TODO: log error return } + + h.w.write(head) }); err != nil { wg.Done() // TODO: log error diff --git a/pkg/services/object/head/remote.go b/pkg/services/object/head/remote.go index 324e7b887e..67343f0f06 100644 --- a/pkg/services/object/head/remote.go +++ b/pkg/services/object/head/remote.go @@ -4,53 +4,85 @@ import ( "context" "github.com/nspcc-dev/neofs-api-go/pkg/client" + objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object" "github.com/nspcc-dev/neofs-node/pkg/core/object" "github.com/nspcc-dev/neofs-node/pkg/network" "github.com/nspcc-dev/neofs-node/pkg/services/object/util" "github.com/pkg/errors" ) -type remoteHeader struct { +// RemoteHeader represents utility for getting +// the object header from a remote host. +type RemoteHeader struct { keyStorage *util.KeyStorage +} + +// RemoteHeadPrm groups remote header operation parameters. +type RemoteHeadPrm struct { + commonHeadPrm *Prm node *network.Address } -func (h *remoteHeader) head(ctx context.Context, prm *Prm, handler func(*object.Object)) error { - key, err := h.keyStorage.GetKey(prm.common.SessionToken()) - if err != nil { - return errors.Wrapf(err, "(%T) could not receive private key", h) +// NewRemoteHeader creates, initializes and returns new RemoteHeader instance. +func NewRemoteHeader(keyStorage *util.KeyStorage) *RemoteHeader { + return &RemoteHeader{ + keyStorage: keyStorage, + } +} + +// WithNodeAddress sets network address of the remote node. +func (p *RemoteHeadPrm) WithNodeAddress(v *network.Address) *RemoteHeadPrm { + if p != nil { + p.node = v } - addr, err := h.node.IPAddrString() + return p +} + +// WithObjectAddress sets object address. +func (p *RemoteHeadPrm) WithObjectAddress(v *objectSDK.Address) *RemoteHeadPrm { + if p != nil { + p.commonHeadPrm = new(Prm).WithAddress(v) + } + + return p +} + +// Head requests object header from the remote node. +func (h *RemoteHeader) Head(ctx context.Context, prm *RemoteHeadPrm) (*object.Object, error) { + key, err := h.keyStorage.GetKey(prm.commonHeadPrm.common.SessionToken()) if err != nil { - return err + return nil, errors.Wrapf(err, "(%T) could not receive private key", h) + } + + addr, err := prm.node.IPAddrString() + if err != nil { + return nil, err } c, err := client.New(key, client.WithAddress(addr), ) if err != nil { - return errors.Wrapf(err, "(%T) could not create SDK client %s", h, addr) + return nil, errors.Wrapf(err, "(%T) could not create SDK client %s", h, addr) } p := new(client.ObjectHeaderParams). - WithAddress(prm.addr) + WithAddress(prm.commonHeadPrm.addr) - if prm.short { + if prm.commonHeadPrm.short { p = p.WithMainFields() } hdr, err := c.GetObjectHeader(ctx, p, client.WithTTL(1), // FIXME: use constant - client.WithSession(prm.common.SessionToken()), - client.WithBearer(prm.common.BearerToken()), + client.WithSession(prm.commonHeadPrm.common.SessionToken()), + client.WithBearer(prm.commonHeadPrm.common.BearerToken()), ) if err != nil { - return errors.Wrapf(err, "(%T) could not head object in %s", h, addr) + return nil, errors.Wrapf(err, "(%T) could not head object in %s", h, addr) } - handler(object.NewFromSDK(hdr)) - - return nil + return object.NewFromSDK(hdr), nil } diff --git a/pkg/services/object/head/service.go b/pkg/services/object/head/service.go index 535b25dcbf..4b658cef86 100644 --- a/pkg/services/object/head/service.go +++ b/pkg/services/object/head/service.go @@ -24,10 +24,6 @@ type Service struct { type Option func(*cfg) type cfg struct { - keyStorage *objutil.KeyStorage - - localStore *localstore.Storage - cnrSrc container.Source netMapSrc netmap.Source @@ -37,6 +33,10 @@ type cfg struct { localAddrSrc network.LocalAddressSource rightChildSearcher RelationSearcher + + localHeader localHeader + + remoteHeader RemoteHeader } var ErrNotFound = errors.New("object header not found") @@ -95,13 +95,13 @@ func (s *Service) Head(ctx context.Context, prm *Prm) (*Response, error) { func WithKeyStorage(v *objutil.KeyStorage) Option { return func(c *cfg) { - c.keyStorage = v + c.remoteHeader.keyStorage = v } } func WithLocalStorage(v *localstore.Storage) Option { return func(c *cfg) { - c.localStore = v + c.localHeader.storage = v } }