From 4225a21ea52320ab4d1130ca52c71c8459454425 Mon Sep 17 00:00:00 2001 From: Angira Kekteeva Date: Tue, 25 May 2021 11:48:01 +0300 Subject: [PATCH 1/4] [#4] *: Add connections, neofs, logger from httpgw Commit in http-gw: a4ad52e181e3653ee43742e2beb8c594c487c8cc Rename connections dir and pkg to pool Signed-off-by: Angira Kekteeva --- pkg/logger/grpc.go | 78 +++++++++++++++++ pkg/logger/option.go | 33 +++++++ pkg/logger/zap.go | 134 +++++++++++++++++++++++++++++ pkg/neofs/client-plant.go | 177 ++++++++++++++++++++++++++++++++++++++ pkg/neofs/credentials.go | 78 +++++++++++++++++ pkg/pool/pool.go | 160 ++++++++++++++++++++++++++++++++++ pkg/pool/sampler.go | 81 +++++++++++++++++ 7 files changed, 741 insertions(+) create mode 100644 pkg/logger/grpc.go create mode 100644 pkg/logger/option.go create mode 100644 pkg/logger/zap.go create mode 100644 pkg/neofs/client-plant.go create mode 100644 pkg/neofs/credentials.go create mode 100644 pkg/pool/pool.go create mode 100644 pkg/pool/sampler.go diff --git a/pkg/logger/grpc.go b/pkg/logger/grpc.go new file mode 100644 index 0000000..584bf25 --- /dev/null +++ b/pkg/logger/grpc.go @@ -0,0 +1,78 @@ +package logger + +import ( + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "google.golang.org/grpc/grpclog" +) + +type ( + zapLogger struct { + zapcore.Core + log *zap.SugaredLogger + } + + // Logger includes grpclog.LoggerV2 interface with an additional + // Println method. + Logger interface { + grpclog.LoggerV2 + Println(v ...interface{}) + } +) + +// GRPC wraps given zap.Logger into grpclog.LoggerV2+ interface. +func GRPC(l *zap.Logger) Logger { + log := l.WithOptions( + // skip gRPCLog + zapLogger in caller + zap.AddCallerSkip(2)) + + return &zapLogger{ + Core: log.Core(), + log: log.Sugar(), + } +} + +// Info implements grpclog.LoggerV2. +func (z *zapLogger) Info(args ...interface{}) { z.log.Info(args...) } + +// Infoln implements grpclog.LoggerV2. +func (z *zapLogger) Infoln(args ...interface{}) { z.log.Info(args...) } + +// Infof implements grpclog.LoggerV2. +func (z *zapLogger) Infof(format string, args ...interface{}) { z.log.Infof(format, args...) } + +// Println allows to print a line with info severity. +func (z *zapLogger) Println(args ...interface{}) { z.log.Info(args...) } + +// Printf implements grpclog.LoggerV2. +func (z *zapLogger) Printf(format string, args ...interface{}) { z.log.Infof(format, args...) } + +// Warning implements grpclog.LoggerV2. +func (z *zapLogger) Warning(args ...interface{}) { z.log.Warn(args...) } + +// Warningln implements grpclog.LoggerV2. +func (z *zapLogger) Warningln(args ...interface{}) { z.log.Warn(args...) } + +// Warningf implements grpclog.LoggerV2. +func (z *zapLogger) Warningf(format string, args ...interface{}) { z.log.Warnf(format, args...) } + +// Error implements grpclog.LoggerV2. +func (z *zapLogger) Error(args ...interface{}) { z.log.Error(args...) } + +// Errorln implements grpclog.LoggerV2. +func (z *zapLogger) Errorln(args ...interface{}) { z.log.Error(args...) } + +// Errorf implements grpclog.LoggerV2. +func (z *zapLogger) Errorf(format string, args ...interface{}) { z.log.Errorf(format, args...) } + +// Fatal implements grpclog.LoggerV2. +func (z *zapLogger) Fatal(args ...interface{}) { z.log.Fatal(args...) } + +// Fatalln implements grpclog.LoggerV2. +func (z *zapLogger) Fatalln(args ...interface{}) { z.log.Fatal(args...) } + +// Fatalf implements grpclog.LoggerV2. +func (z *zapLogger) Fatalf(format string, args ...interface{}) { z.log.Fatalf(format, args...) } + +// V implements grpclog.LoggerV2. +func (z *zapLogger) V(int) bool { return z.Enabled(zapcore.DebugLevel) } diff --git a/pkg/logger/option.go b/pkg/logger/option.go new file mode 100644 index 0000000..f617010 --- /dev/null +++ b/pkg/logger/option.go @@ -0,0 +1,33 @@ +package logger + +import "go.uber.org/zap" + +// WithSamplingInitial returns Option that sets sampling initial parameter. +func WithSamplingInitial(v int) Option { return func(o *options) { o.SamplingInitial = v } } + +// WithSamplingThereafter returns Option that sets sampling thereafter parameter. +func WithSamplingThereafter(v int) Option { return func(o *options) { o.SamplingThereafter = v } } + +// WithFormat returns Option that sets format parameter. +func WithFormat(v string) Option { return func(o *options) { o.Format = v } } + +// WithLevel returns Option that sets Level parameter. +func WithLevel(v string) Option { return func(o *options) { o.Level = v } } + +// WithTraceLevel returns Option that sets trace level parameter. +func WithTraceLevel(v string) Option { return func(o *options) { o.TraceLevel = v } } + +// WithoutDisclaimer returns Option that disables disclaimer. +func WithoutDisclaimer() Option { return func(o *options) { o.NoDisclaimer = true } } + +// WithoutCaller returns Option that disables caller printing. +func WithoutCaller() Option { return func(o *options) { o.NoCaller = true } } + +// WithAppName returns Option that sets application name. +func WithAppName(v string) Option { return func(o *options) { o.AppName = v } } + +// WithAppVersion returns Option that sets application version. +func WithAppVersion(v string) Option { return func(o *options) { o.AppVersion = v } } + +// WithZapOptions returns Option that sets zap logger options. +func WithZapOptions(opts ...zap.Option) Option { return func(o *options) { o.Options = opts } } diff --git a/pkg/logger/zap.go b/pkg/logger/zap.go new file mode 100644 index 0000000..5e9ee62 --- /dev/null +++ b/pkg/logger/zap.go @@ -0,0 +1,134 @@ +package logger + +import ( + "strings" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +type ( + // Option represents logger option setter. + Option func(o *options) + + options struct { + Options []zap.Option + + SamplingInitial int + SamplingThereafter int + + Format string + Level string + TraceLevel string + + NoCaller bool + NoDisclaimer bool + + AppName string + AppVersion string + } +) + +const ( + formatJSON = "json" + formatConsole = "console" + + defaultSamplingInitial = 100 + defaultSamplingThereafter = 100 + + lvlInfo = "info" + lvlWarn = "warn" + lvlDebug = "debug" + lvlError = "error" + lvlFatal = "fatal" + lvlPanic = "panic" +) + +func safeLevel(lvl string) zap.AtomicLevel { + switch strings.ToLower(lvl) { + case lvlDebug: + return zap.NewAtomicLevelAt(zap.DebugLevel) + case lvlWarn: + return zap.NewAtomicLevelAt(zap.WarnLevel) + case lvlError: + return zap.NewAtomicLevelAt(zap.ErrorLevel) + case lvlFatal: + return zap.NewAtomicLevelAt(zap.FatalLevel) + case lvlPanic: + return zap.NewAtomicLevelAt(zap.PanicLevel) + default: + return zap.NewAtomicLevelAt(zap.InfoLevel) + } +} + +func defaults() *options { + return &options{ + SamplingInitial: defaultSamplingInitial, + SamplingThereafter: defaultSamplingThereafter, + + Format: formatConsole, + Level: lvlDebug, + TraceLevel: lvlInfo, + + NoCaller: false, + NoDisclaimer: false, + + AppName: "", + AppVersion: "", + } +} + +// New returns new zap.Logger using all options specified and stdout used +// for output. +func New(opts ...Option) (*zap.Logger, error) { + o := defaults() + c := zap.NewProductionConfig() + + c.OutputPaths = []string{"stdout"} + c.ErrorOutputPaths = []string{"stdout"} + + for _, opt := range opts { + opt(o) + } + + // set sampling + c.Sampling = &zap.SamplingConfig{ + Initial: o.SamplingInitial, + Thereafter: o.SamplingThereafter, + } + + // logger level + c.Level = safeLevel(o.Level) + traceLvl := safeLevel(o.TraceLevel) + + // logger format + switch f := o.Format; strings.ToLower(f) { + case formatConsole: + c.Encoding = formatConsole + default: + c.Encoding = formatJSON + } + + // logger time + c.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder + + if o.NoCaller { + c.EncoderConfig.EncodeCaller = nil + } + + // enable trace only for current log-level + o.Options = append(o.Options, zap.AddStacktrace(traceLvl)) + + l, err := c.Build(o.Options...) + if err != nil { + return nil, err + } + + if o.NoDisclaimer { + return l, nil + } + + return l.With( + zap.String("app_name", o.AppName), + zap.String("app_version", o.AppVersion)), nil +} diff --git a/pkg/neofs/client-plant.go b/pkg/neofs/client-plant.go new file mode 100644 index 0000000..e13f29d --- /dev/null +++ b/pkg/neofs/client-plant.go @@ -0,0 +1,177 @@ +package neofs + +import ( + "context" + "crypto/ecdsa" + "io" + + "github.com/nspcc-dev/neofs-api-go/pkg/client" + "github.com/nspcc-dev/neofs-api-go/pkg/container" + "github.com/nspcc-dev/neofs-api-go/pkg/object" + "github.com/nspcc-dev/neofs-api-go/pkg/owner" + "github.com/nspcc-dev/neofs-api-go/pkg/token" + "github.com/nspcc-dev/neofs-http-gw/connections" +) + +// BaseOptions represents basic NeoFS request options. +type BaseOptions struct { + Client client.Client + SessionToken *token.SessionToken + BearerToken *token.BearerToken +} + +// PutOptions represents NeoFS Put request options. +type PutOptions struct { + BaseOptions + Attributes []*object.Attribute + ContainerID *container.ID + OwnerID *owner.ID + Reader io.Reader +} + +// GetOptions represents NeoFS Get request options. +type GetOptions struct { + BaseOptions + ObjectAddress *object.Address + Writer io.Writer +} + +// SearchOptions represents NeoFS Search request options. +type SearchOptions struct { + BaseOptions + ContainerID *container.ID + Attribute struct { + Key string + Value string + } +} + +// DeleteOptions represents NeoFS Delete request options. +type DeleteOptions struct { + BaseOptions + ObjectAddress *object.Address +} + +// ObjectClient wraps basic NeoFS requests. +type ObjectClient interface { + Put(context.Context, *PutOptions) (*object.Address, error) + Get(context.Context, *GetOptions) (*object.Object, error) + Search(context.Context, *SearchOptions) ([]*object.ID, error) + Delete(context.Context, *DeleteOptions) error +} + +// ClientPlant provides connections to NeoFS nodes from pool and allows to +// get local owner ID. +type ClientPlant interface { + ConnectionArtifacts() (client.Client, *token.SessionToken, error) + Object() ObjectClient + OwnerID() *owner.ID +} + +type neofsObjectClient struct { + key *ecdsa.PrivateKey + pool connections.Pool +} + +type neofsClientPlant struct { + key *ecdsa.PrivateKey + ownerID *owner.ID + pool connections.Pool +} + +// ConnectionArtifacts returns connection from pool. +func (cp *neofsClientPlant) ConnectionArtifacts() (client.Client, *token.SessionToken, error) { + return cp.pool.ConnectionArtifacts() +} + +// Object returns ObjectClient instance from plant. +func (cp *neofsClientPlant) Object() ObjectClient { + return &neofsObjectClient{ + key: cp.key, + pool: cp.pool, + } +} + +// OwnerID returns plant's owner ID. +func (cp *neofsClientPlant) OwnerID() *owner.ID { + return cp.ownerID +} + +// NewClientPlant creates new ClientPlant from given context, pool and credentials. +func NewClientPlant(ctx context.Context, pool connections.Pool, creds Credentials) (ClientPlant, error) { + return &neofsClientPlant{key: creds.PrivateKey(), ownerID: creds.Owner(), pool: pool}, nil +} + +// Put does NeoFS Put request, returning new object address if successful. +func (oc *neofsObjectClient) Put(ctx context.Context, options *PutOptions) (*object.Address, error) { + var ( + err error + objectID *object.ID + ) + address := object.NewAddress() + rawObject := object.NewRaw() + rawObject.SetContainerID(options.ContainerID) + rawObject.SetOwnerID(options.OwnerID) + rawObject.SetAttributes(options.Attributes...) + ops := new(client.PutObjectParams). + WithObject(rawObject.Object()). + WithPayloadReader(options.Reader) + objectID, err = options.Client.PutObject( + ctx, + ops, + client.WithSession(options.SessionToken), + client.WithBearer(options.BearerToken), + ) + if err != nil { + return nil, err + } + address.SetObjectID(objectID) + address.SetContainerID(options.ContainerID) + return address, nil +} + +// Get does NeoFS Get request, returning an object received if successful. +func (oc *neofsObjectClient) Get(ctx context.Context, options *GetOptions) (*object.Object, error) { + var ( + err error + obj *object.Object + ) + ops := new(client.GetObjectParams). + WithAddress(options.ObjectAddress). + WithPayloadWriter(options.Writer) + obj, err = options.Client.GetObject( + ctx, + ops, + client.WithSession(options.SessionToken), + client.WithBearer(options.BearerToken), + ) + return obj, err +} + +// Search does NeoFS Search request, returning object IDs if successful. +func (oc *neofsObjectClient) Search(ctx context.Context, options *SearchOptions) ([]*object.ID, error) { + sfs := object.NewSearchFilters() + sfs.AddRootFilter() + sfs.AddFilter(options.Attribute.Key, options.Attribute.Value, object.MatchStringEqual) + sops := new(client.SearchObjectParams) + sops.WithContainerID(options.ContainerID) + sops.WithSearchFilters(sfs) + return options.Client.SearchObject( + ctx, + sops, + client.WithSession(options.SessionToken), + client.WithBearer(options.BearerToken), + ) +} + +// Delete deletes NeoFS object. +func (oc *neofsObjectClient) Delete(ctx context.Context, options *DeleteOptions) error { + ops := new(client.DeleteObjectParams).WithAddress(options.ObjectAddress) + err := options.Client.DeleteObject( + ctx, + ops, + client.WithSession(options.SessionToken), + client.WithBearer(options.BearerToken), + ) + return err +} diff --git a/pkg/neofs/credentials.go b/pkg/neofs/credentials.go new file mode 100644 index 0000000..c229468 --- /dev/null +++ b/pkg/neofs/credentials.go @@ -0,0 +1,78 @@ +package neofs + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "math/big" + + "github.com/nspcc-dev/neofs-api-go/pkg/owner" + crypto "github.com/nspcc-dev/neofs-crypto" +) + +type ( + // Credentials contains methods that needed to work with NeoFS. + Credentials interface { + Owner() *owner.ID + PublicKey() *ecdsa.PublicKey + PrivateKey() *ecdsa.PrivateKey + } + + credentials struct { + key *ecdsa.PrivateKey + ownerID *owner.ID + } +) + +// NewCredentials creates an instance of Credentials through string +// representation of secret. It allows passing WIF, path, hex-encoded and others. +func NewCredentials(secret string) (Credentials, error) { + key, err := crypto.LoadPrivateKey(secret) + if err != nil { + return nil, err + } + return setFromPrivateKey(key) +} + +// NewEphemeralCredentials creates new private key and Credentials based on that +// key. +func NewEphemeralCredentials() (Credentials, error) { + c := elliptic.P256() + priv, x, y, err := elliptic.GenerateKey(c, rand.Reader) + if err != nil { + return nil, err + } + key := &ecdsa.PrivateKey{ + PublicKey: ecdsa.PublicKey{ + Curve: c, + X: x, + Y: y, + }, + D: new(big.Int).SetBytes(priv), + } + return setFromPrivateKey(key) +} + +// PrivateKey returns ecdsa.PrivateKey. +func (c *credentials) PrivateKey() *ecdsa.PrivateKey { + return c.key +} + +// PublicKey returns ecdsa.PublicKey. +func (c *credentials) PublicKey() *ecdsa.PublicKey { + return &c.key.PublicKey +} + +// Owner returns owner.ID. +func (c *credentials) Owner() *owner.ID { + return c.ownerID +} + +func setFromPrivateKey(key *ecdsa.PrivateKey) (*credentials, error) { + wallet, err := owner.NEO3WalletFromPublicKey(&key.PublicKey) + if err != nil { + return nil, err + } + ownerID := owner.NewIDFromNeo3Wallet(wallet) + return &credentials{key: key, ownerID: ownerID}, nil +} diff --git a/pkg/pool/pool.go b/pkg/pool/pool.go new file mode 100644 index 0000000..3422f75 --- /dev/null +++ b/pkg/pool/pool.go @@ -0,0 +1,160 @@ +package pool + +import ( + "context" + "crypto/ecdsa" + "errors" + "fmt" + "math/rand" + "sync" + "time" + + "github.com/nspcc-dev/neofs-api-go/pkg/client" + "github.com/nspcc-dev/neofs-api-go/pkg/token" + "google.golang.org/grpc" + "google.golang.org/grpc/keepalive" +) + +// PoolBuilderOptions contains options used to build connection pool. +type PoolBuilderOptions struct { + Key *ecdsa.PrivateKey + NodeConnectionTimeout time.Duration + NodeRequestTimeout time.Duration + ClientRebalanceInterval time.Duration + KeepaliveTime time.Duration + KeepaliveTimeout time.Duration + KeepalivePermitWoStream bool + SessionExpirationEpoch uint64 + weights []float64 + connections []*grpc.ClientConn +} + +// PoolBuilder is an interim structure used to collect node addresses/weights and +// build connection pool subsequently. +type PoolBuilder struct { + addresses []string + weights []float64 +} + +// AddNode adds address/weight pair to node PoolBuilder list. +func (pb *PoolBuilder) AddNode(address string, weight float64) *PoolBuilder { + pb.addresses = append(pb.addresses, address) + pb.weights = append(pb.weights, weight) + return pb +} + +// Build creates new pool based on current PoolBuilder state and options. +func (pb *PoolBuilder) Build(ctx context.Context, options *PoolBuilderOptions) (Pool, error) { + if len(pb.addresses) == 0 { + return nil, errors.New("no NeoFS peers configured") + } + totalWeight := 0.0 + for _, w := range pb.weights { + totalWeight += w + } + for i, w := range pb.weights { + pb.weights[i] = w / totalWeight + } + var cons = make([]*grpc.ClientConn, len(pb.addresses)) + for i, address := range pb.addresses { + con, err := func() (*grpc.ClientConn, error) { + toctx, c := context.WithTimeout(ctx, options.NodeConnectionTimeout) + defer c() + return grpc.DialContext(toctx, address, + grpc.WithInsecure(), + grpc.WithBlock(), + grpc.WithKeepaliveParams(keepalive.ClientParameters{ + Time: options.KeepaliveTime, + Timeout: options.KeepaliveTimeout, + PermitWithoutStream: options.KeepalivePermitWoStream, + }), + ) + }() + if err != nil { + return nil, err + } + cons[i] = con + } + options.weights = pb.weights + options.connections = cons + return new(ctx, options) +} + +// Pool is an interface providing connection artifacts on request. +type Pool interface { + ConnectionArtifacts() (client.Client, *token.SessionToken, error) +} + +type clientPack struct { + client client.Client + sessionToken *token.SessionToken + healthy bool +} + +type pool struct { + lock sync.RWMutex + sampler *Sampler + clientPacks []*clientPack +} + +func new(ctx context.Context, options *PoolBuilderOptions) (Pool, error) { + clientPacks := make([]*clientPack, len(options.weights)) + for i, con := range options.connections { + c, err := client.New(client.WithDefaultPrivateKey(options.Key), client.WithGRPCConnection(con)) + if err != nil { + return nil, err + } + st, err := c.CreateSession(ctx, options.SessionExpirationEpoch) + if err != nil { + address := "unknown" + if epi, err := c.EndpointInfo(ctx); err == nil { + address = epi.NodeInfo().Address() + } + return nil, fmt.Errorf("failed to create neofs session token for client %s: %w", address, err) + } + clientPacks[i] = &clientPack{client: c, sessionToken: st, healthy: true} + } + source := rand.NewSource(time.Now().UnixNano()) + sampler := NewSampler(options.weights, source) + pool := &pool{sampler: sampler, clientPacks: clientPacks} + go func() { + ticker := time.NewTimer(options.ClientRebalanceInterval) + for range ticker.C { + ok := true + for i, clientPack := range pool.clientPacks { + func() { + tctx, c := context.WithTimeout(ctx, options.NodeRequestTimeout) + defer c() + if _, err := clientPack.client.EndpointInfo(tctx); err != nil { + ok = false + } + pool.lock.Lock() + pool.clientPacks[i].healthy = ok + pool.lock.Unlock() + }() + } + ticker.Reset(options.ClientRebalanceInterval) + } + }() + return pool, nil +} + +func (p *pool) ConnectionArtifacts() (client.Client, *token.SessionToken, error) { + p.lock.RLock() + defer p.lock.RUnlock() + if len(p.clientPacks) == 1 { + cp := p.clientPacks[0] + if cp.healthy { + return cp.client, cp.sessionToken, nil + } + return nil, nil, errors.New("no healthy client") + } + attempts := 3 * len(p.clientPacks) + for k := 0; k < attempts; k++ { + i := p.sampler.Next() + if cp := p.clientPacks[i]; cp.healthy { + return cp.client, cp.sessionToken, nil + } + } + return nil, nil, errors.New("no healthy client") +} diff --git a/pkg/pool/sampler.go b/pkg/pool/sampler.go new file mode 100644 index 0000000..33b473c --- /dev/null +++ b/pkg/pool/sampler.go @@ -0,0 +1,81 @@ +package pool + +import "math/rand" + +// Sampler implements weighted random number generation using Vose's Alias +// Method (https://www.keithschwarz.com/darts-dice-coins/). +type Sampler struct { + randomGenerator *rand.Rand + probabilities []float64 + alias []int +} + +// NewSampler creates new Sampler with a given set of probabilities using +// given source of randomness. Created Sampler will produce numbers from +// 0 to len(probabilities). +func NewSampler(probabilities []float64, source rand.Source) *Sampler { + sampler := &Sampler{} + var ( + small workList + large workList + ) + n := len(probabilities) + sampler.randomGenerator = rand.New(source) + sampler.probabilities = make([]float64, n) + sampler.alias = make([]int, n) + // Compute scaled probabilities. + p := make([]float64, n) + for i := 0; i < n; i++ { + p[i] = probabilities[i] * float64(n) + } + for i, pi := range p { + if pi < 1 { + small.add(i) + } else { + large.add(i) + } + } + for len(small) > 0 && len(large) > 0 { + l, g := small.remove(), large.remove() + sampler.probabilities[l] = p[l] + sampler.alias[l] = g + p[g] = p[g] + p[l] - 1 + if p[g] < 1 { + small.add(g) + } else { + large.add(g) + } + } + for len(large) > 0 { + g := large.remove() + sampler.probabilities[g] = 1 + } + for len(small) > 0 { + l := small.remove() + sampler.probabilities[l] = 1 + } + return sampler +} + +// Next returns the next (not so) random number from Sampler. +func (g *Sampler) Next() int { + n := len(g.alias) + i := g.randomGenerator.Intn(n) + if g.randomGenerator.Float64() < g.probabilities[i] { + return i + } + return g.alias[i] +} + +type workList []int + +func (wl *workList) add(e int) { + *wl = append(*wl, e) +} + +func (wl *workList) remove() int { + l := len(*wl) - 1 + n := (*wl)[l] + *wl = (*wl)[:l] + return n +} From 9f476e3c1647f926e9445fa79031c96a739f6cbe Mon Sep 17 00:00:00 2001 From: Angira Kekteeva Date: Tue, 25 May 2021 14:10:01 +0300 Subject: [PATCH 2/4] [#4] neofs: Remove useless neofsClientObject Also ObjectClient interface and its functions Resolve imports Signed-off-by: Angira Kekteeva --- pkg/neofs/client-plant.go | 144 +------------------------------------- 1 file changed, 3 insertions(+), 141 deletions(-) diff --git a/pkg/neofs/client-plant.go b/pkg/neofs/client-plant.go index e13f29d..6cf4d90 100644 --- a/pkg/neofs/client-plant.go +++ b/pkg/neofs/client-plant.go @@ -3,80 +3,24 @@ package neofs import ( "context" "crypto/ecdsa" - "io" "github.com/nspcc-dev/neofs-api-go/pkg/client" - "github.com/nspcc-dev/neofs-api-go/pkg/container" - "github.com/nspcc-dev/neofs-api-go/pkg/object" "github.com/nspcc-dev/neofs-api-go/pkg/owner" "github.com/nspcc-dev/neofs-api-go/pkg/token" - "github.com/nspcc-dev/neofs-http-gw/connections" + "github.com/nspcc-dev/neofs-sdk-go/pkg/pool" ) -// BaseOptions represents basic NeoFS request options. -type BaseOptions struct { - Client client.Client - SessionToken *token.SessionToken - BearerToken *token.BearerToken -} - -// PutOptions represents NeoFS Put request options. -type PutOptions struct { - BaseOptions - Attributes []*object.Attribute - ContainerID *container.ID - OwnerID *owner.ID - Reader io.Reader -} - -// GetOptions represents NeoFS Get request options. -type GetOptions struct { - BaseOptions - ObjectAddress *object.Address - Writer io.Writer -} - -// SearchOptions represents NeoFS Search request options. -type SearchOptions struct { - BaseOptions - ContainerID *container.ID - Attribute struct { - Key string - Value string - } -} - -// DeleteOptions represents NeoFS Delete request options. -type DeleteOptions struct { - BaseOptions - ObjectAddress *object.Address -} - -// ObjectClient wraps basic NeoFS requests. -type ObjectClient interface { - Put(context.Context, *PutOptions) (*object.Address, error) - Get(context.Context, *GetOptions) (*object.Object, error) - Search(context.Context, *SearchOptions) ([]*object.ID, error) - Delete(context.Context, *DeleteOptions) error -} - // ClientPlant provides connections to NeoFS nodes from pool and allows to // get local owner ID. type ClientPlant interface { ConnectionArtifacts() (client.Client, *token.SessionToken, error) - Object() ObjectClient OwnerID() *owner.ID } -type neofsObjectClient struct { - key *ecdsa.PrivateKey - pool connections.Pool -} - type neofsClientPlant struct { key *ecdsa.PrivateKey ownerID *owner.ID - pool connections.Pool + pool pool.Pool } // ConnectionArtifacts returns connection from pool. @@ -84,94 +28,12 @@ func (cp *neofsClientPlant) ConnectionArtifacts() (client.Client, *token.Session return cp.pool.ConnectionArtifacts() } -// Object returns ObjectClient instance from plant. -func (cp *neofsClientPlant) Object() ObjectClient { - return &neofsObjectClient{ - key: cp.key, - pool: cp.pool, - } -} - // OwnerID returns plant's owner ID. func (cp *neofsClientPlant) OwnerID() *owner.ID { return cp.ownerID } // NewClientPlant creates new ClientPlant from given context, pool and credentials. -func NewClientPlant(ctx context.Context, pool connections.Pool, creds Credentials) (ClientPlant, error) { +func NewClientPlant(ctx context.Context, pool pool.Pool, creds Credentials) (ClientPlant, error) { return &neofsClientPlant{key: creds.PrivateKey(), ownerID: creds.Owner(), pool: pool}, nil } - -// Put does NeoFS Put request, returning new object address if successful. -func (oc *neofsObjectClient) Put(ctx context.Context, options *PutOptions) (*object.Address, error) { - var ( - err error - objectID *object.ID - ) - address := object.NewAddress() - rawObject := object.NewRaw() - rawObject.SetContainerID(options.ContainerID) - rawObject.SetOwnerID(options.OwnerID) - rawObject.SetAttributes(options.Attributes...) - ops := new(client.PutObjectParams). - WithObject(rawObject.Object()). - WithPayloadReader(options.Reader) - objectID, err = options.Client.PutObject( - ctx, - ops, - client.WithSession(options.SessionToken), - client.WithBearer(options.BearerToken), - ) - if err != nil { - return nil, err - } - address.SetObjectID(objectID) - address.SetContainerID(options.ContainerID) - return address, nil -} - -// Get does NeoFS Get request, returning an object received if successful. -func (oc *neofsObjectClient) Get(ctx context.Context, options *GetOptions) (*object.Object, error) { - var ( - err error - obj *object.Object - ) - ops := new(client.GetObjectParams). - WithAddress(options.ObjectAddress). - WithPayloadWriter(options.Writer) - obj, err = options.Client.GetObject( - ctx, - ops, - client.WithSession(options.SessionToken), - client.WithBearer(options.BearerToken), - ) - return obj, err -} - -// Search does NeoFS Search request, returning object IDs if successful. -func (oc *neofsObjectClient) Search(ctx context.Context, options *SearchOptions) ([]*object.ID, error) { - sfs := object.NewSearchFilters() - sfs.AddRootFilter() - sfs.AddFilter(options.Attribute.Key, options.Attribute.Value, object.MatchStringEqual) - sops := new(client.SearchObjectParams) - sops.WithContainerID(options.ContainerID) - sops.WithSearchFilters(sfs) - return options.Client.SearchObject( - ctx, - sops, - client.WithSession(options.SessionToken), - client.WithBearer(options.BearerToken), - ) -} - -// Delete deletes NeoFS object. -func (oc *neofsObjectClient) Delete(ctx context.Context, options *DeleteOptions) error { - ops := new(client.DeleteObjectParams).WithAddress(options.ObjectAddress) - err := options.Client.DeleteObject( - ctx, - ops, - client.WithSession(options.SessionToken), - client.WithBearer(options.BearerToken), - ) - return err -} From d62b4534db65a72b88d0009faee7bae085f0aa2b Mon Sep 17 00:00:00 2001 From: Angira Kekteeva Date: Tue, 25 May 2021 14:35:50 +0300 Subject: [PATCH 3/4] [#4] *: Add new imports for added pkgs Signed-off-by: Angira Kekteeva --- go.mod | 3 +++ go.sum | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/go.mod b/go.mod index bad5cc6..f889573 100644 --- a/go.mod +++ b/go.mod @@ -5,5 +5,8 @@ go 1.16 require ( github.com/alecthomas/participle v0.7.1 github.com/nspcc-dev/neofs-api-go v1.26.1 + github.com/nspcc-dev/neofs-crypto v0.3.0 github.com/stretchr/testify v1.6.1 + go.uber.org/zap v1.10.0 + google.golang.org/grpc v1.29.1 ) diff --git a/go.sum b/go.sum index b81a708..d06974e 100644 --- a/go.sum +++ b/go.sum @@ -23,6 +23,7 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= @@ -86,10 +87,13 @@ github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -103,8 +107,10 @@ github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -119,6 +125,7 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nspcc-dev/dbft v0.0.0-20191205084618-dacb1a30c254/go.mod h1:w1Ln2aT+dBlPhLnuZhBV+DfPEdS2CHWWLp5JTScY3bw= @@ -131,14 +138,17 @@ github.com/nspcc-dev/hrw v1.0.9 h1:17VcAuTtrstmFppBjfRiia4K2wA/ukXZhLFS8Y8rz5Y= github.com/nspcc-dev/hrw v1.0.9/go.mod h1:l/W2vx83vMQo6aStyx2AuZrJ+07lGv2JQGlVkPG06MU= github.com/nspcc-dev/neo-go v0.73.1-pre.0.20200303142215-f5a1b928ce09/go.mod h1:pPYwPZ2ks+uMnlRLUyXOpLieaDQSEaf4NM3zHVbRjmg= github.com/nspcc-dev/neo-go v0.91.0/go.mod h1:G6HdOWvzQ6tlvFdvFSN/PgCzLPN/X/X4d5hTjFRUDcc= +github.com/nspcc-dev/neo-go v0.95.0 h1:bttArYkIuhBJWSZsZ1xVW8MJsj5SvZwAhqVN3HZPNbo= github.com/nspcc-dev/neo-go v0.95.0/go.mod h1:bW07ge1WFXsBgqrcPpLUr6OcyQxHqM26MZNesWMdH0c= github.com/nspcc-dev/neofs-api-go v1.24.0/go.mod h1:G7dqincfdjBrAbL5nxVp82emF05fSVEqe59ICsoRDI8= github.com/nspcc-dev/neofs-api-go v1.26.1 h1:GMIuEB6Hv9IXP9SJd/1f8Df6gRriPkSplpmpJXgQ/1I= github.com/nspcc-dev/neofs-api-go v1.26.1/go.mod h1:SHuH1Ba3U/h3j+8HHbb3Cns1LfMlEb88guWog9Qi68Y= github.com/nspcc-dev/neofs-crypto v0.2.0/go.mod h1:F/96fUzPM3wR+UGsPi3faVNmFlA9KAEAUQR7dMxZmNA= github.com/nspcc-dev/neofs-crypto v0.2.3/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw= +github.com/nspcc-dev/neofs-crypto v0.3.0 h1:zlr3pgoxuzrmGCxc5W8dGVfA9Rro8diFvVnBg0L4ifM= github.com/nspcc-dev/neofs-crypto v0.3.0/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw= github.com/nspcc-dev/rfc6979 v0.1.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso= +github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYvOE= github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -150,6 +160,7 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -192,13 +203,17 @@ github.com/yuin/gopher-lua v0.0.0-20190514113301-1cd887cd7036/go.mod h1:gqRgreBU github.com/yuin/gopher-lua v0.0.0-20191128022950-c6266f4fe8d7/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -245,6 +260,7 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -266,6 +282,7 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 gopkg.in/abiosoft/ishell.v2 v2.0.0/go.mod h1:sFp+cGtH6o4s1FtpVPTMcHq2yue+c4DGOVohJCPUzwY= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= From 7cfe91fac75a97113941ecc53fd17c90bf50da87 Mon Sep 17 00:00:00 2001 From: Angira Kekteeva Date: Tue, 25 May 2021 14:46:58 +0300 Subject: [PATCH 4/4] [#4] pool: Rename exported structs in pool pkg Renamed PoolBuilderOptions to BuilderOptions and PoolBuilder to Builder because usages of them with prefix pool.* in other packages stutter. Signed-off-by: Angira Kekteeva --- pkg/pool/pool.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/pool/pool.go b/pkg/pool/pool.go index 3422f75..7dd1221 100644 --- a/pkg/pool/pool.go +++ b/pkg/pool/pool.go @@ -15,8 +15,8 @@ import ( "google.golang.org/grpc/keepalive" ) -// PoolBuilderOptions contains options used to build connection pool. -type PoolBuilderOptions struct { +// BuilderOptions contains options used to build connection pool. +type BuilderOptions struct { Key *ecdsa.PrivateKey NodeConnectionTimeout time.Duration NodeRequestTimeout time.Duration @@ -29,22 +29,22 @@ type PoolBuilderOptions struct { connections []*grpc.ClientConn } -// PoolBuilder is an interim structure used to collect node addresses/weights and +// Builder is an interim structure used to collect node addresses/weights and // build connection pool subsequently. -type PoolBuilder struct { +type Builder struct { addresses []string weights []float64 } // AddNode adds address/weight pair to node PoolBuilder list. -func (pb *PoolBuilder) AddNode(address string, weight float64) *PoolBuilder { +func (pb *Builder) AddNode(address string, weight float64) *Builder { pb.addresses = append(pb.addresses, address) pb.weights = append(pb.weights, weight) return pb } // Build creates new pool based on current PoolBuilder state and options. -func (pb *PoolBuilder) Build(ctx context.Context, options *PoolBuilderOptions) (Pool, error) { +func (pb *Builder) Build(ctx context.Context, options *BuilderOptions) (Pool, error) { if len(pb.addresses) == 0 { return nil, errors.New("no NeoFS peers configured") } @@ -97,7 +97,7 @@ type pool struct { clientPacks []*clientPack } -func new(ctx context.Context, options *PoolBuilderOptions) (Pool, error) { +func new(ctx context.Context, options *BuilderOptions) (Pool, error) { clientPacks := make([]*clientPack, len(options.weights)) for i, con := range options.connections { c, err := client.New(client.WithDefaultPrivateKey(options.Key), client.WithGRPCConnection(con))