2020-12-02 23:45:25 +00:00
|
|
|
package getsvc
|
|
|
|
|
|
|
|
import (
|
2021-01-11 13:50:49 +00:00
|
|
|
"io"
|
2020-12-02 23:45:25 +00:00
|
|
|
|
|
|
|
"github.com/nspcc-dev/neofs-api-go/pkg/client"
|
|
|
|
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
|
2021-06-21 14:13:08 +00:00
|
|
|
coreclient "github.com/nspcc-dev/neofs-node/pkg/core/client"
|
2021-01-12 14:55:02 +00:00
|
|
|
"github.com/nspcc-dev/neofs-node/pkg/core/netmap"
|
2020-12-02 23:45:25 +00:00
|
|
|
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
|
|
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/engine"
|
2021-05-20 15:17:16 +00:00
|
|
|
"github.com/nspcc-dev/neofs-node/pkg/network"
|
2020-12-02 23:45:25 +00:00
|
|
|
)
|
|
|
|
|
2020-12-09 10:32:33 +00:00
|
|
|
type SimpleObjectWriter struct {
|
2020-12-02 23:45:25 +00:00
|
|
|
obj *object.RawObject
|
|
|
|
|
2020-12-07 17:49:47 +00:00
|
|
|
pld []byte
|
2020-12-02 23:45:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type clientCacheWrapper struct {
|
2021-03-23 18:40:36 +00:00
|
|
|
cache ClientConstructor
|
2020-12-02 23:45:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type clientWrapper struct {
|
2021-06-21 14:13:08 +00:00
|
|
|
client coreclient.Client
|
2020-12-02 23:45:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type storageEngineWrapper struct {
|
|
|
|
engine *engine.StorageEngine
|
|
|
|
}
|
|
|
|
|
2020-12-09 10:32:33 +00:00
|
|
|
type partWriter struct {
|
2020-12-07 17:49:47 +00:00
|
|
|
ObjectWriter
|
|
|
|
|
2020-12-09 10:32:33 +00:00
|
|
|
headWriter HeaderWriter
|
|
|
|
|
2020-12-07 17:49:47 +00:00
|
|
|
chunkWriter ChunkWriter
|
|
|
|
}
|
|
|
|
|
2020-12-08 16:18:24 +00:00
|
|
|
type hasherWrapper struct {
|
2021-01-11 13:50:49 +00:00
|
|
|
hash io.Writer
|
2020-12-08 16:18:24 +00:00
|
|
|
}
|
|
|
|
|
2021-01-12 14:55:02 +00:00
|
|
|
type nmSrcWrapper struct {
|
|
|
|
nmSrc netmap.Source
|
|
|
|
}
|
|
|
|
|
2020-12-09 10:32:33 +00:00
|
|
|
func NewSimpleObjectWriter() *SimpleObjectWriter {
|
|
|
|
return &SimpleObjectWriter{
|
2020-12-07 17:49:47 +00:00
|
|
|
obj: object.NewRaw(),
|
|
|
|
}
|
2020-12-02 23:45:25 +00:00
|
|
|
}
|
|
|
|
|
2020-12-09 10:32:33 +00:00
|
|
|
func (s *SimpleObjectWriter) WriteHeader(obj *object.Object) error {
|
2020-12-02 23:45:25 +00:00
|
|
|
s.obj = object.NewRawFromObject(obj)
|
|
|
|
|
2020-12-07 17:49:47 +00:00
|
|
|
s.pld = make([]byte, 0, obj.PayloadSize())
|
2020-12-02 23:45:25 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-12-09 10:32:33 +00:00
|
|
|
func (s *SimpleObjectWriter) WriteChunk(p []byte) error {
|
2020-12-07 17:49:47 +00:00
|
|
|
s.pld = append(s.pld, p...)
|
2020-12-02 23:45:25 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-12-09 10:32:33 +00:00
|
|
|
func (s *SimpleObjectWriter) Object() *object.Object {
|
2020-12-07 17:49:47 +00:00
|
|
|
if len(s.pld) > 0 {
|
|
|
|
s.obj.SetPayload(s.pld)
|
2020-12-02 23:45:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return s.obj.Object()
|
|
|
|
}
|
|
|
|
|
2021-06-18 06:00:21 +00:00
|
|
|
func (c *clientCacheWrapper) get(addr network.Address) (getClient, error) {
|
2021-03-13 15:22:24 +00:00
|
|
|
clt, err := c.cache.Get(addr)
|
2020-12-02 23:45:25 +00:00
|
|
|
|
|
|
|
return &clientWrapper{
|
|
|
|
client: clt,
|
|
|
|
}, err
|
|
|
|
}
|
|
|
|
|
2021-06-21 14:13:08 +00:00
|
|
|
func (c *clientWrapper) getObject(exec *execCtx, addr network.Address) (*objectSDK.Object, error) {
|
2021-05-20 08:04:20 +00:00
|
|
|
if !exec.assembling && exec.prm.forwarder != nil {
|
2021-06-21 14:13:08 +00:00
|
|
|
return exec.prm.forwarder(addr, c.client)
|
2021-04-29 12:18:29 +00:00
|
|
|
}
|
|
|
|
|
2020-12-09 10:32:33 +00:00
|
|
|
if exec.headOnly() {
|
|
|
|
return c.client.GetObjectHeader(exec.context(),
|
|
|
|
new(client.ObjectHeaderParams).
|
|
|
|
WithAddress(exec.address()).
|
|
|
|
WithRawFlag(exec.isRaw()),
|
|
|
|
exec.callOptions()...,
|
|
|
|
)
|
|
|
|
}
|
2020-12-02 23:45:25 +00:00
|
|
|
// we don't specify payload writer because we accumulate
|
|
|
|
// the object locally (even huge).
|
2020-12-09 10:32:33 +00:00
|
|
|
if rng := exec.ctxRange(); rng != nil {
|
|
|
|
data, err := c.client.ObjectPayloadRangeData(exec.context(),
|
2020-12-07 17:49:47 +00:00
|
|
|
new(client.RangeDataParams).
|
2020-12-09 10:32:33 +00:00
|
|
|
WithAddress(exec.address()).
|
|
|
|
WithRange(rng).
|
|
|
|
WithRaw(exec.isRaw()),
|
|
|
|
exec.callOptions()...,
|
2020-12-07 17:49:47 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return payloadOnlyObject(data), nil
|
|
|
|
}
|
2021-01-11 15:21:06 +00:00
|
|
|
|
|
|
|
return c.client.GetObject(exec.context(),
|
|
|
|
exec.remotePrm(),
|
|
|
|
exec.callOptions()...,
|
|
|
|
)
|
2020-12-02 23:45:25 +00:00
|
|
|
}
|
|
|
|
|
2020-12-09 10:32:33 +00:00
|
|
|
func (e *storageEngineWrapper) get(exec *execCtx) (*object.Object, error) {
|
|
|
|
if exec.headOnly() {
|
|
|
|
r, err := e.engine.Head(new(engine.HeadPrm).
|
|
|
|
WithAddress(exec.address()).
|
|
|
|
WithRaw(exec.isRaw()),
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return r.Header(), nil
|
|
|
|
} else if rng := exec.ctxRange(); rng != nil {
|
2020-12-07 17:49:47 +00:00
|
|
|
r, err := e.engine.GetRange(new(engine.RngPrm).
|
2020-12-09 10:32:33 +00:00
|
|
|
WithAddress(exec.address()).
|
|
|
|
WithPayloadRange(rng),
|
2020-12-07 17:49:47 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return r.Object(), nil
|
|
|
|
} else {
|
|
|
|
r, err := e.engine.Get(new(engine.GetPrm).
|
2020-12-09 10:32:33 +00:00
|
|
|
WithAddress(exec.address()),
|
2020-12-07 17:49:47 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return r.Object(), nil
|
2020-12-02 23:45:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-09 10:32:33 +00:00
|
|
|
func (w *partWriter) WriteChunk(p []byte) error {
|
|
|
|
return w.chunkWriter.WriteChunk(p)
|
2020-12-02 23:45:25 +00:00
|
|
|
}
|
2020-12-07 17:49:47 +00:00
|
|
|
|
2020-12-09 10:32:33 +00:00
|
|
|
func (w *partWriter) WriteHeader(o *object.Object) error {
|
|
|
|
return w.headWriter.WriteHeader(o)
|
2020-12-07 17:49:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func payloadOnlyObject(payload []byte) *objectSDK.Object {
|
|
|
|
rawObj := object.NewRaw()
|
|
|
|
rawObj.SetPayload(payload)
|
|
|
|
|
|
|
|
return rawObj.Object().SDK()
|
|
|
|
}
|
2020-12-08 16:18:24 +00:00
|
|
|
|
|
|
|
func (h *hasherWrapper) WriteChunk(p []byte) error {
|
|
|
|
_, err := h.hash.Write(p)
|
|
|
|
return err
|
|
|
|
}
|
2021-01-12 14:55:02 +00:00
|
|
|
|
|
|
|
func (n *nmSrcWrapper) currentEpoch() (uint64, error) {
|
|
|
|
return n.nmSrc.Epoch()
|
|
|
|
}
|