frostfs-sdk-go/client/opts.go
Pavel Karpy 2a6fe47e5e [#114] client: Add WithNeoFSErrorParsing option
This option make client parse all NeoFS error statuses and return them as
errors from method calls (not as part of result structure). This is done
for applications that want to handle errors as it is customary in golang.
Default behaviour (construction client without new option) has not been
changed.

Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
2022-01-13 15:37:43 +03:00

212 lines
4.9 KiB
Go

package client
import (
"crypto/ecdsa"
"crypto/tls"
"time"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
v2session "github.com/nspcc-dev/neofs-api-go/v2/session"
"github.com/nspcc-dev/neofs-sdk-go/session"
"github.com/nspcc-dev/neofs-sdk-go/token"
"github.com/nspcc-dev/neofs-sdk-go/version"
"google.golang.org/grpc"
)
type (
CallOption func(*callOptions)
Option func(*clientOptions)
callOptions struct {
version *version.Version
xHeaders []*session.XHeader
ttl uint32
epoch uint64
key *ecdsa.PrivateKey
session *session.Token
bearer *token.BearerToken
}
clientOptions struct {
key *ecdsa.PrivateKey
rawOpts []client.Option
cbRespInfo func(ResponseMetaInfo) error
// defines if client parses erroneous NeoFS
// statuses and returns them as `error`
//
// default is false
parseNeoFSErrors bool
}
v2SessionReqInfo struct {
addr *refs.Address
verb v2session.ObjectSessionVerb
exp, nbf, iat uint64
}
)
func (c *Client) defaultCallOptions() *callOptions {
return &callOptions{
version: version.Current(),
ttl: 2,
key: c.opts.key,
}
}
func WithXHeader(x *session.XHeader) CallOption {
return func(opts *callOptions) {
opts.xHeaders = append(opts.xHeaders, x)
}
}
func WithTTL(ttl uint32) CallOption {
return func(opts *callOptions) {
opts.ttl = ttl
}
}
// WithKey sets client's key for the next request.
func WithKey(key *ecdsa.PrivateKey) CallOption {
return func(opts *callOptions) {
opts.key = key
}
}
func WithEpoch(epoch uint64) CallOption {
return func(opts *callOptions) {
opts.epoch = epoch
}
}
func WithSession(token *session.Token) CallOption {
return func(opts *callOptions) {
opts.session = token
}
}
func WithBearer(token *token.BearerToken) CallOption {
return func(opts *callOptions) {
opts.bearer = token
}
}
func v2MetaHeaderFromOpts(options *callOptions) *v2session.RequestMetaHeader {
meta := new(v2session.RequestMetaHeader)
meta.SetVersion(options.version.ToV2())
meta.SetTTL(options.ttl)
meta.SetEpoch(options.epoch)
xhdrs := make([]*v2session.XHeader, len(options.xHeaders))
for i := range options.xHeaders {
xhdrs[i] = options.xHeaders[i].ToV2()
}
meta.SetXHeaders(xhdrs)
if options.bearer != nil {
meta.SetBearerToken(options.bearer.ToV2())
}
meta.SetSessionToken(options.session.ToV2())
return meta
}
func defaultClientOptions() *clientOptions {
return &clientOptions{
rawOpts: make([]client.Option, 0, 4),
}
}
// WithAddress returns option to specify
// network address of the remote server.
//
// Ignored if WithGRPCConnection is provided.
func WithAddress(addr string) Option {
return func(opts *clientOptions) {
opts.rawOpts = append(opts.rawOpts, client.WithNetworkAddress(addr))
}
}
// WithDialTimeout returns option to set connection timeout to the remote node.
//
// Ignored if WithGRPCConn is provided.
func WithDialTimeout(dur time.Duration) Option {
return func(opts *clientOptions) {
opts.rawOpts = append(opts.rawOpts, client.WithDialTimeout(dur))
}
}
// WithRWTimeout returns option to set timeout for single read and write
// operation on protobuf message.
func WithRWTimeout(dur time.Duration) Option {
return func(opts *clientOptions) {
opts.rawOpts = append(opts.rawOpts, client.WithRWTimeout(dur))
}
}
// WithTLSConfig returns option to set connection's TLS config to the remote node.
//
// Ignored if WithGRPCConnection is provided.
func WithTLSConfig(cfg *tls.Config) Option {
return func(opts *clientOptions) {
opts.rawOpts = append(opts.rawOpts, client.WithTLSCfg(cfg))
}
}
// WithDefaultPrivateKey returns option to set default private key
// used for the work.
func WithDefaultPrivateKey(key *ecdsa.PrivateKey) Option {
return func(opts *clientOptions) {
opts.key = key
}
}
// WithURIAddress returns option to specify
// network address of a remote server and connection
// scheme for it.
//
// Format of the URI:
//
// [scheme://]host:port
//
// Supported schemes:
// - grpc;
// - grpcs.
//
// tls.Cfg second argument is optional and is taken into
// account only in case of `grpcs` scheme.
//
// Falls back to WithNetworkAddress if address is not a valid URI.
//
// Do not use along with WithAddress and WithTLSConfig.
//
// Ignored if WithGRPCConnection is provided.
func WithURIAddress(addr string, tlsCfg *tls.Config) Option {
return func(opts *clientOptions) {
opts.rawOpts = append(opts.rawOpts, client.WithNetworkURIAddress(addr, tlsCfg)...)
}
}
// WithGRPCConnection returns option to set GRPC connection to
// the remote node.
func WithGRPCConnection(grpcConn *grpc.ClientConn) Option {
return func(opts *clientOptions) {
opts.rawOpts = append(opts.rawOpts, client.WithGRPCConn(grpcConn))
}
}
// WithNeoFSErrorParsing returns option that makes client parse
// erroneous NeoFS statuses and return them as `error` of the method
// call.
func WithNeoFSErrorParsing() Option {
return func(opts *clientOptions) {
opts.parseNeoFSErrors = true
}
}