178 lines
4.8 KiB
Go
178 lines
4.8 KiB
Go
|
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
|
||
|
}
|