[#214] object: Implement Get\Head requests for EC object

Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
This commit is contained in:
Anton Nikiforov 2024-04-22 09:51:20 +03:00
parent 3790142b10
commit 20ab57bf7e
7 changed files with 142 additions and 3 deletions

View file

@ -150,6 +150,9 @@ func (x *ObjectReader) ReadHeader(dst *object.Object) bool {
case *v2object.SplitInfo:
x.err = object.NewSplitInfoError(object.NewSplitInfoFromV2(v))
return false
case *v2object.ECInfo:
x.err = object.NewECInfoError(object.NewECInfoFromV2(v))
return false
case *v2object.GetObjectPartInit:
partInit = v
}
@ -502,6 +505,8 @@ func (c *Client) ObjectHead(ctx context.Context, prm PrmObjectHead) (*ResObjectH
return nil, fmt.Errorf("unexpected header type %T", v)
case *v2object.SplitInfo:
return nil, object.NewSplitInfoError(object.NewSplitInfoFromV2(v))
case *v2object.ECInfo:
return nil, object.NewECInfoError(object.NewECInfoFromV2(v))
case *v2object.HeaderWithSignature:
res.hdr = v
}

2
go.mod
View file

@ -3,7 +3,7 @@ module git.frostfs.info/TrueCloudLab/frostfs-sdk-go
go 1.20
require (
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240327095603-491a47e7fe24
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240422151450-df9b65324a4c
git.frostfs.info/TrueCloudLab/frostfs-contract v0.0.0-20230307110621-19a8ef2d02fb
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0
git.frostfs.info/TrueCloudLab/hrw v1.2.1

4
go.sum
View file

@ -31,8 +31,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240327095603-491a47e7fe24 h1:uIkl0mKWwDICUZTbNWZ38HLYDBI9rMgdAhYQWZ0C9iQ=
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240327095603-491a47e7fe24/go.mod h1:OBDSr+DqV1z4VDouoX3YMleNc4DPBVBWTG3WDT2PK1o=
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240422151450-df9b65324a4c h1:RFDrNsF2e+EJfaB8lZrRRxNjQkLfM09gnEyudvGuc10=
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240422151450-df9b65324a4c/go.mod h1:OBDSr+DqV1z4VDouoX3YMleNc4DPBVBWTG3WDT2PK1o=
git.frostfs.info/TrueCloudLab/frostfs-contract v0.0.0-20230307110621-19a8ef2d02fb h1:S/TrbOOu9qEXZRZ9/Ddw7crnxbBUQLo68PSzQWYrc9M=
git.frostfs.info/TrueCloudLab/frostfs-contract v0.0.0-20230307110621-19a8ef2d02fb/go.mod h1:nkR5gaGeez3Zv2SE7aceP0YwxG2FzIB5cGKpQO2vV2o=
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0 h1:FxqFDhQYYgpe41qsIHVOcdzSVCB8JNSfPG7Uk4r2oSk=

69
object/ecinfo.go Normal file
View file

@ -0,0 +1,69 @@
package object
import (
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
)
type ECChunk object.ECChunk
func (c *ECChunk) SetID(id oid.ID) {
objV2 := new(refs.ObjectID)
id.WriteToV2(objV2)
c.ID = *objV2
}
// ToV2 converts ECChunk to v2 ECChunk message.
//
// Nil ECChunk converts to nil.
func (c *ECChunk) ToV2() *object.ECChunk {
return (*object.ECChunk)(c)
}
func NewECChunkFromV2(v2 *object.ECChunk) *ECChunk {
return (*ECChunk)(v2)
}
type ECInfo object.ECInfo
// NewECInfoFromV2 wraps v2 ECInfo message to ECInfo.
//
// Nil object.ECInfo converts to nil.
func NewECInfoFromV2(v2 *object.ECInfo) *ECInfo {
return (*ECInfo)(v2)
}
// NewECInfo creates and initializes blank ECInfo.
func NewECInfo() *ECInfo {
return NewECInfoFromV2(new(object.ECInfo))
}
// ToV2 converts ECInfo to v2 ECInfo message.
//
// Nil ECInfo converts to nil.
func (s *ECInfo) ToV2() *object.ECInfo {
return (*object.ECInfo)(s)
}
func (s *ECInfo) Marshal() ([]byte, error) {
return (*object.ECInfo)(s).StableMarshal(nil), nil
}
func (s *ECInfo) Unmarshal(data []byte) error {
return (*object.ECInfo)(s).Unmarshal(data)
}
// MarshalJSON implements json.Marshaler.
func (s *ECInfo) MarshalJSON() ([]byte, error) {
return (*object.ECInfo)(s).MarshalJSON()
}
// UnmarshalJSON implements json.Unmarshaler.
func (s *ECInfo) UnmarshalJSON(data []byte) error {
return (*object.ECInfo)(s).UnmarshalJSON(data)
}
func (s *ECInfo) AddChunk(chunk ECChunk) {
s.Chunks = append(s.Chunks, *chunk.ToV2())
}

View file

@ -17,3 +17,21 @@ func (s *SplitInfoError) SplitInfo() *SplitInfo {
func NewSplitInfoError(v *SplitInfo) *SplitInfoError {
return &SplitInfoError{si: v}
}
type ECInfoError struct {
ei *ECInfo
}
const ecInfoErrorMsg = "object not found, ec info has been provided"
func (e *ECInfoError) Error() string {
return ecInfoErrorMsg
}
func (e *ECInfoError) ECInfo() *ECInfo {
return e.ei
}
func NewECInfoError(v *ECInfo) *ECInfoError {
return &ECInfoError{ei: v}
}

View file

@ -1,9 +1,12 @@
package object_test
import (
"crypto/rand"
"errors"
"testing"
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
"github.com/stretchr/testify/require"
)
@ -31,3 +34,43 @@ func generateSplitInfo() *object.SplitInfo {
return si
}
func TestNewECInfoError(t *testing.T) {
var (
ei = generateECInfo()
err error = object.NewECInfoError(ei)
expectedErr *object.ECInfoError
)
require.True(t, errors.As(err, &expectedErr))
eiErr, ok := err.(*object.ECInfoError)
require.True(t, ok)
require.Equal(t, ei, eiErr.ECInfo())
}
func generateECInfo() *object.ECInfo {
ei := object.NewECInfo()
ei.Chunks = append(ei.Chunks, objectV2.ECChunk{
ID: generateV2ID(),
Index: 0,
Total: 2,
})
ei.Chunks = append(ei.Chunks, objectV2.ECChunk{
ID: generateV2ID(),
Index: 1,
Total: 2,
})
return ei
}
func generateV2ID() refs.ObjectID {
var buf [32]byte
_, _ = rand.Read(buf[:])
var id refs.ObjectID
id.SetValue(buf[:])
return id
}

View file

@ -1182,6 +1182,10 @@ func needCountError(ctx context.Context, err error) bool {
if errors.As(err, &siErr) {
return false
}
var eiErr *object.ECInfoError
if errors.As(err, &eiErr) {
return false
}
if errors.Is(ctx.Err(), context.Canceled) {
return false