forked from TrueCloudLab/frostfs-sdk-go
client: Support static data slicing
Add `CreateObject` function which slices data stream into NeoFS objects and saves the produced objects in the NeoFS network using `Client`. Closes #342. Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
This commit is contained in:
parent
8eded316de
commit
0d7d03d56f
1 changed files with 87 additions and 0 deletions
|
@ -13,10 +13,13 @@ import (
|
||||||
v2session "github.com/nspcc-dev/neofs-api-go/v2/session"
|
v2session "github.com/nspcc-dev/neofs-api-go/v2/session"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/bearer"
|
"github.com/nspcc-dev/neofs-sdk-go/bearer"
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
|
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
|
"github.com/nspcc-dev/neofs-sdk-go/object/slicer"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/session"
|
"github.com/nspcc-dev/neofs-sdk-go/session"
|
||||||
|
"github.com/nspcc-dev/neofs-sdk-go/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PrmObjectPutInit groups parameters of ObjectPutInit operation.
|
// PrmObjectPutInit groups parameters of ObjectPutInit operation.
|
||||||
|
@ -263,3 +266,87 @@ func (c *Client) ObjectPutInit(ctx context.Context, prm PrmObjectPutInit) (*Obje
|
||||||
|
|
||||||
return &w, nil
|
return &w, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type objectWriter struct {
|
||||||
|
context context.Context
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *objectWriter) InitDataStream(header object.Object) (io.Writer, error) {
|
||||||
|
var prm PrmObjectPutInit
|
||||||
|
|
||||||
|
stream, err := x.client.ObjectPutInit(x.context, prm)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("init object stream: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if stream.WriteHeader(header) {
|
||||||
|
return &payloadWriter{
|
||||||
|
stream: stream,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := stream.Close()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, apistatus.ErrFromStatus(res.Status())
|
||||||
|
}
|
||||||
|
|
||||||
|
type payloadWriter struct {
|
||||||
|
stream *ObjectWriter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *payloadWriter) Write(p []byte) (int, error) {
|
||||||
|
if !x.stream.WritePayloadChunk(p) {
|
||||||
|
return 0, x.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *payloadWriter) Close() error {
|
||||||
|
res, err := x.stream.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return apistatus.ErrFromStatus(res.Status())
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateObject creates new NeoFS object with given payload data and stores it
|
||||||
|
// in specified container of the NeoFS network using provided Client connection.
|
||||||
|
// The object is created on behalf of provided neofscrypto.Signer, and owned by
|
||||||
|
// the specified user.ID.
|
||||||
|
//
|
||||||
|
// In terms of NeoFS, parameterized neofscrypto.Signer represents object owner,
|
||||||
|
// object signer and request sender. Container SHOULD be public-write or sender
|
||||||
|
// SHOULD have corresponding rights.
|
||||||
|
//
|
||||||
|
// Client connection MUST be opened in advance, see Dial method for details.
|
||||||
|
// Network communication is carried out within a given context, so it MUST NOT
|
||||||
|
// be nil.
|
||||||
|
//
|
||||||
|
// Notice: This API is EXPERIMENTAL and is planned to be replaced/changed in the
|
||||||
|
// future. Be ready to refactor your code regarding imports and call mechanics,
|
||||||
|
// in essence the operation will not change.
|
||||||
|
func CreateObject(ctx context.Context, cli *Client, signer neofscrypto.Signer, cnr cid.ID, owner user.ID, data io.Reader, attributes ...string) (oid.ID, error) {
|
||||||
|
resNetInfo, err := cli.NetworkInfo(ctx, PrmNetworkInfo{})
|
||||||
|
if err != nil {
|
||||||
|
return oid.ID{}, fmt.Errorf("read current network info: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
netInfo := resNetInfo.Info()
|
||||||
|
|
||||||
|
var opts slicer.Options
|
||||||
|
opts.SetObjectPayloadLimit(netInfo.MaxObjectSize())
|
||||||
|
opts.SetCurrentNeoFSEpoch(netInfo.CurrentEpoch())
|
||||||
|
|
||||||
|
s := slicer.New(signer, cnr, owner, &objectWriter{
|
||||||
|
context: ctx,
|
||||||
|
client: cli,
|
||||||
|
}, opts)
|
||||||
|
|
||||||
|
return s.Slice(data, attributes...)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue