From ae2fb263f1f08d5c24adfb54988ca3bb930d774d Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 12 Mar 2021 18:02:26 +0300 Subject: [PATCH] [#266] pkg/client: Export `Client` interface instead of structure Make it easier to test API clients and mock specific methods. Also add comments on exported methods. Signed-off-by: Evgenii Stratonikov --- pkg/client/accounting.go | 14 +++++++--- pkg/client/client.go | 16 ++++++++--- pkg/client/container.go | 58 +++++++++++++++++++++++++++------------- pkg/client/netmap.go | 22 +++++++++++---- pkg/client/object.go | 56 +++++++++++++++++++++++++------------- pkg/client/opts.go | 2 +- pkg/client/session.go | 18 ++++++++++--- 7 files changed, 134 insertions(+), 52 deletions(-) diff --git a/pkg/client/accounting.go b/pkg/client/accounting.go index 99e520c..e9db7f1 100644 --- a/pkg/client/accounting.go +++ b/pkg/client/accounting.go @@ -11,11 +11,19 @@ import ( "github.com/pkg/errors" ) -func (c Client) GetSelfBalance(ctx context.Context, opts ...CallOption) (*accounting.Decimal, error) { +// Accounting contains methods related to balance querying. +type Accounting interface { + // GetSelfBalance returns balance of the account deduced from client's key. + GetSelfBalance(context.Context, ...CallOption) (*accounting.Decimal, error) + // GetBalance returns balance of provided account. + GetBalance(context.Context, *owner.ID, ...CallOption) (*accounting.Decimal, error) +} + +func (c clientImpl) GetSelfBalance(ctx context.Context, opts ...CallOption) (*accounting.Decimal, error) { return c.GetBalance(ctx, nil, opts...) } -func (c Client) GetBalance(ctx context.Context, owner *owner.ID, opts ...CallOption) (*accounting.Decimal, error) { +func (c clientImpl) GetBalance(ctx context.Context, owner *owner.ID, opts ...CallOption) (*accounting.Decimal, error) { // check remote node version switch c.remoteNode.Version.Major() { case 2: @@ -25,7 +33,7 @@ func (c Client) GetBalance(ctx context.Context, owner *owner.ID, opts ...CallOpt } } -func (c Client) getBalanceV2(ctx context.Context, ownerID *owner.ID, opts ...CallOption) (*accounting.Decimal, error) { +func (c clientImpl) getBalanceV2(ctx context.Context, ownerID *owner.ID, opts ...CallOption) (*accounting.Decimal, error) { // apply all available options callOptions := c.defaultCallOptions() diff --git a/pkg/client/client.go b/pkg/client/client.go index 94770d4..42bd454 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -9,7 +9,16 @@ import ( ) type ( - Client struct { + // Client represents NeoFS client. + Client interface { + Accounting + Container + Netmap + Object + Session + } + + clientImpl struct { key *ecdsa.PrivateKey remoteNode TransportInfo @@ -35,7 +44,8 @@ const ( var errUnsupportedProtocol = errors.New("unsupported transport protocol") -func New(key *ecdsa.PrivateKey, opts ...Option) (*Client, error) { +// New returns new client which uses key as default signing key. +func New(key *ecdsa.PrivateKey, opts ...Option) (Client, error) { clientOptions := defaultClientOptions() for i := range opts { @@ -43,7 +53,7 @@ func New(key *ecdsa.PrivateKey, opts ...Option) (*Client, error) { } // todo: make handshake to check latest version - return &Client{ + return &clientImpl{ key: key, remoteNode: TransportInfo{ Version: pkg.SDKVersion(), diff --git a/pkg/client/container.go b/pkg/client/container.go index 83ea657..1328028 100644 --- a/pkg/client/container.go +++ b/pkg/client/container.go @@ -15,6 +15,28 @@ import ( "github.com/pkg/errors" ) +// Container contains methods related to container and ACL. +type Container interface { + // PutContainer creates new container in the NeoFS network. + PutContainer(context.Context, *container.Container, ...CallOption) (*container.ID, error) + // GetContainer returns container by ID. + GetContainer(context.Context, *container.ID, ...CallOption) (*container.Container, error) + // ListContainers return container list with the provided owner. + ListContainers(context.Context, *owner.ID, ...CallOption) ([]*container.ID, error) + // ListSelfContainers is similar to ListContainers but uses client's key to deduce owner ID. + ListSelfContainers(context.Context, ...CallOption) ([]*container.ID, error) + // DeleteContainer removes container from NeoFS network. + DeleteContainer(context.Context, *container.ID, ...CallOption) error + // GetEACL returns extended ACL for a given container. + GetEACL(context.Context, *container.ID, ...CallOption) (*eacl.Table, error) + // GetEACLWithSignature is similar to GetEACL but returns signed ACL. + GetEACLWithSignature(context.Context, *container.ID, ...CallOption) (*EACLWithSignature, error) + // SetEACL sets extended ACL. + SetEACL(context.Context, *eacl.Table, ...CallOption) error + // AnnounceContainerUsedSpace announces amount of space which is taken by stored objects. + AnnounceContainerUsedSpace(context.Context, []container.UsedSpaceAnnouncement, ...CallOption) error +} + type delContainerSignWrapper struct { body *v2container.DeleteRequestBody } @@ -46,7 +68,7 @@ func (e EACLWithSignature) Signature() *pkg.Signature { return e.sig } -func (c Client) PutContainer(ctx context.Context, cnr *container.Container, opts ...CallOption) (*container.ID, error) { +func (c clientImpl) PutContainer(ctx context.Context, cnr *container.Container, opts ...CallOption) (*container.ID, error) { switch c.remoteNode.Version.Major() { case 2: return c.putContainerV2(ctx, cnr, opts...) @@ -58,7 +80,7 @@ func (c Client) PutContainer(ctx context.Context, cnr *container.Container, opts // GetContainer receives container structure through NeoFS API call. // // Returns error if container structure is received but does not meet NeoFS API specification. -func (c Client) GetContainer(ctx context.Context, id *container.ID, opts ...CallOption) (*container.Container, error) { +func (c clientImpl) GetContainer(ctx context.Context, id *container.ID, opts ...CallOption) (*container.Container, error) { switch c.remoteNode.Version.Major() { case 2: return c.getContainerV2(ctx, id, opts...) @@ -71,7 +93,7 @@ func (c Client) GetContainer(ctx context.Context, id *container.ID, opts ...Call // which checks if the structure of the resulting container matches its identifier. // // Returns container.ErrIDMismatch if container does not match the identifier. -func GetVerifiedContainerStructure(ctx context.Context, c *Client, id *container.ID, opts ...CallOption) (*container.Container, error) { +func GetVerifiedContainerStructure(ctx context.Context, c Client, id *container.ID, opts ...CallOption) (*container.Container, error) { cnr, err := c.GetContainer(ctx, id, opts...) if err != nil { return nil, err @@ -84,7 +106,7 @@ func GetVerifiedContainerStructure(ctx context.Context, c *Client, id *container return cnr, nil } -func (c Client) ListContainers(ctx context.Context, owner *owner.ID, opts ...CallOption) ([]*container.ID, error) { +func (c clientImpl) ListContainers(ctx context.Context, owner *owner.ID, opts ...CallOption) ([]*container.ID, error) { switch c.remoteNode.Version.Major() { case 2: return c.listContainerV2(ctx, owner, opts...) @@ -93,11 +115,11 @@ func (c Client) ListContainers(ctx context.Context, owner *owner.ID, opts ...Cal } } -func (c Client) ListSelfContainers(ctx context.Context, opts ...CallOption) ([]*container.ID, error) { +func (c clientImpl) ListSelfContainers(ctx context.Context, opts ...CallOption) ([]*container.ID, error) { return c.ListContainers(ctx, nil, opts...) } -func (c Client) DeleteContainer(ctx context.Context, id *container.ID, opts ...CallOption) error { +func (c clientImpl) DeleteContainer(ctx context.Context, id *container.ID, opts ...CallOption) error { switch c.remoteNode.Version.Major() { case 2: return c.delContainerV2(ctx, id, opts...) @@ -106,7 +128,7 @@ func (c Client) DeleteContainer(ctx context.Context, id *container.ID, opts ...C } } -func (c Client) GetEACL(ctx context.Context, id *container.ID, opts ...CallOption) (*eacl.Table, error) { +func (c clientImpl) GetEACL(ctx context.Context, id *container.ID, opts ...CallOption) (*eacl.Table, error) { v, err := c.getEACL(ctx, id, true, opts...) if err != nil { return nil, err @@ -115,11 +137,11 @@ func (c Client) GetEACL(ctx context.Context, id *container.ID, opts ...CallOptio return v.table, nil } -func (c Client) GetEACLWithSignature(ctx context.Context, id *container.ID, opts ...CallOption) (*EACLWithSignature, error) { +func (c clientImpl) GetEACLWithSignature(ctx context.Context, id *container.ID, opts ...CallOption) (*EACLWithSignature, error) { return c.getEACL(ctx, id, false, opts...) } -func (c Client) getEACL(ctx context.Context, id *container.ID, verify bool, opts ...CallOption) (*EACLWithSignature, error) { +func (c clientImpl) getEACL(ctx context.Context, id *container.ID, verify bool, opts ...CallOption) (*EACLWithSignature, error) { switch c.remoteNode.Version.Major() { case 2: resp, err := c.getEACLV2(ctx, id, verify, opts...) @@ -136,7 +158,7 @@ func (c Client) getEACL(ctx context.Context, id *container.ID, verify bool, opts } } -func (c Client) SetEACL(ctx context.Context, eacl *eacl.Table, opts ...CallOption) error { +func (c clientImpl) SetEACL(ctx context.Context, eacl *eacl.Table, opts ...CallOption) error { switch c.remoteNode.Version.Major() { case 2: return c.setEACLV2(ctx, eacl, opts...) @@ -147,7 +169,7 @@ func (c Client) SetEACL(ctx context.Context, eacl *eacl.Table, opts ...CallOptio // AnnounceContainerUsedSpace used by storage nodes to estimate their container // sizes during lifetime. Use it only in storage node applications. -func (c Client) AnnounceContainerUsedSpace( +func (c clientImpl) AnnounceContainerUsedSpace( ctx context.Context, announce []container.UsedSpaceAnnouncement, opts ...CallOption) error { @@ -159,7 +181,7 @@ func (c Client) AnnounceContainerUsedSpace( } } -func (c Client) putContainerV2(ctx context.Context, cnr *container.Container, opts ...CallOption) (*container.ID, error) { +func (c clientImpl) putContainerV2(ctx context.Context, cnr *container.Container, opts ...CallOption) (*container.ID, error) { // apply all available options callOptions := c.defaultCallOptions() @@ -231,7 +253,7 @@ func (c Client) putContainerV2(ctx context.Context, cnr *container.Container, op } } -func (c Client) getContainerV2(ctx context.Context, id *container.ID, opts ...CallOption) (*container.Container, error) { +func (c clientImpl) getContainerV2(ctx context.Context, id *container.ID, opts ...CallOption) (*container.Container, error) { // apply all available options callOptions := c.defaultCallOptions() @@ -274,7 +296,7 @@ func (c Client) getContainerV2(ctx context.Context, id *container.ID, opts ...Ca } } -func (c Client) listContainerV2(ctx context.Context, ownerID *owner.ID, opts ...CallOption) ([]*container.ID, error) { +func (c clientImpl) listContainerV2(ctx context.Context, ownerID *owner.ID, opts ...CallOption) ([]*container.ID, error) { // apply all available options callOptions := c.defaultCallOptions() @@ -332,7 +354,7 @@ func (c Client) listContainerV2(ctx context.Context, ownerID *owner.ID, opts ... } } -func (c Client) delContainerV2(ctx context.Context, id *container.ID, opts ...CallOption) error { +func (c clientImpl) delContainerV2(ctx context.Context, id *container.ID, opts ...CallOption) error { // apply all available options callOptions := c.defaultCallOptions() @@ -391,7 +413,7 @@ func (c Client) delContainerV2(ctx context.Context, id *container.ID, opts ...Ca } } -func (c Client) getEACLV2(ctx context.Context, id *container.ID, verify bool, opts ...CallOption) (*v2container.GetExtendedACLResponseBody, error) { +func (c clientImpl) getEACLV2(ctx context.Context, id *container.ID, verify bool, opts ...CallOption) (*v2container.GetExtendedACLResponseBody, error) { // apply all available options callOptions := c.defaultCallOptions() @@ -455,7 +477,7 @@ func (c Client) getEACLV2(ctx context.Context, id *container.ID, verify bool, op } } -func (c Client) setEACLV2(ctx context.Context, eacl *eacl.Table, opts ...CallOption) error { +func (c clientImpl) setEACLV2(ctx context.Context, eacl *eacl.Table, opts ...CallOption) error { // apply all available options callOptions := c.defaultCallOptions() @@ -511,7 +533,7 @@ func (c Client) setEACLV2(ctx context.Context, eacl *eacl.Table, opts ...CallOpt } } -func (c Client) announceContainerUsedSpaceV2( +func (c clientImpl) announceContainerUsedSpaceV2( ctx context.Context, announce []container.UsedSpaceAnnouncement, opts ...CallOption) error { diff --git a/pkg/client/netmap.go b/pkg/client/netmap.go index c440aa1..b3f8966 100644 --- a/pkg/client/netmap.go +++ b/pkg/client/netmap.go @@ -10,10 +10,22 @@ import ( "github.com/pkg/errors" ) +// Netmap contains methods related to netmap. +type Netmap interface { + // EndpointInfo returns attributes, address and public key of the node, specified + // in client constructor via address or open connection. This can be used as a + // health check to see if node is alive and responses to requests. + EndpointInfo(context.Context, ...CallOption) (*netmap.NodeInfo, error) + // Epoch returns the epoch number from the local state of the remote host. + Epoch(context.Context, ...CallOption) (uint64, error) + // NetworkInfo returns information about the NeoFS network of which the remote server is a part. + NetworkInfo(context.Context, ...CallOption) (*netmap.NetworkInfo, error) +} + // EndpointInfo returns attributes, address and public key of the node, specified // in client constructor via address or open connection. This can be used as a // health check to see if node is alive and responses to requests. -func (c Client) EndpointInfo(ctx context.Context, opts ...CallOption) (*netmap.NodeInfo, error) { +func (c clientImpl) EndpointInfo(ctx context.Context, opts ...CallOption) (*netmap.NodeInfo, error) { switch c.remoteNode.Version.Major() { case 2: resp, err := c.endpointInfoV2(ctx, opts...) @@ -28,7 +40,7 @@ func (c Client) EndpointInfo(ctx context.Context, opts ...CallOption) (*netmap.N } // Epoch returns the epoch number from the local state of the remote host. -func (c Client) Epoch(ctx context.Context, opts ...CallOption) (uint64, error) { +func (c clientImpl) Epoch(ctx context.Context, opts ...CallOption) (uint64, error) { switch c.remoteNode.Version.Major() { case 2: resp, err := c.endpointInfoV2(ctx, opts...) @@ -42,7 +54,7 @@ func (c Client) Epoch(ctx context.Context, opts ...CallOption) (uint64, error) { } } -func (c Client) endpointInfoV2(ctx context.Context, opts ...CallOption) (*v2netmap.LocalNodeInfoResponse, error) { +func (c clientImpl) endpointInfoV2(ctx context.Context, opts ...CallOption) (*v2netmap.LocalNodeInfoResponse, error) { // apply all available options callOptions := c.defaultCallOptions() @@ -116,7 +128,7 @@ func v2NetmapClientFromOptions(opts *clientOptions) (cli *v2netmap.Client, err e } // NetworkInfo returns information about the NeoFS network of which the remote server is a part. -func (c Client) NetworkInfo(ctx context.Context, opts ...CallOption) (*netmap.NetworkInfo, error) { +func (c clientImpl) NetworkInfo(ctx context.Context, opts ...CallOption) (*netmap.NetworkInfo, error) { switch c.remoteNode.Version.Major() { case 2: resp, err := c.networkInfoV2(ctx, opts...) @@ -130,7 +142,7 @@ func (c Client) NetworkInfo(ctx context.Context, opts ...CallOption) (*netmap.Ne } } -func (c Client) networkInfoV2(ctx context.Context, opts ...CallOption) (*v2netmap.NetworkInfoResponse, error) { +func (c clientImpl) networkInfoV2(ctx context.Context, opts ...CallOption) (*v2netmap.NetworkInfoResponse, error) { // apply all available options callOptions := c.defaultCallOptions() diff --git a/pkg/client/object.go b/pkg/client/object.go index 7c07051..62f99cf 100644 --- a/pkg/client/object.go +++ b/pkg/client/object.go @@ -19,6 +19,26 @@ import ( "github.com/pkg/errors" ) +// Object contains methods for working with objects. +type Object interface { + // PutObject puts new object to NeoFS. + PutObject(context.Context, *PutObjectParams, ...CallOption) (*object.ID, error) + // DeleteObject deletes object to NeoFS. + DeleteObject(context.Context, *DeleteObjectParams, ...CallOption) error + // GetObject returns object stored in NeoFS. + GetObject(context.Context, *GetObjectParams, ...CallOption) (*object.Object, error) + // GetObjectHeader returns object header. + GetObjectHeader(context.Context, *ObjectHeaderParams, ...CallOption) (*object.Object, error) + // ObjectPayloadRangeData returns range of object payload. + ObjectPayloadRangeData(context.Context, *RangeDataParams, ...CallOption) ([]byte, error) + // ObjectPayloadRangeSHA256 returns sha-256 hashes of object sub-ranges from NeoFS. + ObjectPayloadRangeSHA256(context.Context, *RangeChecksumParams, ...CallOption) ([][sha256.Size]byte, error) + // ObjectPayloadRangeTZ returns homomorphic hashes of object sub-ranges from NeoFS. + ObjectPayloadRangeTZ(context.Context, *RangeChecksumParams, ...CallOption) ([][TZSize]byte, error) + // SearchObject searches for objects in NeoFS using provided parameters. + SearchObject(context.Context, *SearchObjectParams, ...CallOption) ([]*object.ID, error) +} + type PutObjectParams struct { obj *object.Object @@ -190,7 +210,7 @@ func (p *PutObjectParams) PayloadReader() io.Reader { return nil } -func (c *Client) PutObject(ctx context.Context, p *PutObjectParams, opts ...CallOption) (*object.ID, error) { +func (c *clientImpl) PutObject(ctx context.Context, p *PutObjectParams, opts ...CallOption) (*object.ID, error) { // check remote node version switch c.remoteNode.Version.Major() { case 2: @@ -200,7 +220,7 @@ func (c *Client) PutObject(ctx context.Context, p *PutObjectParams, opts ...Call } } -func (c *Client) putObjectV2(ctx context.Context, p *PutObjectParams, opts ...CallOption) (*object.ID, error) { +func (c *clientImpl) putObjectV2(ctx context.Context, p *PutObjectParams, opts ...CallOption) (*object.ID, error) { // create V2 Object client cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts) if err != nil { @@ -342,7 +362,7 @@ func (p *DeleteObjectParams) TombstoneAddressTarget() ObjectAddressWriter { // DeleteObject is a wrapper over Client.DeleteObject method // that provides the ability to receive tombstone address // without setting a target in the parameters. -func DeleteObject(ctx context.Context, c *Client, p *DeleteObjectParams, opts ...CallOption) (*object.Address, error) { +func DeleteObject(ctx context.Context, c Client, p *DeleteObjectParams, opts ...CallOption) (*object.Address, error) { w := new(objectAddressWriter) err := c.DeleteObject(ctx, p.WithTombstoneAddressTarget(w), opts...) @@ -356,7 +376,7 @@ func DeleteObject(ctx context.Context, c *Client, p *DeleteObjectParams, opts .. // DeleteObject removes object by address. // // If target of tombstone address is not set, the address is ignored. -func (c *Client) DeleteObject(ctx context.Context, p *DeleteObjectParams, opts ...CallOption) error { +func (c *clientImpl) DeleteObject(ctx context.Context, p *DeleteObjectParams, opts ...CallOption) error { // check remote node version switch c.remoteNode.Version.Major() { case 2: @@ -378,7 +398,7 @@ func (c *Client) DeleteObject(ctx context.Context, p *DeleteObjectParams, opts . } } -func (c *Client) deleteObjectV2(ctx context.Context, p *DeleteObjectParams, opts ...CallOption) (*v2object.DeleteResponse, error) { +func (c *clientImpl) deleteObjectV2(ctx context.Context, p *DeleteObjectParams, opts ...CallOption) (*v2object.DeleteResponse, error) { // create V2 Object client cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts) if err != nil { @@ -481,7 +501,7 @@ func (p *GetObjectParams) RawFlag() bool { return false } -func (c *Client) GetObject(ctx context.Context, p *GetObjectParams, opts ...CallOption) (*object.Object, error) { +func (c *clientImpl) GetObject(ctx context.Context, p *GetObjectParams, opts ...CallOption) (*object.Object, error) { // check remote node version switch c.remoteNode.Version.Major() { case 2: @@ -491,7 +511,7 @@ func (c *Client) GetObject(ctx context.Context, p *GetObjectParams, opts ...Call } } -func (c *Client) getObjectV2(ctx context.Context, p *GetObjectParams, opts ...CallOption) (*object.Object, error) { +func (c *clientImpl) getObjectV2(ctx context.Context, p *GetObjectParams, opts ...CallOption) (*object.Object, error) { // create V2 Object client cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts) if err != nil { @@ -653,7 +673,7 @@ func (p *ObjectHeaderParams) RawFlag() bool { return false } -func (c *Client) GetObjectHeader(ctx context.Context, p *ObjectHeaderParams, opts ...CallOption) (*object.Object, error) { +func (c *clientImpl) GetObjectHeader(ctx context.Context, p *ObjectHeaderParams, opts ...CallOption) (*object.Object, error) { // check remote node version switch c.remoteNode.Version.Major() { case 2: @@ -663,7 +683,7 @@ func (c *Client) GetObjectHeader(ctx context.Context, p *ObjectHeaderParams, opt } } -func (c *Client) getObjectHeaderV2(ctx context.Context, p *ObjectHeaderParams, opts ...CallOption) (*object.Object, error) { +func (c *clientImpl) getObjectHeaderV2(ctx context.Context, p *ObjectHeaderParams, opts ...CallOption) (*object.Object, error) { // create V2 Object client cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts) if err != nil { @@ -850,7 +870,7 @@ func (p *RangeDataParams) DataWriter() io.Writer { return nil } -func (c *Client) ObjectPayloadRangeData(ctx context.Context, p *RangeDataParams, opts ...CallOption) ([]byte, error) { +func (c *clientImpl) ObjectPayloadRangeData(ctx context.Context, p *RangeDataParams, opts ...CallOption) ([]byte, error) { // check remote node version switch c.remoteNode.Version.Major() { case 2: @@ -860,7 +880,7 @@ func (c *Client) ObjectPayloadRangeData(ctx context.Context, p *RangeDataParams, } } -func (c *Client) objectPayloadRangeV2(ctx context.Context, p *RangeDataParams, opts ...CallOption) ([]byte, error) { +func (c *clientImpl) objectPayloadRangeV2(ctx context.Context, p *RangeDataParams, opts ...CallOption) ([]byte, error) { // create V2 Object client cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts) if err != nil { @@ -1009,7 +1029,7 @@ func (p *RangeChecksumParams) withChecksumType(t checksumType) *RangeChecksumPar return p } -func (c *Client) ObjectPayloadRangeSHA256(ctx context.Context, p *RangeChecksumParams, opts ...CallOption) ([][sha256.Size]byte, error) { +func (c *clientImpl) ObjectPayloadRangeSHA256(ctx context.Context, p *RangeChecksumParams, opts ...CallOption) ([][sha256.Size]byte, error) { res, err := c.objectPayloadRangeHash(ctx, p.withChecksumType(checksumSHA256), opts...) if err != nil { return nil, err @@ -1018,7 +1038,7 @@ func (c *Client) ObjectPayloadRangeSHA256(ctx context.Context, p *RangeChecksumP return res.([][sha256.Size]byte), nil } -func (c *Client) ObjectPayloadRangeTZ(ctx context.Context, p *RangeChecksumParams, opts ...CallOption) ([][TZSize]byte, error) { +func (c *clientImpl) ObjectPayloadRangeTZ(ctx context.Context, p *RangeChecksumParams, opts ...CallOption) ([][TZSize]byte, error) { res, err := c.objectPayloadRangeHash(ctx, p.withChecksumType(checksumTZ), opts...) if err != nil { return nil, err @@ -1027,7 +1047,7 @@ func (c *Client) ObjectPayloadRangeTZ(ctx context.Context, p *RangeChecksumParam return res.([][TZSize]byte), nil } -func (c *Client) objectPayloadRangeHash(ctx context.Context, p *RangeChecksumParams, opts ...CallOption) (interface{}, error) { +func (c *clientImpl) objectPayloadRangeHash(ctx context.Context, p *RangeChecksumParams, opts ...CallOption) (interface{}, error) { // check remote node version switch c.remoteNode.Version.Major() { case 2: @@ -1037,7 +1057,7 @@ func (c *Client) objectPayloadRangeHash(ctx context.Context, p *RangeChecksumPar } } -func (c *Client) objectPayloadRangeHashV2(ctx context.Context, p *RangeChecksumParams, opts ...CallOption) (interface{}, error) { +func (c *clientImpl) objectPayloadRangeHashV2(ctx context.Context, p *RangeChecksumParams, opts ...CallOption) (interface{}, error) { // create V2 Object client cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts) if err != nil { @@ -1176,7 +1196,7 @@ func (p *SearchObjectParams) SearchFilters() object.SearchFilters { return nil } -func (c *Client) SearchObject(ctx context.Context, p *SearchObjectParams, opts ...CallOption) ([]*object.ID, error) { +func (c *clientImpl) SearchObject(ctx context.Context, p *SearchObjectParams, opts ...CallOption) ([]*object.ID, error) { // check remote node version switch c.remoteNode.Version.Major() { case 2: @@ -1186,7 +1206,7 @@ func (c *Client) SearchObject(ctx context.Context, p *SearchObjectParams, opts . } } -func (c *Client) searchObjectV2(ctx context.Context, p *SearchObjectParams, opts ...CallOption) ([]*object.ID, error) { +func (c *clientImpl) searchObjectV2(ctx context.Context, p *SearchObjectParams, opts ...CallOption) ([]*object.ID, error) { // create V2 Object client cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts) if err != nil { @@ -1297,7 +1317,7 @@ func v2ObjectClient(proto TransportProtocol, opts *clientOptions) (*v2object.Cli } } -func (c Client) attachV2SessionToken(opts callOptions, hdr *v2session.RequestMetaHeader, info v2SessionReqInfo) error { +func (c clientImpl) attachV2SessionToken(opts callOptions, hdr *v2session.RequestMetaHeader, info v2SessionReqInfo) error { if opts.session == nil { return nil } diff --git a/pkg/client/opts.go b/pkg/client/opts.go index 7450d12..9f16888 100644 --- a/pkg/client/opts.go +++ b/pkg/client/opts.go @@ -68,7 +68,7 @@ func (e errOptionsLack) Error() string { return fmt.Sprintf("lack of sdk client options to create %s client", string(e)) } -func (c Client) defaultCallOptions() callOptions { +func (c clientImpl) defaultCallOptions() callOptions { return callOptions{ ttl: 2, version: pkg.SDKVersion(), diff --git a/pkg/client/session.go b/pkg/client/session.go index 6f368e1..4df7263 100644 --- a/pkg/client/session.go +++ b/pkg/client/session.go @@ -11,9 +11,19 @@ import ( "github.com/pkg/errors" ) +// Session contains session-related methods. +type Session interface { + // CreateSession creates session using provided expiration time. + CreateSession(context.Context, uint64, ...CallOption) (*token.SessionToken, error) + // AttachSessionToken attaches session token to be used by default for following requests. + AttachSessionToken(*token.SessionToken) + // AttachBearerToken attaches bearer token to be used by default for following requests. + AttachBearerToken(*token.BearerToken) +} + var errMalformedResponseBody = errors.New("malformed response body") -func (c Client) CreateSession(ctx context.Context, expiration uint64, opts ...CallOption) (*token.SessionToken, error) { +func (c clientImpl) CreateSession(ctx context.Context, expiration uint64, opts ...CallOption) (*token.SessionToken, error) { switch c.remoteNode.Version.Major() { case 2: return c.createSessionV2(ctx, expiration, opts...) @@ -22,7 +32,7 @@ func (c Client) CreateSession(ctx context.Context, expiration uint64, opts ...Ca } } -func (c Client) createSessionV2(ctx context.Context, expiration uint64, opts ...CallOption) (*token.SessionToken, error) { +func (c clientImpl) createSessionV2(ctx context.Context, expiration uint64, opts ...CallOption) (*token.SessionToken, error) { // apply all available options callOptions := c.defaultCallOptions() @@ -119,7 +129,7 @@ func v2SessionClientFromOptions(opts *clientOptions) (cli *v2session.Client, err // // Provided token is attached to all requests without WithSession option. // Use WithSession(nil) option in order to send request without session token. -func (c *Client) AttachSessionToken(token *token.SessionToken) { +func (c *clientImpl) AttachSessionToken(token *token.SessionToken) { c.sessionToken = token } @@ -127,6 +137,6 @@ func (c *Client) AttachSessionToken(token *token.SessionToken) { // // Provided bearer is attached to all requests without WithBearer option. // Use WithBearer(nil) option in order to send request without bearer token. -func (c *Client) AttachBearerToken(token *token.BearerToken) { +func (c *clientImpl) AttachBearerToken(token *token.BearerToken) { c.bearerToken = token }