frostfs-node/pkg/services/object/util/prm.go

219 lines
4 KiB
Go
Raw Normal View History

package util
import (
"crypto/ecdsa"
"strconv"
"github.com/nspcc-dev/neofs-api-go/pkg"
"github.com/nspcc-dev/neofs-api-go/pkg/client"
"github.com/nspcc-dev/neofs-api-go/pkg/token"
"github.com/nspcc-dev/neofs-api-go/v2/session"
)
type CommonPrm struct {
local bool
netmapEpoch, netmapLookupDepth uint64
token *token.SessionToken
bearer *token.BearerToken
key *ecdsa.PrivateKey
callOpts []client.CallOption
}
type remoteCallOpts struct {
opts []client.CallOption
}
type DynamicCallOption func(*remoteCallOpts)
func (p *CommonPrm) WithLocalOnly(v bool) *CommonPrm {
if p != nil {
p.local = v
}
return p
}
func (p *CommonPrm) LocalOnly() bool {
if p != nil {
return p.local
}
return false
}
func (p *CommonPrm) WithSessionToken(token *token.SessionToken) *CommonPrm {
if p != nil {
p.token = token
}
return p
}
func (p *CommonPrm) WithBearerToken(token *token.BearerToken) *CommonPrm {
if p != nil {
p.bearer = token
}
return p
}
// WithPrivateKey sets private key to use during execution.
func (p *CommonPrm) WithPrivateKey(key *ecdsa.PrivateKey) *CommonPrm {
if p != nil {
p.key = key
}
return p
}
// PrivateKey returns private key to use during execution.
func (p *CommonPrm) PrivateKey() *ecdsa.PrivateKey {
if p != nil {
return p.key
}
return nil
}
// WithRemoteCallOptions sets call options remote remote client calls.
func (p *CommonPrm) WithRemoteCallOptions(opts ...client.CallOption) *CommonPrm {
if p != nil {
p.callOpts = opts
}
return p
}
// RemoteCallOptions return call options for remote client calls.
func (p *CommonPrm) RemoteCallOptions(dynamic ...DynamicCallOption) []client.CallOption {
if p != nil {
o := &remoteCallOpts{
opts: p.callOpts,
}
for _, applier := range dynamic {
applier(o)
}
return o.opts
}
return nil
}
func WithNetmapEpoch(v uint64) DynamicCallOption {
return func(o *remoteCallOpts) {
xHdr := pkg.NewXHeader()
xHdr.SetKey(session.XHeaderNetmapEpoch)
xHdr.SetValue(strconv.FormatUint(v, 10))
o.opts = append(o.opts, client.WithXHeader(xHdr))
}
}
// WithKey sets key to use for the request.
func WithKey(key *ecdsa.PrivateKey) DynamicCallOption {
return func(o *remoteCallOpts) {
o.opts = append(o.opts, client.WithKey(key))
}
}
func (p *CommonPrm) SessionToken() *token.SessionToken {
if p != nil {
return p.token
}
return nil
}
func (p *CommonPrm) BearerToken() *token.BearerToken {
if p != nil {
return p.bearer
}
return nil
}
func (p *CommonPrm) NetmapEpoch() uint64 {
if p != nil {
return p.netmapEpoch
}
return 0
}
func (p *CommonPrm) NetmapLookupDepth() uint64 {
if p != nil {
return p.netmapLookupDepth
}
return 0
}
func (p *CommonPrm) SetNetmapLookupDepth(v uint64) {
if p != nil {
p.netmapLookupDepth = v
}
}
func CommonPrmFromV2(req interface {
GetMetaHeader() *session.RequestMetaHeader
}) (*CommonPrm, error) {
meta := req.GetMetaHeader()
xHdrs := meta.GetXHeaders()
const staticOptNum = 3
prm := &CommonPrm{
local: meta.GetTTL() <= 1, // FIXME: use constant
token: nil,
bearer: nil,
callOpts: make([]client.CallOption, 0, staticOptNum+len(xHdrs)),
}
prm.callOpts = append(prm.callOpts, client.WithTTL(meta.GetTTL()-1))
if tok := meta.GetSessionToken(); tok != nil {
prm.token = token.NewSessionTokenFromV2(tok)
prm.callOpts = append(prm.callOpts, client.WithSession(prm.token))
}
if tok := meta.GetBearerToken(); tok != nil {
prm.bearer = token.NewBearerTokenFromV2(tok)
prm.callOpts = append(prm.callOpts, client.WithBearer(prm.bearer))
}
for i := range xHdrs {
switch xHdrs[i].GetKey() {
case session.XHeaderNetmapEpoch:
var err error
prm.netmapEpoch, err = strconv.ParseUint(xHdrs[i].GetValue(), 10, 64)
if err != nil {
return nil, err
}
case session.XHeaderNetmapLookupDepth:
var err error
prm.netmapLookupDepth, err = strconv.ParseUint(xHdrs[i].GetValue(), 10, 64)
if err != nil {
return nil, err
}
default:
prm.callOpts = append(prm.callOpts,
client.WithXHeader(
pkg.NewXHeaderFromV2(xHdrs[i]),
),
)
}
}
return prm, nil
}