forked from TrueCloudLab/frostfs-api-go
[#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 <evgeniy@nspcc.ru>
This commit is contained in:
parent
e39a1fd949
commit
ae2fb263f1
7 changed files with 134 additions and 52 deletions
|
@ -11,11 +11,19 @@ import (
|
||||||
"github.com/pkg/errors"
|
"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...)
|
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
|
// check remote node version
|
||||||
switch c.remoteNode.Version.Major() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
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
|
// apply all available options
|
||||||
callOptions := c.defaultCallOptions()
|
callOptions := c.defaultCallOptions()
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,16 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
Client struct {
|
// Client represents NeoFS client.
|
||||||
|
Client interface {
|
||||||
|
Accounting
|
||||||
|
Container
|
||||||
|
Netmap
|
||||||
|
Object
|
||||||
|
Session
|
||||||
|
}
|
||||||
|
|
||||||
|
clientImpl struct {
|
||||||
key *ecdsa.PrivateKey
|
key *ecdsa.PrivateKey
|
||||||
remoteNode TransportInfo
|
remoteNode TransportInfo
|
||||||
|
|
||||||
|
@ -35,7 +44,8 @@ const (
|
||||||
|
|
||||||
var errUnsupportedProtocol = errors.New("unsupported transport protocol")
|
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()
|
clientOptions := defaultClientOptions()
|
||||||
|
|
||||||
for i := range opts {
|
for i := range opts {
|
||||||
|
@ -43,7 +53,7 @@ func New(key *ecdsa.PrivateKey, opts ...Option) (*Client, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: make handshake to check latest version
|
// todo: make handshake to check latest version
|
||||||
return &Client{
|
return &clientImpl{
|
||||||
key: key,
|
key: key,
|
||||||
remoteNode: TransportInfo{
|
remoteNode: TransportInfo{
|
||||||
Version: pkg.SDKVersion(),
|
Version: pkg.SDKVersion(),
|
||||||
|
|
|
@ -15,6 +15,28 @@ import (
|
||||||
"github.com/pkg/errors"
|
"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 {
|
type delContainerSignWrapper struct {
|
||||||
body *v2container.DeleteRequestBody
|
body *v2container.DeleteRequestBody
|
||||||
}
|
}
|
||||||
|
@ -46,7 +68,7 @@ func (e EACLWithSignature) Signature() *pkg.Signature {
|
||||||
return e.sig
|
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() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
case 2:
|
||||||
return c.putContainerV2(ctx, cnr, opts...)
|
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.
|
// GetContainer receives container structure through NeoFS API call.
|
||||||
//
|
//
|
||||||
// Returns error if container structure is received but does not meet NeoFS API specification.
|
// 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() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
case 2:
|
||||||
return c.getContainerV2(ctx, id, opts...)
|
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.
|
// which checks if the structure of the resulting container matches its identifier.
|
||||||
//
|
//
|
||||||
// Returns container.ErrIDMismatch if container does not match the 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...)
|
cnr, err := c.GetContainer(ctx, id, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -84,7 +106,7 @@ func GetVerifiedContainerStructure(ctx context.Context, c *Client, id *container
|
||||||
return cnr, nil
|
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() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
case 2:
|
||||||
return c.listContainerV2(ctx, owner, opts...)
|
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...)
|
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() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
case 2:
|
||||||
return c.delContainerV2(ctx, id, opts...)
|
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...)
|
v, err := c.getEACL(ctx, id, true, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -115,11 +137,11 @@ func (c Client) GetEACL(ctx context.Context, id *container.ID, opts ...CallOptio
|
||||||
return v.table, nil
|
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...)
|
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() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
case 2:
|
||||||
resp, err := c.getEACLV2(ctx, id, verify, opts...)
|
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() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
case 2:
|
||||||
return c.setEACLV2(ctx, eacl, opts...)
|
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
|
// AnnounceContainerUsedSpace used by storage nodes to estimate their container
|
||||||
// sizes during lifetime. Use it only in storage node applications.
|
// sizes during lifetime. Use it only in storage node applications.
|
||||||
func (c Client) AnnounceContainerUsedSpace(
|
func (c clientImpl) AnnounceContainerUsedSpace(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
announce []container.UsedSpaceAnnouncement,
|
announce []container.UsedSpaceAnnouncement,
|
||||||
opts ...CallOption) error {
|
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
|
// apply all available options
|
||||||
callOptions := c.defaultCallOptions()
|
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
|
// apply all available options
|
||||||
callOptions := c.defaultCallOptions()
|
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
|
// apply all available options
|
||||||
callOptions := c.defaultCallOptions()
|
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
|
// apply all available options
|
||||||
callOptions := c.defaultCallOptions()
|
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
|
// apply all available options
|
||||||
callOptions := c.defaultCallOptions()
|
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
|
// apply all available options
|
||||||
callOptions := c.defaultCallOptions()
|
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,
|
ctx context.Context,
|
||||||
announce []container.UsedSpaceAnnouncement,
|
announce []container.UsedSpaceAnnouncement,
|
||||||
opts ...CallOption) error {
|
opts ...CallOption) error {
|
||||||
|
|
|
@ -10,10 +10,22 @@ import (
|
||||||
"github.com/pkg/errors"
|
"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
|
// 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
|
// 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.
|
// 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() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
case 2:
|
||||||
resp, err := c.endpointInfoV2(ctx, opts...)
|
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.
|
// 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() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
case 2:
|
||||||
resp, err := c.endpointInfoV2(ctx, opts...)
|
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
|
// apply all available options
|
||||||
callOptions := c.defaultCallOptions()
|
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.
|
// 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() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
case 2:
|
||||||
resp, err := c.networkInfoV2(ctx, opts...)
|
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
|
// apply all available options
|
||||||
callOptions := c.defaultCallOptions()
|
callOptions := c.defaultCallOptions()
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,26 @@ import (
|
||||||
"github.com/pkg/errors"
|
"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 {
|
type PutObjectParams struct {
|
||||||
obj *object.Object
|
obj *object.Object
|
||||||
|
|
||||||
|
@ -190,7 +210,7 @@ func (p *PutObjectParams) PayloadReader() io.Reader {
|
||||||
return nil
|
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
|
// check remote node version
|
||||||
switch c.remoteNode.Version.Major() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
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
|
// create V2 Object client
|
||||||
cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts)
|
cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -342,7 +362,7 @@ func (p *DeleteObjectParams) TombstoneAddressTarget() ObjectAddressWriter {
|
||||||
// DeleteObject is a wrapper over Client.DeleteObject method
|
// DeleteObject is a wrapper over Client.DeleteObject method
|
||||||
// that provides the ability to receive tombstone address
|
// that provides the ability to receive tombstone address
|
||||||
// without setting a target in the parameters.
|
// 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)
|
w := new(objectAddressWriter)
|
||||||
|
|
||||||
err := c.DeleteObject(ctx, p.WithTombstoneAddressTarget(w), opts...)
|
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.
|
// DeleteObject removes object by address.
|
||||||
//
|
//
|
||||||
// If target of tombstone address is not set, the address is ignored.
|
// 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
|
// check remote node version
|
||||||
switch c.remoteNode.Version.Major() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
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
|
// create V2 Object client
|
||||||
cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts)
|
cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -481,7 +501,7 @@ func (p *GetObjectParams) RawFlag() bool {
|
||||||
return false
|
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
|
// check remote node version
|
||||||
switch c.remoteNode.Version.Major() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
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
|
// create V2 Object client
|
||||||
cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts)
|
cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -653,7 +673,7 @@ func (p *ObjectHeaderParams) RawFlag() bool {
|
||||||
return false
|
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
|
// check remote node version
|
||||||
switch c.remoteNode.Version.Major() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
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
|
// create V2 Object client
|
||||||
cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts)
|
cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -850,7 +870,7 @@ func (p *RangeDataParams) DataWriter() io.Writer {
|
||||||
return nil
|
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
|
// check remote node version
|
||||||
switch c.remoteNode.Version.Major() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
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
|
// create V2 Object client
|
||||||
cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts)
|
cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1009,7 +1029,7 @@ func (p *RangeChecksumParams) withChecksumType(t checksumType) *RangeChecksumPar
|
||||||
return p
|
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...)
|
res, err := c.objectPayloadRangeHash(ctx, p.withChecksumType(checksumSHA256), opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -1018,7 +1038,7 @@ func (c *Client) ObjectPayloadRangeSHA256(ctx context.Context, p *RangeChecksumP
|
||||||
return res.([][sha256.Size]byte), nil
|
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...)
|
res, err := c.objectPayloadRangeHash(ctx, p.withChecksumType(checksumTZ), opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -1027,7 +1047,7 @@ func (c *Client) ObjectPayloadRangeTZ(ctx context.Context, p *RangeChecksumParam
|
||||||
return res.([][TZSize]byte), nil
|
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
|
// check remote node version
|
||||||
switch c.remoteNode.Version.Major() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
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
|
// create V2 Object client
|
||||||
cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts)
|
cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1176,7 +1196,7 @@ func (p *SearchObjectParams) SearchFilters() object.SearchFilters {
|
||||||
return nil
|
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
|
// check remote node version
|
||||||
switch c.remoteNode.Version.Major() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
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
|
// create V2 Object client
|
||||||
cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts)
|
cli, err := v2ObjectClient(c.remoteNode.Protocol, c.opts)
|
||||||
if err != nil {
|
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 {
|
if opts.session == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ func (e errOptionsLack) Error() string {
|
||||||
return fmt.Sprintf("lack of sdk client options to create %s client", string(e))
|
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{
|
return callOptions{
|
||||||
ttl: 2,
|
ttl: 2,
|
||||||
version: pkg.SDKVersion(),
|
version: pkg.SDKVersion(),
|
||||||
|
|
|
@ -11,9 +11,19 @@ import (
|
||||||
"github.com/pkg/errors"
|
"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")
|
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() {
|
switch c.remoteNode.Version.Major() {
|
||||||
case 2:
|
case 2:
|
||||||
return c.createSessionV2(ctx, expiration, opts...)
|
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
|
// apply all available options
|
||||||
callOptions := c.defaultCallOptions()
|
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.
|
// Provided token is attached to all requests without WithSession option.
|
||||||
// Use WithSession(nil) option in order to send request without session token.
|
// 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
|
c.sessionToken = token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +137,6 @@ func (c *Client) AttachSessionToken(token *token.SessionToken) {
|
||||||
//
|
//
|
||||||
// Provided bearer is attached to all requests without WithBearer option.
|
// Provided bearer is attached to all requests without WithBearer option.
|
||||||
// Use WithBearer(nil) option in order to send request without bearer token.
|
// 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
|
c.bearerToken = token
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue