forked from TrueCloudLab/frostfs-s3-gw
[#236] api: Create info.go for basic structs
Moved BucketInfo and ObjectInfo from layer and handler to api Signed-off-by: Angira Kekteeva <kira@nspcc.ru>
This commit is contained in:
parent
345dafb29d
commit
239742f413
17 changed files with 231 additions and 229 deletions
34
api/cache/buckets.go
vendored
34
api/cache/buckets.go
vendored
|
@ -4,27 +4,17 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/bluele/gcache"
|
||||
cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id"
|
||||
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||
)
|
||||
|
||||
type (
|
||||
// BucketCache provides interface for lru cache for objects.
|
||||
BucketCache interface {
|
||||
Get(key string) *BucketInfo
|
||||
Put(bkt *BucketInfo) error
|
||||
Get(key string) *api.BucketInfo
|
||||
Put(bkt *api.BucketInfo) error
|
||||
Delete(key string) bool
|
||||
}
|
||||
|
||||
// BucketInfo stores basic bucket data.
|
||||
BucketInfo struct {
|
||||
Name string
|
||||
CID *cid.ID
|
||||
Owner *owner.ID
|
||||
Created time.Time
|
||||
BasicACL uint32
|
||||
}
|
||||
|
||||
// GetBucketCache contains cache with objects and lifetime of cache entries.
|
||||
GetBucketCache struct {
|
||||
cache gcache.Cache
|
||||
|
@ -40,13 +30,13 @@ func NewBucketCache(cacheSize int, lifetime time.Duration) *GetBucketCache {
|
|||
}
|
||||
|
||||
// Get returns cached object.
|
||||
func (o *GetBucketCache) Get(key string) *BucketInfo {
|
||||
func (o *GetBucketCache) Get(key string) *api.BucketInfo {
|
||||
entry, err := o.cache.Get(key)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
result, ok := entry.(*BucketInfo)
|
||||
result, ok := entry.(*api.BucketInfo)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
@ -55,7 +45,7 @@ func (o *GetBucketCache) Get(key string) *BucketInfo {
|
|||
}
|
||||
|
||||
// Put puts an object to cache.
|
||||
func (o *GetBucketCache) Put(bkt *BucketInfo) error {
|
||||
func (o *GetBucketCache) Put(bkt *api.BucketInfo) error {
|
||||
return o.cache.SetWithExpire(bkt.Name, bkt, o.lifetime)
|
||||
}
|
||||
|
||||
|
@ -63,15 +53,3 @@ func (o *GetBucketCache) Put(bkt *BucketInfo) error {
|
|||
func (o *GetBucketCache) Delete(key string) bool {
|
||||
return o.cache.Remove(key)
|
||||
}
|
||||
|
||||
const bktVersionSettingsObject = ".s3-versioning-settings"
|
||||
|
||||
// SettingsObjectName is system name for bucket settings file.
|
||||
func (b *BucketInfo) SettingsObjectName() string {
|
||||
return bktVersionSettingsObject
|
||||
}
|
||||
|
||||
// SystemObjectKey is key to use in SystemCache.
|
||||
func (b *BucketInfo) SystemObjectKey(obj string) string {
|
||||
return b.Name + obj
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
"github.com/nspcc-dev/neofs-api-go/pkg/object"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/acl"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/cache"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/errors"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/layer"
|
||||
)
|
||||
|
@ -300,7 +299,7 @@ func (h *handler) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request)
|
|||
}
|
||||
}
|
||||
|
||||
func checkOwner(info *cache.BucketInfo, owner string) error {
|
||||
func checkOwner(info *api.BucketInfo, owner string) error {
|
||||
if owner == "" {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ func path2BucketObject(path string) (bucket, prefix string) {
|
|||
func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
err error
|
||||
info *layer.ObjectInfo
|
||||
info *api.ObjectInfo
|
||||
metadata map[string]string
|
||||
|
||||
reqInfo = api.GetReqInfo(r.Context())
|
||||
|
@ -118,7 +118,7 @@ func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
h.log.Info("object is copied",
|
||||
zap.String("bucket", info.Bucket),
|
||||
zap.String("object", info.Name),
|
||||
zap.Stringer("object_id", info.ID()))
|
||||
zap.Stringer("object_id", info.ID))
|
||||
}
|
||||
|
||||
func parseCopyObjectArgs(headers http.Header) (*copyObjectArgs, error) {
|
||||
|
|
|
@ -65,14 +65,14 @@ func fetchRangeHeader(headers http.Header, fullSize uint64) (*layer.RangeParams,
|
|||
return &layer.RangeParams{Start: start, End: end}, nil
|
||||
}
|
||||
|
||||
func writeHeaders(h http.Header, info *layer.ObjectInfo, tagSetLength int) {
|
||||
func writeHeaders(h http.Header, info *api.ObjectInfo, tagSetLength int) {
|
||||
if len(info.ContentType) > 0 {
|
||||
h.Set(api.ContentType, info.ContentType)
|
||||
}
|
||||
h.Set(api.LastModified, info.Created.UTC().Format(http.TimeFormat))
|
||||
h.Set(api.ContentLength, strconv.FormatInt(info.Size, 10))
|
||||
h.Set(api.ETag, info.HashSum)
|
||||
h.Set(api.AmzVersionID, info.ID().String())
|
||||
h.Set(api.AmzVersionID, info.ID.String())
|
||||
h.Set(api.AmzTaggingCount, strconv.Itoa(tagSetLength))
|
||||
|
||||
for key, val := range info.Headers {
|
||||
|
@ -83,7 +83,7 @@ func writeHeaders(h http.Header, info *layer.ObjectInfo, tagSetLength int) {
|
|||
func (h *handler) GetObjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
err error
|
||||
info *layer.ObjectInfo
|
||||
info *api.ObjectInfo
|
||||
params *layer.RangeParams
|
||||
|
||||
reqInfo = api.GetReqInfo(r.Context())
|
||||
|
@ -143,7 +143,7 @@ func (h *handler) GetObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
func checkPreconditions(info *layer.ObjectInfo, args *conditionalArgs) error {
|
||||
func checkPreconditions(info *api.ObjectInfo, args *conditionalArgs) error {
|
||||
if len(args.IfMatch) > 0 && args.IfMatch != info.HashSum {
|
||||
return errors.GetAPIError(errors.ErrPreconditionFailed)
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/errors"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/layer"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -45,8 +46,8 @@ func TestFetchRangeHeader(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func newInfo(etag string, created time.Time) *layer.ObjectInfo {
|
||||
return &layer.ObjectInfo{
|
||||
func newInfo(etag string, created time.Time) *api.ObjectInfo {
|
||||
return &api.ObjectInfo{
|
||||
HashSum: etag,
|
||||
Created: created,
|
||||
}
|
||||
|
@ -60,13 +61,13 @@ func TestPreconditions(t *testing.T) {
|
|||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
info *layer.ObjectInfo
|
||||
info *api.ObjectInfo
|
||||
args *conditionalArgs
|
||||
expected error
|
||||
}{
|
||||
{
|
||||
name: "no conditions",
|
||||
info: new(layer.ObjectInfo),
|
||||
info: new(api.ObjectInfo),
|
||||
args: new(conditionalArgs),
|
||||
expected: nil,
|
||||
},
|
||||
|
|
|
@ -27,7 +27,7 @@ func getRangeToDetectContentType(maxSize int64) *layer.RangeParams {
|
|||
func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
err error
|
||||
info *layer.ObjectInfo
|
||||
info *api.ObjectInfo
|
||||
|
||||
reqInfo = api.GetReqInfo(r.Context())
|
||||
)
|
||||
|
@ -62,7 +62,7 @@ func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
VersionID: reqInfo.URL.Query().Get(api.QueryVersionID),
|
||||
}
|
||||
if err = h.obj.GetObject(r.Context(), getParams); err != nil {
|
||||
h.logAndSendError(w, "could not get object", reqInfo, err, zap.Stringer("oid", info.ID()))
|
||||
h.logAndSendError(w, "could not get object", reqInfo, err, zap.Stringer("oid", info.ID))
|
||||
return
|
||||
}
|
||||
info.ContentType = http.DetectContentType(buffer.Bytes())
|
||||
|
|
|
@ -183,11 +183,11 @@ func fillPrefixes(src []string, encode string) []CommonPrefix {
|
|||
return dst
|
||||
}
|
||||
|
||||
func fillContentsWithOwner(src []*layer.ObjectInfo, encode string) []Object {
|
||||
func fillContentsWithOwner(src []*api.ObjectInfo, encode string) []Object {
|
||||
return fillContents(src, encode, true)
|
||||
}
|
||||
|
||||
func fillContents(src []*layer.ObjectInfo, encode string, fetchOwner bool) []Object {
|
||||
func fillContents(src []*api.ObjectInfo, encode string, fetchOwner bool) []Object {
|
||||
var dst []Object
|
||||
for _, obj := range src {
|
||||
res := Object{
|
||||
|
|
65
api/info.go
Normal file
65
api/info.go
Normal file
|
@ -0,0 +1,65 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id"
|
||||
"github.com/nspcc-dev/neofs-api-go/pkg/object"
|
||||
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
||||
)
|
||||
|
||||
const bktVersionSettingsObject = ".s3-versioning-settings"
|
||||
|
||||
type (
|
||||
// BucketInfo stores basic bucket data.
|
||||
BucketInfo struct {
|
||||
Name string
|
||||
CID *cid.ID
|
||||
Owner *owner.ID
|
||||
Created time.Time
|
||||
BasicACL uint32
|
||||
}
|
||||
|
||||
// ObjectInfo holds S3 object data.
|
||||
ObjectInfo struct {
|
||||
ID *object.ID
|
||||
CID *cid.ID
|
||||
IsDir bool
|
||||
|
||||
Bucket string
|
||||
Name string
|
||||
Size int64
|
||||
ContentType string
|
||||
Created time.Time
|
||||
CreationEpoch uint64
|
||||
HashSum string
|
||||
Owner *owner.ID
|
||||
Headers map[string]string
|
||||
}
|
||||
)
|
||||
|
||||
// SettingsObjectName is system name for bucket settings file.
|
||||
func (b *BucketInfo) SettingsObjectName() string { return bktVersionSettingsObject }
|
||||
|
||||
// SystemObjectKey is key to use in SystemCache.
|
||||
func (b *BucketInfo) SystemObjectKey(obj string) string {
|
||||
return b.Name + obj
|
||||
}
|
||||
|
||||
// Version returns object version from ObjectInfo.
|
||||
func (o *ObjectInfo) Version() string { return o.ID.String() }
|
||||
|
||||
// NiceName returns object name for cache.
|
||||
func (o *ObjectInfo) NiceName() string { return o.Bucket + "/" + o.Name }
|
||||
|
||||
// Address returns object address.
|
||||
func (o *ObjectInfo) Address() *object.Address {
|
||||
address := object.NewAddress()
|
||||
address.SetContainerID(o.CID)
|
||||
address.SetObjectID(o.ID)
|
||||
|
||||
return address
|
||||
}
|
||||
|
||||
// TagsObject returns name of system object for tags.
|
||||
func (o *ObjectInfo) TagsObject() string { return ".tagset." + o.Name + "." + o.Version() }
|
|
@ -12,7 +12,6 @@ import (
|
|||
"github.com/nspcc-dev/neofs-api-go/pkg/container"
|
||||
cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/cache"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/errors"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/pool"
|
||||
"go.uber.org/zap"
|
||||
|
@ -21,19 +20,19 @@ import (
|
|||
type (
|
||||
// BucketACL extends BucketInfo by eacl.Table.
|
||||
BucketACL struct {
|
||||
Info *cache.BucketInfo
|
||||
Info *api.BucketInfo
|
||||
EACL *eacl.Table
|
||||
}
|
||||
)
|
||||
|
||||
func (n *layer) containerInfo(ctx context.Context, cid *cid.ID) (*cache.BucketInfo, error) {
|
||||
func (n *layer) containerInfo(ctx context.Context, cid *cid.ID) (*api.BucketInfo, error) {
|
||||
var (
|
||||
err error
|
||||
res *container.Container
|
||||
rid = api.GetRequestID(ctx)
|
||||
bearerOpt = n.BearerOpt(ctx)
|
||||
|
||||
info = &cache.BucketInfo{
|
||||
info = &api.BucketInfo{
|
||||
CID: cid,
|
||||
Name: cid.String(),
|
||||
}
|
||||
|
@ -84,7 +83,7 @@ func (n *layer) containerInfo(ctx context.Context, cid *cid.ID) (*cache.BucketIn
|
|||
return info, nil
|
||||
}
|
||||
|
||||
func (n *layer) containerList(ctx context.Context) ([]*cache.BucketInfo, error) {
|
||||
func (n *layer) containerList(ctx context.Context) ([]*api.BucketInfo, error) {
|
||||
var (
|
||||
err error
|
||||
own = n.Owner(ctx)
|
||||
|
@ -100,7 +99,7 @@ func (n *layer) containerList(ctx context.Context) ([]*cache.BucketInfo, error)
|
|||
return nil, err
|
||||
}
|
||||
|
||||
list := make([]*cache.BucketInfo, 0, len(res))
|
||||
list := make([]*api.BucketInfo, 0, len(res))
|
||||
for _, cid := range res {
|
||||
info, err := n.containerInfo(ctx, cid)
|
||||
if err != nil {
|
||||
|
@ -118,7 +117,7 @@ func (n *layer) containerList(ctx context.Context) ([]*cache.BucketInfo, error)
|
|||
|
||||
func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*cid.ID, error) {
|
||||
var err error
|
||||
bktInfo := &cache.BucketInfo{
|
||||
bktInfo := &api.BucketInfo{
|
||||
Name: p.Name,
|
||||
Owner: n.Owner(ctx),
|
||||
Created: time.Now(),
|
||||
|
|
|
@ -54,7 +54,7 @@ type (
|
|||
// GetObjectParams stores object get request parameters.
|
||||
GetObjectParams struct {
|
||||
Range *RangeParams
|
||||
ObjectInfo *ObjectInfo
|
||||
ObjectInfo *api.ObjectInfo
|
||||
Offset int64
|
||||
Length int64
|
||||
Writer io.Writer
|
||||
|
@ -96,7 +96,7 @@ type (
|
|||
|
||||
// CopyObjectParams stores object copy request parameters.
|
||||
CopyObjectParams struct {
|
||||
SrcObject *ObjectInfo
|
||||
SrcObject *api.ObjectInfo
|
||||
DstBucket string
|
||||
DstObject string
|
||||
SrcSize int64
|
||||
|
@ -138,7 +138,7 @@ type (
|
|||
|
||||
// PutTaggingParams stores tag set params.
|
||||
PutTaggingParams struct {
|
||||
ObjectInfo *ObjectInfo
|
||||
ObjectInfo *api.ObjectInfo
|
||||
TagSet map[string]string
|
||||
}
|
||||
|
||||
|
@ -151,33 +151,33 @@ type (
|
|||
Client interface {
|
||||
NeoFS
|
||||
|
||||
PutBucketVersioning(ctx context.Context, p *PutVersioningParams) (*ObjectInfo, error)
|
||||
PutBucketVersioning(ctx context.Context, p *PutVersioningParams) (*api.ObjectInfo, error)
|
||||
GetBucketVersioning(ctx context.Context, name string) (*BucketSettings, error)
|
||||
|
||||
ListBuckets(ctx context.Context) ([]*cache.BucketInfo, error)
|
||||
GetBucketInfo(ctx context.Context, name string) (*cache.BucketInfo, error)
|
||||
ListBuckets(ctx context.Context) ([]*api.BucketInfo, error)
|
||||
GetBucketInfo(ctx context.Context, name string) (*api.BucketInfo, error)
|
||||
GetBucketACL(ctx context.Context, name string) (*BucketACL, error)
|
||||
PutBucketACL(ctx context.Context, p *PutBucketACLParams) error
|
||||
CreateBucket(ctx context.Context, p *CreateBucketParams) (*cid.ID, error)
|
||||
DeleteBucket(ctx context.Context, p *DeleteBucketParams) error
|
||||
|
||||
GetObject(ctx context.Context, p *GetObjectParams) error
|
||||
GetObjectInfo(ctx context.Context, p *HeadObjectParams) (*ObjectInfo, error)
|
||||
GetObjectTagging(ctx context.Context, p *ObjectInfo) (map[string]string, error)
|
||||
GetObjectInfo(ctx context.Context, p *HeadObjectParams) (*api.ObjectInfo, error)
|
||||
GetObjectTagging(ctx context.Context, p *api.ObjectInfo) (map[string]string, error)
|
||||
GetBucketTagging(ctx context.Context, bucket string) (map[string]string, error)
|
||||
|
||||
PutObject(ctx context.Context, p *PutObjectParams) (*ObjectInfo, error)
|
||||
PutObject(ctx context.Context, p *PutObjectParams) (*api.ObjectInfo, error)
|
||||
PutObjectTagging(ctx context.Context, p *PutTaggingParams) error
|
||||
PutBucketTagging(ctx context.Context, bucket string, tagSet map[string]string) error
|
||||
|
||||
CopyObject(ctx context.Context, p *CopyObjectParams) (*ObjectInfo, error)
|
||||
CopyObject(ctx context.Context, p *CopyObjectParams) (*api.ObjectInfo, error)
|
||||
|
||||
ListObjectsV1(ctx context.Context, p *ListObjectsParamsV1) (*ListObjectsInfoV1, error)
|
||||
ListObjectsV2(ctx context.Context, p *ListObjectsParamsV2) (*ListObjectsInfoV2, error)
|
||||
ListObjectVersions(ctx context.Context, p *ListObjectVersionsParams) (*ListObjectVersionsInfo, error)
|
||||
|
||||
DeleteObjects(ctx context.Context, bucket string, objects []*VersionedObject) []error
|
||||
DeleteObjectTagging(ctx context.Context, p *ObjectInfo) error
|
||||
DeleteObjectTagging(ctx context.Context, p *api.ObjectInfo) error
|
||||
DeleteBucketTagging(ctx context.Context, bucket string) error
|
||||
}
|
||||
)
|
||||
|
@ -240,7 +240,7 @@ func (n *layer) Get(ctx context.Context, address *object.Address) (*object.Objec
|
|||
}
|
||||
|
||||
// GetBucketInfo returns bucket info by name.
|
||||
func (n *layer) GetBucketInfo(ctx context.Context, name string) (*cache.BucketInfo, error) {
|
||||
func (n *layer) GetBucketInfo(ctx context.Context, name string) (*api.BucketInfo, error) {
|
||||
name, err := url.QueryUnescape(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -298,7 +298,7 @@ func (n *layer) PutBucketACL(ctx context.Context, param *PutBucketACLParams) err
|
|||
|
||||
// ListBuckets returns all user containers. Name of the bucket is a container
|
||||
// id. Timestamp is omitted since it is not saved in neofs container.
|
||||
func (n *layer) ListBuckets(ctx context.Context) ([]*cache.BucketInfo, error) {
|
||||
func (n *layer) ListBuckets(ctx context.Context) ([]*api.BucketInfo, error) {
|
||||
return n.containerList(ctx)
|
||||
}
|
||||
|
||||
|
@ -308,8 +308,8 @@ func (n *layer) GetObject(ctx context.Context, p *GetObjectParams) error {
|
|||
|
||||
params := &getParams{
|
||||
Writer: p.Writer,
|
||||
cid: p.ObjectInfo.CID(),
|
||||
oid: p.ObjectInfo.ID(),
|
||||
cid: p.ObjectInfo.CID,
|
||||
oid: p.ObjectInfo.ID,
|
||||
offset: p.Offset,
|
||||
length: p.Length,
|
||||
}
|
||||
|
@ -327,14 +327,14 @@ func (n *layer) GetObject(ctx context.Context, p *GetObjectParams) error {
|
|||
|
||||
if err != nil {
|
||||
n.objCache.Delete(p.ObjectInfo.Address())
|
||||
return fmt.Errorf("couldn't get object, cid: %s : %w", p.ObjectInfo.CID(), err)
|
||||
return fmt.Errorf("couldn't get object, cid: %s : %w", p.ObjectInfo.CID, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetObjectInfo returns meta information about the object.
|
||||
func (n *layer) GetObjectInfo(ctx context.Context, p *HeadObjectParams) (*ObjectInfo, error) {
|
||||
func (n *layer) GetObjectInfo(ctx context.Context, p *HeadObjectParams) (*api.ObjectInfo, error) {
|
||||
bkt, err := n.GetBucketInfo(ctx, p.Bucket)
|
||||
if err != nil {
|
||||
n.log.Error("could not fetch bucket info", zap.Error(err))
|
||||
|
@ -349,7 +349,7 @@ func (n *layer) GetObjectInfo(ctx context.Context, p *HeadObjectParams) (*Object
|
|||
}
|
||||
|
||||
// PutObject into storage.
|
||||
func (n *layer) PutObject(ctx context.Context, p *PutObjectParams) (*ObjectInfo, error) {
|
||||
func (n *layer) PutObject(ctx context.Context, p *PutObjectParams) (*api.ObjectInfo, error) {
|
||||
bkt, err := n.GetBucketInfo(ctx, p.Bucket)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -359,10 +359,10 @@ func (n *layer) PutObject(ctx context.Context, p *PutObjectParams) (*ObjectInfo,
|
|||
}
|
||||
|
||||
// GetObjectTagging from storage.
|
||||
func (n *layer) GetObjectTagging(ctx context.Context, oi *ObjectInfo) (map[string]string, error) {
|
||||
bktInfo := &cache.BucketInfo{
|
||||
func (n *layer) GetObjectTagging(ctx context.Context, oi *api.ObjectInfo) (map[string]string, error) {
|
||||
bktInfo := &api.BucketInfo{
|
||||
Name: oi.Bucket,
|
||||
CID: oi.CID(),
|
||||
CID: oi.CID,
|
||||
Owner: oi.Owner,
|
||||
}
|
||||
|
||||
|
@ -389,7 +389,7 @@ func (n *layer) GetBucketTagging(ctx context.Context, bucketName string) (map[st
|
|||
return formTagSet(objInfo), nil
|
||||
}
|
||||
|
||||
func formTagSet(objInfo *ObjectInfo) map[string]string {
|
||||
func formTagSet(objInfo *api.ObjectInfo) map[string]string {
|
||||
var tagSet map[string]string
|
||||
if objInfo != nil {
|
||||
tagSet = make(map[string]string, len(objInfo.Headers))
|
||||
|
@ -407,9 +407,9 @@ func formTagSet(objInfo *ObjectInfo) map[string]string {
|
|||
|
||||
// PutObjectTagging into storage.
|
||||
func (n *layer) PutObjectTagging(ctx context.Context, p *PutTaggingParams) error {
|
||||
bktInfo := &cache.BucketInfo{
|
||||
bktInfo := &api.BucketInfo{
|
||||
Name: p.ObjectInfo.Bucket,
|
||||
CID: p.ObjectInfo.CID(),
|
||||
CID: p.ObjectInfo.CID,
|
||||
Owner: p.ObjectInfo.Owner,
|
||||
}
|
||||
|
||||
|
@ -435,7 +435,7 @@ func (n *layer) PutBucketTagging(ctx context.Context, bucketName string, tagSet
|
|||
}
|
||||
|
||||
// DeleteObjectTagging from storage.
|
||||
func (n *layer) DeleteObjectTagging(ctx context.Context, p *ObjectInfo) error {
|
||||
func (n *layer) DeleteObjectTagging(ctx context.Context, p *api.ObjectInfo) error {
|
||||
bktInfo, err := n.GetBucketInfo(ctx, p.Bucket)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -443,7 +443,7 @@ func (n *layer) DeleteObjectTagging(ctx context.Context, p *ObjectInfo) error {
|
|||
return n.deleteSystemObject(ctx, bktInfo, p.TagsObject())
|
||||
}
|
||||
|
||||
func (n *layer) deleteSystemObject(ctx context.Context, bktInfo *cache.BucketInfo, name string) error {
|
||||
func (n *layer) deleteSystemObject(ctx context.Context, bktInfo *api.BucketInfo, name string) error {
|
||||
var oid *object.ID
|
||||
if meta := n.systemCache.Get(bktInfo.SystemObjectKey(name)); meta != nil {
|
||||
oid = meta.ID()
|
||||
|
@ -472,7 +472,7 @@ func (n *layer) DeleteBucketTagging(ctx context.Context, bucketName string) erro
|
|||
return n.deleteSystemObject(ctx, bktInfo, formBucketTagObjectName(bucketName))
|
||||
}
|
||||
|
||||
func (n *layer) putSystemObject(ctx context.Context, bktInfo *cache.BucketInfo, objName string, metadata map[string]string, prefix string) (*object.Object, error) {
|
||||
func (n *layer) putSystemObject(ctx context.Context, bktInfo *api.BucketInfo, objName string, metadata map[string]string, prefix string) (*object.Object, error) {
|
||||
var (
|
||||
err error
|
||||
oldOID *object.ID
|
||||
|
@ -539,7 +539,7 @@ func (n *layer) putSystemObject(ctx context.Context, bktInfo *cache.BucketInfo,
|
|||
return meta, nil
|
||||
}
|
||||
|
||||
func (n *layer) getSystemObject(ctx context.Context, bkt *cache.BucketInfo, objName string) (*ObjectInfo, error) {
|
||||
func (n *layer) getSystemObject(ctx context.Context, bkt *api.BucketInfo, objName string) (*api.ObjectInfo, error) {
|
||||
if meta := n.systemCache.Get(bkt.SystemObjectKey(objName)); meta != nil {
|
||||
return objInfoFromMeta(bkt, meta), nil
|
||||
}
|
||||
|
@ -561,7 +561,7 @@ func (n *layer) getSystemObject(ctx context.Context, bkt *cache.BucketInfo, objN
|
|||
}
|
||||
|
||||
// CopyObject from one bucket into another bucket.
|
||||
func (n *layer) CopyObject(ctx context.Context, p *CopyObjectParams) (*ObjectInfo, error) {
|
||||
func (n *layer) CopyObject(ctx context.Context, p *CopyObjectParams) (*api.ObjectInfo, error) {
|
||||
pr, pw := io.Pipe()
|
||||
|
||||
go func() {
|
||||
|
@ -585,7 +585,7 @@ func (n *layer) CopyObject(ctx context.Context, p *CopyObjectParams) (*ObjectInf
|
|||
}
|
||||
|
||||
// DeleteObject removes all objects with passed nice name.
|
||||
func (n *layer) deleteObject(ctx context.Context, bkt *cache.BucketInfo, obj *VersionedObject) error {
|
||||
func (n *layer) deleteObject(ctx context.Context, bkt *api.BucketInfo, obj *VersionedObject) error {
|
||||
var (
|
||||
err error
|
||||
ids []*object.ID
|
||||
|
@ -627,7 +627,7 @@ func (n *layer) deleteObject(ctx context.Context, bkt *cache.BucketInfo, obj *Ve
|
|||
if err = n.objectDelete(ctx, bkt.CID, id); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = n.DeleteObjectTagging(ctx, &ObjectInfo{id: id, Bucket: bkt.Name, Name: obj.Name}); err != nil {
|
||||
if err = n.DeleteObjectTagging(ctx, &api.ObjectInfo{ID: id, Bucket: bkt.Name, Name: obj.Name}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ import (
|
|||
"github.com/nspcc-dev/neofs-api-go/pkg/object"
|
||||
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/cache"
|
||||
apiErrors "github.com/nspcc-dev/neofs-s3-gw/api/errors"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
@ -61,7 +60,7 @@ type (
|
|||
}
|
||||
|
||||
allObjectParams struct {
|
||||
Bucket *cache.BucketInfo
|
||||
Bucket *api.BucketInfo
|
||||
Delimiter string
|
||||
Prefix string
|
||||
}
|
||||
|
@ -128,7 +127,7 @@ func (n *layer) objectRange(ctx context.Context, p *getParams) ([]byte, error) {
|
|||
}
|
||||
|
||||
// objectPut into NeoFS, took payload from io.Reader.
|
||||
func (n *layer) objectPut(ctx context.Context, bkt *cache.BucketInfo, p *PutObjectParams) (*ObjectInfo, error) {
|
||||
func (n *layer) objectPut(ctx context.Context, bkt *api.BucketInfo, p *PutObjectParams) (*api.ObjectInfo, error) {
|
||||
own := n.Owner(ctx)
|
||||
obj, err := url.QueryUnescape(p.Object)
|
||||
if err != nil {
|
||||
|
@ -190,9 +189,9 @@ func (n *layer) objectPut(ctx context.Context, bkt *cache.BucketInfo, p *PutObje
|
|||
}
|
||||
}
|
||||
|
||||
return &ObjectInfo{
|
||||
id: oid,
|
||||
bucketID: bkt.CID,
|
||||
return &api.ObjectInfo{
|
||||
ID: oid,
|
||||
CID: bkt.CID,
|
||||
|
||||
Owner: own,
|
||||
Bucket: p.Bucket,
|
||||
|
@ -264,14 +263,14 @@ func updateCRDT2PSetHeaders(p *PutObjectParams, versions *objectVersions, versio
|
|||
|
||||
if lastVersion := versions.getLast(); lastVersion != nil {
|
||||
p.Header[versionsDelAttr] = versionsDeletedStr + lastVersion.Version()
|
||||
idsToDeleteArr = append(idsToDeleteArr, lastVersion.ID())
|
||||
idsToDeleteArr = append(idsToDeleteArr, lastVersion.ID)
|
||||
} else if len(versionsDeletedStr) != 0 {
|
||||
p.Header[versionsDelAttr] = versionsDeletedStr
|
||||
}
|
||||
|
||||
for _, version := range versions.objects {
|
||||
if contains(versions.delList, version.Version()) {
|
||||
idsToDeleteArr = append(idsToDeleteArr, version.ID())
|
||||
idsToDeleteArr = append(idsToDeleteArr, version.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -279,7 +278,7 @@ func updateCRDT2PSetHeaders(p *PutObjectParams, versions *objectVersions, versio
|
|||
return idsToDeleteArr
|
||||
}
|
||||
|
||||
func (n *layer) headLastVersionIfNotDeleted(ctx context.Context, bkt *cache.BucketInfo, objectName string) (*ObjectInfo, error) {
|
||||
func (n *layer) headLastVersionIfNotDeleted(ctx context.Context, bkt *api.BucketInfo, objectName string) (*api.ObjectInfo, error) {
|
||||
if address := n.namesCache.Get(bkt.Name + "/" + objectName); address != nil {
|
||||
if headInfo := n.objCache.Get(address); headInfo != nil {
|
||||
return objInfoFromMeta(bkt, headInfo), nil
|
||||
|
@ -305,7 +304,7 @@ func (n *layer) headLastVersionIfNotDeleted(ctx context.Context, bkt *cache.Buck
|
|||
return lastVersion, nil
|
||||
}
|
||||
|
||||
func (n *layer) headVersions(ctx context.Context, bkt *cache.BucketInfo, objectName string) (*objectVersions, error) {
|
||||
func (n *layer) headVersions(ctx context.Context, bkt *api.BucketInfo, objectName string) (*objectVersions, error) {
|
||||
ids, err := n.objectSearch(ctx, &findParams{cid: bkt.CID, val: objectName})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -343,7 +342,7 @@ func (n *layer) headVersions(ctx context.Context, bkt *cache.BucketInfo, objectN
|
|||
return versions, nil
|
||||
}
|
||||
|
||||
func (n *layer) headVersion(ctx context.Context, bkt *cache.BucketInfo, versionID string) (*ObjectInfo, error) {
|
||||
func (n *layer) headVersion(ctx context.Context, bkt *api.BucketInfo, versionID string) (*api.ObjectInfo, error) {
|
||||
oid := object.NewID()
|
||||
if err := oid.Parse(versionID); err != nil {
|
||||
return nil, err
|
||||
|
@ -365,9 +364,9 @@ func (n *layer) headVersion(ctx context.Context, bkt *cache.BucketInfo, versionI
|
|||
if err = n.objCache.Put(*meta); err != nil {
|
||||
n.log.Warn("couldn't put obj to object cache",
|
||||
zap.String("bucket name", objInfo.Bucket),
|
||||
zap.Stringer("bucket cid", objInfo.CID()),
|
||||
zap.Stringer("bucket cid", objInfo.CID),
|
||||
zap.String("object name", objInfo.Name),
|
||||
zap.Stringer("object id", objInfo.ID()),
|
||||
zap.Stringer("object id", objInfo.ID),
|
||||
zap.Error(err))
|
||||
}
|
||||
|
||||
|
@ -388,7 +387,7 @@ func (n *layer) ListObjectsV1(ctx context.Context, p *ListObjectsParamsV1) (*Lis
|
|||
var (
|
||||
err error
|
||||
result ListObjectsInfoV1
|
||||
allObjects []*ObjectInfo
|
||||
allObjects []*api.ObjectInfo
|
||||
)
|
||||
|
||||
if p.MaxKeys == 0 {
|
||||
|
@ -423,7 +422,7 @@ func (n *layer) ListObjectsV2(ctx context.Context, p *ListObjectsParamsV2) (*Lis
|
|||
var (
|
||||
err error
|
||||
result ListObjectsInfoV2
|
||||
allObjects []*ObjectInfo
|
||||
allObjects []*api.ObjectInfo
|
||||
)
|
||||
|
||||
if p.MaxKeys == 0 {
|
||||
|
@ -449,7 +448,7 @@ func (n *layer) ListObjectsV2(ctx context.Context, p *ListObjectsParamsV2) (*Lis
|
|||
if len(allObjects) > p.MaxKeys {
|
||||
result.IsTruncated = true
|
||||
allObjects = allObjects[:p.MaxKeys]
|
||||
result.NextContinuationToken = allObjects[len(allObjects)-1].id.String()
|
||||
result.NextContinuationToken = allObjects[len(allObjects)-1].ID.String()
|
||||
}
|
||||
|
||||
result.Prefixes, result.Objects = triageObjects(allObjects)
|
||||
|
@ -457,13 +456,13 @@ func (n *layer) ListObjectsV2(ctx context.Context, p *ListObjectsParamsV2) (*Lis
|
|||
return &result, nil
|
||||
}
|
||||
|
||||
func (n *layer) listSortedObjectsFromNeoFS(ctx context.Context, p allObjectParams) ([]*ObjectInfo, error) {
|
||||
func (n *layer) listSortedObjectsFromNeoFS(ctx context.Context, p allObjectParams) ([]*api.ObjectInfo, error) {
|
||||
versions, err := n.getAllObjectsVersions(ctx, p.Bucket, p.Prefix, p.Delimiter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
objects := make([]*ObjectInfo, 0, len(versions))
|
||||
objects := make([]*api.ObjectInfo, 0, len(versions))
|
||||
for _, v := range versions {
|
||||
lastVersion := v.getLast()
|
||||
if lastVersion != nil {
|
||||
|
@ -478,7 +477,7 @@ func (n *layer) listSortedObjectsFromNeoFS(ctx context.Context, p allObjectParam
|
|||
return objects, nil
|
||||
}
|
||||
|
||||
func (n *layer) getAllObjectsVersions(ctx context.Context, bkt *cache.BucketInfo, prefix, delimiter string) (map[string]*objectVersions, error) {
|
||||
func (n *layer) getAllObjectsVersions(ctx context.Context, bkt *api.BucketInfo, prefix, delimiter string) (map[string]*objectVersions, error) {
|
||||
ids, err := n.objectSearch(ctx, &findParams{cid: bkt.CID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -526,12 +525,12 @@ func splitVersions(header string) []string {
|
|||
return strings.Split(header, ",")
|
||||
}
|
||||
|
||||
func isSystem(obj *ObjectInfo) bool {
|
||||
func isSystem(obj *api.ObjectInfo) bool {
|
||||
return len(obj.Headers[objectSystemAttributeName]) > 0 ||
|
||||
len(obj.Headers[attrVersionsIgnore]) > 0
|
||||
}
|
||||
|
||||
func trimAfterObjectName(startAfter string, objects []*ObjectInfo) []*ObjectInfo {
|
||||
func trimAfterObjectName(startAfter string, objects []*api.ObjectInfo) []*api.ObjectInfo {
|
||||
if len(objects) != 0 && objects[len(objects)-1].Name <= startAfter {
|
||||
return nil
|
||||
}
|
||||
|
@ -544,12 +543,12 @@ func trimAfterObjectName(startAfter string, objects []*ObjectInfo) []*ObjectInfo
|
|||
return nil
|
||||
}
|
||||
|
||||
func trimAfterObjectID(id string, objects []*ObjectInfo) []*ObjectInfo {
|
||||
if len(objects) != 0 && objects[len(objects)-1].id.String() == id {
|
||||
return []*ObjectInfo{}
|
||||
func trimAfterObjectID(id string, objects []*api.ObjectInfo) []*api.ObjectInfo {
|
||||
if len(objects) != 0 && objects[len(objects)-1].ID.String() == id {
|
||||
return []*api.ObjectInfo{}
|
||||
}
|
||||
for i, obj := range objects {
|
||||
if obj.ID().String() == id {
|
||||
if obj.ID.String() == id {
|
||||
return objects[i+1:]
|
||||
}
|
||||
}
|
||||
|
@ -557,9 +556,9 @@ func trimAfterObjectID(id string, objects []*ObjectInfo) []*ObjectInfo {
|
|||
return nil
|
||||
}
|
||||
|
||||
func triageObjects(allObjects []*ObjectInfo) (prefixes []string, objects []*ObjectInfo) {
|
||||
func triageObjects(allObjects []*api.ObjectInfo) (prefixes []string, objects []*api.ObjectInfo) {
|
||||
for _, ov := range allObjects {
|
||||
if ov.isDir {
|
||||
if ov.IsDir {
|
||||
prefixes = append(prefixes, ov.Name)
|
||||
} else {
|
||||
objects = append(objects, ov)
|
||||
|
@ -569,12 +568,12 @@ func triageObjects(allObjects []*ObjectInfo) (prefixes []string, objects []*Obje
|
|||
return
|
||||
}
|
||||
|
||||
func (n *layer) listAllObjects(ctx context.Context, p ListObjectsParamsCommon) ([]*ObjectInfo, error) {
|
||||
func (n *layer) listAllObjects(ctx context.Context, p ListObjectsParamsCommon) ([]*api.ObjectInfo, error) {
|
||||
var (
|
||||
err error
|
||||
bkt *cache.BucketInfo
|
||||
bkt *api.BucketInfo
|
||||
cacheKey cacheOptions
|
||||
allObjects []*ObjectInfo
|
||||
allObjects []*api.ObjectInfo
|
||||
)
|
||||
|
||||
if bkt, err = n.GetBucketInfo(ctx, p.Bucket); err != nil {
|
||||
|
@ -598,13 +597,13 @@ func (n *layer) listAllObjects(ctx context.Context, p ListObjectsParamsCommon) (
|
|||
}
|
||||
|
||||
// putting to cache a copy of allObjects because allObjects can be modified further
|
||||
n.listsCache.Put(cacheKey, append([]*ObjectInfo(nil), allObjects...))
|
||||
n.listsCache.Put(cacheKey, append([]*api.ObjectInfo(nil), allObjects...))
|
||||
}
|
||||
|
||||
return allObjects, nil
|
||||
}
|
||||
|
||||
func (n *layer) isVersioningEnabled(ctx context.Context, bktInfo *cache.BucketInfo) bool {
|
||||
func (n *layer) isVersioningEnabled(ctx context.Context, bktInfo *api.BucketInfo) bool {
|
||||
settings, err := n.getBucketSettings(ctx, bktInfo)
|
||||
if err != nil {
|
||||
n.log.Warn("couldn't get versioning settings object", zap.Error(err))
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"time"
|
||||
|
||||
cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||
)
|
||||
|
||||
/*
|
||||
|
@ -21,8 +22,8 @@ import (
|
|||
// ObjectsListCache provides interface for cache of ListObjectsV2 in a layer struct.
|
||||
type (
|
||||
ObjectsListCache interface {
|
||||
Get(key cacheOptions) []*ObjectInfo
|
||||
Put(key cacheOptions, objects []*ObjectInfo)
|
||||
Get(key cacheOptions) []*api.ObjectInfo
|
||||
Put(key cacheOptions, objects []*api.ObjectInfo)
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -41,7 +42,7 @@ type (
|
|||
mtx sync.RWMutex
|
||||
}
|
||||
cacheEntry struct {
|
||||
list []*ObjectInfo
|
||||
list []*api.ObjectInfo
|
||||
}
|
||||
cacheOptions struct {
|
||||
method string
|
||||
|
@ -58,7 +59,7 @@ func newListObjectsCache(lifetime time.Duration) *listObjectsCache {
|
|||
}
|
||||
}
|
||||
|
||||
func (l *listObjectsCache) Get(key cacheOptions) []*ObjectInfo {
|
||||
func (l *listObjectsCache) Get(key cacheOptions) []*api.ObjectInfo {
|
||||
l.mtx.RLock()
|
||||
defer l.mtx.RUnlock()
|
||||
if val, ok := l.caches[key]; ok {
|
||||
|
@ -67,7 +68,7 @@ func (l *listObjectsCache) Get(key cacheOptions) []*ObjectInfo {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (l *listObjectsCache) Put(key cacheOptions, objects []*ObjectInfo) {
|
||||
func (l *listObjectsCache) Put(key cacheOptions, objects []*api.ObjectInfo) {
|
||||
if len(objects) == 0 {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/pkg/object"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
@ -29,11 +30,11 @@ func randSHA256Checksum(t *testing.T) (cs [sha256.Size]byte) {
|
|||
|
||||
func TestTrimAfterObjectName(t *testing.T) {
|
||||
var (
|
||||
objects []*ObjectInfo
|
||||
objects []*api.ObjectInfo
|
||||
names = []string{"b", "c", "d"}
|
||||
)
|
||||
for _, name := range names {
|
||||
objects = append(objects, &ObjectInfo{Name: name})
|
||||
objects = append(objects, &api.ObjectInfo{Name: name})
|
||||
}
|
||||
|
||||
t.Run("startafter before all objects", func(t *testing.T) {
|
||||
|
@ -62,7 +63,7 @@ func TestTrimAfterObjectName(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("empty objects", func(t *testing.T) {
|
||||
actual := trimAfterObjectName(names[0], []*ObjectInfo{})
|
||||
actual := trimAfterObjectName(names[0], []*api.ObjectInfo{})
|
||||
require.Nil(t, actual)
|
||||
})
|
||||
|
||||
|
@ -79,14 +80,14 @@ func TestTrimAfterObjectName(t *testing.T) {
|
|||
|
||||
func TestTrimAfterObjectID(t *testing.T) {
|
||||
var (
|
||||
objects []*ObjectInfo
|
||||
objects []*api.ObjectInfo
|
||||
ids []*object.ID
|
||||
numberOfIDS = 3
|
||||
)
|
||||
|
||||
for i := 0; i < numberOfIDS; i++ {
|
||||
id := randID(t)
|
||||
objects = append(objects, &ObjectInfo{id: id})
|
||||
objects = append(objects, &api.ObjectInfo{ID: id})
|
||||
ids = append(ids, id)
|
||||
}
|
||||
|
||||
|
@ -119,13 +120,13 @@ func TestTrimAfterObjectID(t *testing.T) {
|
|||
func TestObjectsListCache(t *testing.T) {
|
||||
var (
|
||||
cacheSize = 10
|
||||
objects []*ObjectInfo
|
||||
objects []*api.ObjectInfo
|
||||
userKey = "key"
|
||||
)
|
||||
|
||||
for i := 0; i < cacheSize; i++ {
|
||||
id := randID(t)
|
||||
objects = append(objects, &ObjectInfo{id: id, Name: id.String()})
|
||||
objects = append(objects, &api.ObjectInfo{ID: id, Name: id.String()})
|
||||
}
|
||||
|
||||
sort.Slice(objects, func(i, j int) bool {
|
||||
|
|
|
@ -8,36 +8,16 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id"
|
||||
"github.com/nspcc-dev/neofs-api-go/pkg/object"
|
||||
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/cache"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/creds/accessbox"
|
||||
)
|
||||
|
||||
type (
|
||||
// ObjectInfo holds S3 object data.
|
||||
ObjectInfo struct {
|
||||
id *object.ID
|
||||
bucketID *cid.ID
|
||||
isDir bool
|
||||
|
||||
Bucket string
|
||||
Name string
|
||||
Size int64
|
||||
ContentType string
|
||||
Created time.Time
|
||||
CreationEpoch uint64
|
||||
HashSum string
|
||||
Owner *owner.ID
|
||||
Headers map[string]string
|
||||
}
|
||||
|
||||
// ListObjectsInfo contains common fields of data for ListObjectsV1 and ListObjectsV2.
|
||||
ListObjectsInfo struct {
|
||||
Prefixes []string
|
||||
Objects []*ObjectInfo
|
||||
Objects []*api.ObjectInfo
|
||||
IsTruncated bool
|
||||
}
|
||||
|
||||
|
@ -55,7 +35,7 @@ type (
|
|||
|
||||
// ObjectVersionInfo stores info about objects versions.
|
||||
ObjectVersionInfo struct {
|
||||
Object *ObjectInfo
|
||||
Object *api.ObjectInfo
|
||||
IsLatest bool
|
||||
}
|
||||
|
||||
|
@ -85,11 +65,11 @@ func userHeaders(attrs []*object.Attribute) map[string]string {
|
|||
return result
|
||||
}
|
||||
|
||||
func objInfoFromMeta(bkt *cache.BucketInfo, meta *object.Object) *ObjectInfo {
|
||||
func objInfoFromMeta(bkt *api.BucketInfo, meta *object.Object) *api.ObjectInfo {
|
||||
return objectInfoFromMeta(bkt, meta, "", "")
|
||||
}
|
||||
|
||||
func objectInfoFromMeta(bkt *cache.BucketInfo, meta *object.Object, prefix, delimiter string) *ObjectInfo {
|
||||
func objectInfoFromMeta(bkt *api.BucketInfo, meta *object.Object, prefix, delimiter string) *api.ObjectInfo {
|
||||
var (
|
||||
isDir bool
|
||||
size int64
|
||||
|
@ -130,10 +110,10 @@ func objectInfoFromMeta(bkt *cache.BucketInfo, meta *object.Object, prefix, deli
|
|||
size = int64(meta.PayloadSize())
|
||||
}
|
||||
|
||||
return &ObjectInfo{
|
||||
id: meta.ID(),
|
||||
bucketID: bkt.CID,
|
||||
isDir: isDir,
|
||||
return &api.ObjectInfo{
|
||||
ID: meta.ID(),
|
||||
CID: bkt.CID,
|
||||
IsDir: isDir,
|
||||
|
||||
Bucket: bkt.Name,
|
||||
Name: filename,
|
||||
|
@ -163,27 +143,6 @@ func NameFromString(name string) (string, string) {
|
|||
return name[ind+1:], name[:ind+1]
|
||||
}
|
||||
|
||||
// ID returns object ID from ObjectInfo.
|
||||
func (o *ObjectInfo) ID() *object.ID { return o.id }
|
||||
|
||||
// Version returns object version from ObjectInfo.
|
||||
func (o *ObjectInfo) Version() string { return o.id.String() }
|
||||
|
||||
// NiceName returns object name for cache.
|
||||
func (o *ObjectInfo) NiceName() string { return o.Bucket + "/" + o.Name }
|
||||
|
||||
// Address returns object address.
|
||||
func (o *ObjectInfo) Address() *object.Address { return newAddress(o.bucketID, o.id) }
|
||||
|
||||
// TagsObject returns name of system object for tags.
|
||||
func (o *ObjectInfo) TagsObject() string { return ".tagset." + o.Name + "." + o.Version() }
|
||||
|
||||
// CID returns bucket ID from ObjectInfo.
|
||||
func (o *ObjectInfo) CID() *cid.ID { return o.bucketID }
|
||||
|
||||
// IsDir allows to check if object is a directory.
|
||||
func (o *ObjectInfo) IsDir() bool { return o.isDir }
|
||||
|
||||
// GetBoxData extracts accessbox.Box from context.
|
||||
func GetBoxData(ctx context.Context) (*accessbox.Box, error) {
|
||||
var boxData *accessbox.Box
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id"
|
||||
"github.com/nspcc-dev/neofs-api-go/pkg/object"
|
||||
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/cache"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
@ -20,7 +20,7 @@ var (
|
|||
defaultTestContentType = http.DetectContentType(defaultTestPayload)
|
||||
)
|
||||
|
||||
func newTestObject(oid *object.ID, bkt *cache.BucketInfo, name string) *object.Object {
|
||||
func newTestObject(oid *object.ID, bkt *api.BucketInfo, name string) *object.Object {
|
||||
filename := object.NewAttribute()
|
||||
filename.SetKey(object.AttributeFileName)
|
||||
filename.SetValue(name)
|
||||
|
@ -44,12 +44,12 @@ func newTestObject(oid *object.ID, bkt *cache.BucketInfo, name string) *object.O
|
|||
return raw.Object()
|
||||
}
|
||||
|
||||
func newTestInfo(oid *object.ID, bkt *cache.BucketInfo, name string, isDir bool) *ObjectInfo {
|
||||
info := &ObjectInfo{
|
||||
id: oid,
|
||||
func newTestInfo(oid *object.ID, bkt *api.BucketInfo, name string, isDir bool) *api.ObjectInfo {
|
||||
info := &api.ObjectInfo{
|
||||
ID: oid,
|
||||
Name: name,
|
||||
Bucket: bkt.Name,
|
||||
bucketID: bkt.CID,
|
||||
CID: bkt.CID,
|
||||
Size: defaultTestPayloadLength,
|
||||
ContentType: defaultTestContentType,
|
||||
Created: time.Unix(defaultTestCreated.Unix(), 0),
|
||||
|
@ -58,7 +58,7 @@ func newTestInfo(oid *object.ID, bkt *cache.BucketInfo, name string, isDir bool)
|
|||
}
|
||||
|
||||
if isDir {
|
||||
info.isDir = true
|
||||
info.IsDir = true
|
||||
info.Size = 0
|
||||
info.ContentType = ""
|
||||
info.Headers = nil
|
||||
|
@ -72,7 +72,7 @@ func Test_objectInfoFromMeta(t *testing.T) {
|
|||
oid := object.NewID()
|
||||
containerID := cid.New()
|
||||
|
||||
bkt := &cache.BucketInfo{
|
||||
bkt := &api.BucketInfo{
|
||||
Name: "test-container",
|
||||
CID: containerID,
|
||||
Owner: uid,
|
||||
|
@ -82,7 +82,7 @@ func Test_objectInfoFromMeta(t *testing.T) {
|
|||
cases := []struct {
|
||||
name string
|
||||
prefix string
|
||||
result *ObjectInfo
|
||||
result *api.ObjectInfo
|
||||
object *object.Object
|
||||
delimiter string
|
||||
}{
|
||||
|
|
|
@ -7,13 +7,13 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/pkg/object"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/cache"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/errors"
|
||||
)
|
||||
|
||||
type objectVersions struct {
|
||||
name string
|
||||
objects []*ObjectInfo
|
||||
objects []*api.ObjectInfo
|
||||
addList []string
|
||||
delList []string
|
||||
isSorted bool
|
||||
|
@ -34,7 +34,7 @@ func newObjectVersions(name string) *objectVersions {
|
|||
return &objectVersions{name: name}
|
||||
}
|
||||
|
||||
func (v *objectVersions) appendVersion(oi *ObjectInfo) {
|
||||
func (v *objectVersions) appendVersion(oi *api.ObjectInfo) {
|
||||
addVers := append(splitVersions(oi.Headers[versionsAddAttr]), oi.Version())
|
||||
delVers := splitVersions(oi.Headers[versionsDelAttr])
|
||||
v.objects = append(v.objects, oi)
|
||||
|
@ -60,7 +60,7 @@ func (v *objectVersions) sort() {
|
|||
}
|
||||
}
|
||||
|
||||
func (v *objectVersions) getLast() *ObjectInfo {
|
||||
func (v *objectVersions) getLast() *api.ObjectInfo {
|
||||
if len(v.objects) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
@ -82,14 +82,14 @@ func (v *objectVersions) getLast() *ObjectInfo {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (v *objectVersions) getFiltered() []*ObjectInfo {
|
||||
func (v *objectVersions) getFiltered() []*api.ObjectInfo {
|
||||
if len(v.objects) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
v.sort()
|
||||
existedVersions := getExistedVersions(v)
|
||||
res := make([]*ObjectInfo, 0, len(v.objects))
|
||||
res := make([]*api.ObjectInfo, 0, len(v.objects))
|
||||
|
||||
for _, version := range v.objects {
|
||||
delMark := version.Headers[versionsDeleteMarkAttr]
|
||||
|
@ -109,15 +109,15 @@ func (v *objectVersions) getDelHeader() string {
|
|||
return strings.Join(v.delList, ",")
|
||||
}
|
||||
|
||||
func (v *objectVersions) getVersion(oid *object.ID) *ObjectInfo {
|
||||
func (v *objectVersions) getVersion(oid *object.ID) *api.ObjectInfo {
|
||||
for _, version := range v.objects {
|
||||
if version.ID() == oid {
|
||||
if version.ID == oid {
|
||||
return version
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (n *layer) PutBucketVersioning(ctx context.Context, p *PutVersioningParams) (*ObjectInfo, error) {
|
||||
func (n *layer) PutBucketVersioning(ctx context.Context, p *PutVersioningParams) (*api.ObjectInfo, error) {
|
||||
bktInfo, err := n.GetBucketInfo(ctx, p.Bucket)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -171,13 +171,13 @@ func (n *layer) ListObjectVersions(ctx context.Context, p *ListObjectVersionsPar
|
|||
}
|
||||
sort.Strings(sortedNames)
|
||||
|
||||
allObjects = make([]*ObjectInfo, 0, p.MaxKeys)
|
||||
allObjects = make([]*api.ObjectInfo, 0, p.MaxKeys)
|
||||
for _, name := range sortedNames {
|
||||
allObjects = append(allObjects, versions[name].getFiltered()...)
|
||||
}
|
||||
|
||||
// putting to cache a copy of allObjects because allObjects can be modified further
|
||||
n.listsCache.Put(cacheKey, append([]*ObjectInfo(nil), allObjects...))
|
||||
n.listsCache.Put(cacheKey, append([]*api.ObjectInfo(nil), allObjects...))
|
||||
}
|
||||
|
||||
for i, obj := range allObjects {
|
||||
|
@ -230,7 +230,7 @@ func triageVersions(objVersions []*ObjectVersionInfo) ([]*ObjectVersionInfo, []*
|
|||
return resVersion, resDelMarkVersions
|
||||
}
|
||||
|
||||
func less(ov1, ov2 *ObjectInfo) bool {
|
||||
func less(ov1, ov2 *api.ObjectInfo) bool {
|
||||
if ov1.CreationEpoch == ov2.CreationEpoch {
|
||||
return ov1.Version() < ov2.Version()
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ func contains(list []string, elem string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (n *layer) getBucketSettings(ctx context.Context, bktInfo *cache.BucketInfo) (*BucketSettings, error) {
|
||||
func (n *layer) getBucketSettings(ctx context.Context, bktInfo *api.BucketInfo) (*BucketSettings, error) {
|
||||
objInfo, err := n.getSystemObject(ctx, bktInfo, bktInfo.SettingsObjectName())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -255,7 +255,7 @@ func (n *layer) getBucketSettings(ctx context.Context, bktInfo *cache.BucketInfo
|
|||
return objectInfoToBucketSettings(objInfo), nil
|
||||
}
|
||||
|
||||
func objectInfoToBucketSettings(info *ObjectInfo) *BucketSettings {
|
||||
func objectInfoToBucketSettings(info *api.ObjectInfo) *BucketSettings {
|
||||
res := &BucketSettings{}
|
||||
|
||||
enabled, ok := info.Headers[attrSettingsVersioningEnabled]
|
||||
|
@ -267,7 +267,7 @@ func objectInfoToBucketSettings(info *ObjectInfo) *BucketSettings {
|
|||
return res
|
||||
}
|
||||
|
||||
func (n *layer) checkVersionsExist(ctx context.Context, bkt *cache.BucketInfo, obj *VersionedObject) (*object.ID, error) {
|
||||
func (n *layer) checkVersionsExist(ctx context.Context, bkt *api.BucketInfo, obj *VersionedObject) (*object.ID, error) {
|
||||
id := object.NewID()
|
||||
if err := id.Parse(obj.VersionID); err != nil {
|
||||
return nil, errors.GetAPIError(errors.ErrInvalidVersion)
|
||||
|
|
|
@ -207,7 +207,7 @@ func (t *testPool) WaitForContainerPresence(ctx context.Context, id *cid.ID, par
|
|||
return nil
|
||||
}
|
||||
|
||||
func (tc *testContext) putObject(content []byte) *ObjectInfo {
|
||||
func (tc *testContext) putObject(content []byte) *api.ObjectInfo {
|
||||
objInfo, err := tc.layer.PutObject(tc.ctx, &PutObjectParams{
|
||||
Bucket: tc.bkt,
|
||||
Object: tc.obj,
|
||||
|
@ -220,7 +220,7 @@ func (tc *testContext) putObject(content []byte) *ObjectInfo {
|
|||
return objInfo
|
||||
}
|
||||
|
||||
func (tc *testContext) getObject(objectName, versionID string, needError bool) (*ObjectInfo, []byte) {
|
||||
func (tc *testContext) getObject(objectName, versionID string, needError bool) (*api.ObjectInfo, []byte) {
|
||||
objInfo, err := tc.layer.GetObjectInfo(tc.ctx, &HeadObjectParams{
|
||||
Bucket: tc.bkt,
|
||||
Object: objectName,
|
||||
|
@ -252,7 +252,7 @@ func (tc *testContext) deleteObject(objectName, versionID string) {
|
|||
}
|
||||
}
|
||||
|
||||
func (tc *testContext) listObjectsV1() []*ObjectInfo {
|
||||
func (tc *testContext) listObjectsV1() []*api.ObjectInfo {
|
||||
res, err := tc.layer.ListObjectsV1(tc.ctx, &ListObjectsParamsV1{
|
||||
ListObjectsParamsCommon: ListObjectsParamsCommon{
|
||||
Bucket: tc.bkt,
|
||||
|
@ -263,7 +263,7 @@ func (tc *testContext) listObjectsV1() []*ObjectInfo {
|
|||
return res.Objects
|
||||
}
|
||||
|
||||
func (tc *testContext) listObjectsV2() []*ObjectInfo {
|
||||
func (tc *testContext) listObjectsV2() []*api.ObjectInfo {
|
||||
res, err := tc.layer.ListObjectsV2(tc.ctx, &ListObjectsParamsV2{
|
||||
ListObjectsParamsCommon: ListObjectsParamsCommon{
|
||||
Bucket: tc.bkt,
|
||||
|
@ -357,12 +357,12 @@ func TestSimpleVersioning(t *testing.T) {
|
|||
|
||||
objv2, buffer2 := tc.getObject(tc.obj, "", false)
|
||||
require.Equal(t, obj1Content2, buffer2)
|
||||
require.Contains(t, objv2.Headers[versionsAddAttr], obj1v1.ID().String())
|
||||
require.Contains(t, objv2.Headers[versionsAddAttr], obj1v1.ID.String())
|
||||
|
||||
_, buffer1 := tc.getObject(tc.obj, obj1v1.ID().String(), false)
|
||||
_, buffer1 := tc.getObject(tc.obj, obj1v1.ID.String(), false)
|
||||
require.Equal(t, obj1Content1, buffer1)
|
||||
|
||||
tc.checkListObjects(obj1v2.ID())
|
||||
tc.checkListObjects(obj1v2.ID)
|
||||
}
|
||||
|
||||
func TestSimpleNoVersioning(t *testing.T) {
|
||||
|
@ -376,10 +376,10 @@ func TestSimpleNoVersioning(t *testing.T) {
|
|||
|
||||
objv2, buffer2 := tc.getObject(tc.obj, "", false)
|
||||
require.Equal(t, obj1Content2, buffer2)
|
||||
require.Contains(t, objv2.Headers[versionsDelAttr], obj1v1.ID().String())
|
||||
require.Contains(t, objv2.Headers[versionsDelAttr], obj1v1.ID.String())
|
||||
|
||||
tc.getObject(tc.obj, obj1v1.ID().String(), true)
|
||||
tc.checkListObjects(obj1v2.ID())
|
||||
tc.getObject(tc.obj, obj1v1.ID.String(), true)
|
||||
tc.checkListObjects(obj1v2.ID)
|
||||
}
|
||||
|
||||
func TestVersioningDeleteObject(t *testing.T) {
|
||||
|
@ -454,7 +454,7 @@ func TestGetLastVersion(t *testing.T) {
|
|||
|
||||
for _, tc := range []struct {
|
||||
versions *objectVersions
|
||||
expected *ObjectInfo
|
||||
expected *api.ObjectInfo
|
||||
}{
|
||||
{
|
||||
versions: &objectVersions{},
|
||||
|
@ -462,21 +462,21 @@ func TestGetLastVersion(t *testing.T) {
|
|||
},
|
||||
{
|
||||
versions: &objectVersions{
|
||||
objects: []*ObjectInfo{obj2, obj1},
|
||||
objects: []*api.ObjectInfo{obj2, obj1},
|
||||
addList: []string{obj1.Version(), obj2.Version()},
|
||||
},
|
||||
expected: obj2,
|
||||
},
|
||||
{
|
||||
versions: &objectVersions{
|
||||
objects: []*ObjectInfo{obj2, obj1, obj3},
|
||||
objects: []*api.ObjectInfo{obj2, obj1, obj3},
|
||||
addList: []string{obj1.Version(), obj2.Version(), obj3.Version()},
|
||||
},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
versions: &objectVersions{
|
||||
objects: []*ObjectInfo{obj2, obj1, obj4},
|
||||
objects: []*api.ObjectInfo{obj2, obj1, obj4},
|
||||
addList: []string{obj1.Version(), obj2.Version(), obj4.Version()},
|
||||
delList: []string{obj2.Version()},
|
||||
},
|
||||
|
@ -484,7 +484,7 @@ func TestGetLastVersion(t *testing.T) {
|
|||
},
|
||||
{
|
||||
versions: &objectVersions{
|
||||
objects: []*ObjectInfo{obj1, obj5},
|
||||
objects: []*api.ObjectInfo{obj1, obj5},
|
||||
addList: []string{obj1.Version(), obj5.Version()},
|
||||
delList: []string{obj1.Version()},
|
||||
},
|
||||
|
@ -492,13 +492,13 @@ func TestGetLastVersion(t *testing.T) {
|
|||
},
|
||||
{
|
||||
versions: &objectVersions{
|
||||
objects: []*ObjectInfo{obj5},
|
||||
objects: []*api.ObjectInfo{obj5},
|
||||
},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
versions: &objectVersions{
|
||||
objects: []*ObjectInfo{obj1, obj2, obj3, obj6},
|
||||
objects: []*api.ObjectInfo{obj1, obj2, obj3, obj6},
|
||||
addList: []string{obj1.Version(), obj2.Version(), obj3.Version(), obj6.Version()},
|
||||
delList: []string{obj3.Version()},
|
||||
},
|
||||
|
@ -506,7 +506,7 @@ func TestGetLastVersion(t *testing.T) {
|
|||
},
|
||||
{
|
||||
versions: &objectVersions{
|
||||
objects: []*ObjectInfo{obj1, obj1V2},
|
||||
objects: []*api.ObjectInfo{obj1, obj1V2},
|
||||
addList: []string{obj1.Version(), obj1V2.Version()},
|
||||
},
|
||||
// creation epochs are equal
|
||||
|
@ -527,38 +527,38 @@ func TestAppendVersions(t *testing.T) {
|
|||
|
||||
for _, tc := range []struct {
|
||||
versions *objectVersions
|
||||
objectToAdd *ObjectInfo
|
||||
objectToAdd *api.ObjectInfo
|
||||
expectedVersions *objectVersions
|
||||
}{
|
||||
{
|
||||
versions: &objectVersions{},
|
||||
objectToAdd: obj1,
|
||||
expectedVersions: &objectVersions{
|
||||
objects: []*ObjectInfo{obj1},
|
||||
objects: []*api.ObjectInfo{obj1},
|
||||
addList: []string{obj1.Version()},
|
||||
},
|
||||
},
|
||||
{
|
||||
versions: &objectVersions{objects: []*ObjectInfo{obj1}},
|
||||
versions: &objectVersions{objects: []*api.ObjectInfo{obj1}},
|
||||
objectToAdd: obj2,
|
||||
expectedVersions: &objectVersions{
|
||||
objects: []*ObjectInfo{obj1, obj2},
|
||||
objects: []*api.ObjectInfo{obj1, obj2},
|
||||
addList: []string{obj1.Version(), obj2.Version()},
|
||||
},
|
||||
},
|
||||
{
|
||||
versions: &objectVersions{objects: []*ObjectInfo{obj1, obj2}},
|
||||
versions: &objectVersions{objects: []*api.ObjectInfo{obj1, obj2}},
|
||||
objectToAdd: obj3,
|
||||
expectedVersions: &objectVersions{
|
||||
objects: []*ObjectInfo{obj1, obj2, obj3},
|
||||
objects: []*api.ObjectInfo{obj1, obj2, obj3},
|
||||
addList: []string{obj1.Version(), obj2.Version(), obj3.Version()},
|
||||
},
|
||||
},
|
||||
{
|
||||
versions: &objectVersions{objects: []*ObjectInfo{obj1, obj2}},
|
||||
versions: &objectVersions{objects: []*api.ObjectInfo{obj1, obj2}},
|
||||
objectToAdd: obj4,
|
||||
expectedVersions: &objectVersions{
|
||||
objects: []*ObjectInfo{obj1, obj2, obj4},
|
||||
objects: []*api.ObjectInfo{obj1, obj2, obj4},
|
||||
addList: []string{obj1.Version(), obj2.Version(), obj4.Version()},
|
||||
delList: []string{obj2.Version()},
|
||||
},
|
||||
|
@ -569,7 +569,7 @@ func TestAppendVersions(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func joinVers(objs ...*ObjectInfo) string {
|
||||
func joinVers(objs ...*api.ObjectInfo) string {
|
||||
if len(objs) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
@ -590,7 +590,7 @@ func getOID(id byte) *object.ID {
|
|||
return oid
|
||||
}
|
||||
|
||||
func getTestObjectInfo(epoch uint64, oid *object.ID, addAttr, delAttr, delMarkAttr string) *ObjectInfo {
|
||||
func getTestObjectInfo(epoch uint64, oid *object.ID, addAttr, delAttr, delMarkAttr string) *api.ObjectInfo {
|
||||
headers := make(map[string]string)
|
||||
if addAttr != "" {
|
||||
headers[versionsAddAttr] = addAttr
|
||||
|
@ -602,8 +602,8 @@ func getTestObjectInfo(epoch uint64, oid *object.ID, addAttr, delAttr, delMarkAt
|
|||
headers[versionsDeleteMarkAttr] = delMarkAttr
|
||||
}
|
||||
|
||||
return &ObjectInfo{
|
||||
id: oid,
|
||||
return &api.ObjectInfo{
|
||||
ID: oid,
|
||||
CreationEpoch: epoch,
|
||||
Headers: headers,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue