use s3Service interface

This commit is contained in:
2021-11-23 20:12:24 +01:00
parent 60817c2249
commit 8d85d645d6
9 changed files with 162 additions and 257 deletions

View File

@@ -28,44 +28,62 @@ func NewMinio(config types.AppConfig) (S3Service, error) {
}, nil
}
func (m *minioS3) ListBuckets(ctx context.Context) ([]Bucket, error) {
func (m *minioS3) ListBuckets(ctx context.Context) ([]string, error) {
buckets, err := m.client.ListBuckets(ctx)
if err != nil {
return nil, err
}
var rtn []Bucket
var rtn []string
for _, v := range buckets {
rtn = append(rtn, Bucket(v.Name))
rtn = append(rtn, v.Name)
}
return rtn, nil
}
func (m *minioS3) ListObjects(ctx context.Context, id types.ID) ([]types.File, []types.Directory, error) {
var files []types.File
var dirs []types.Directory
func (m *minioS3) ListObjects(ctx context.Context, id types.ID) ([]Object, error) {
var result []Object
for objInfo := range m.client.ListObjects(ctx, id.Bucket, minio.ListObjectsOptions{}) {
for objInfo := range m.client.ListObjects(ctx, id.Bucket, minio.ListObjectsOptions{
Prefix: id.Key,
Recursive: false,
}) {
objId := types.ID{
Bucket: id.Bucket,
Key: objInfo.Key,
}
objId.Normalize()
if objId.IsDirectory() {
dirs = append(dirs, *obkInfoToDir(objInfo, objId))
} else {
files = append(files, *objInfoToFile(objInfo, objId))
}
result = append(result, Object{
ID: objId,
Size: objInfo.Size,
})
}
return files, dirs, nil
return result, nil
}
func (m *minioS3) GetObject(ctx context.Context, id types.ID) (Object, error) {
func (m *minioS3) ListObjectsRecursive(ctx context.Context, id types.ID) ([]Object, error) {
var result []Object
for objInfo := range m.client.ListObjects(ctx, id.Bucket, minio.ListObjectsOptions{
Prefix: id.Key,
Recursive: true,
}) {
objId := types.ID{
Bucket: id.Bucket,
Key: objInfo.Key,
}
result = append(result, Object{
ID: objId,
Size: objInfo.Size,
})
}
return result, nil
}
func (m *minioS3) GetObject(ctx context.Context, id types.ID) (ObjectReader, error) {
object, err := m.client.GetObject(ctx, id.Bucket, id.Key, minio.GetObjectOptions{})
if err != nil {
@@ -92,35 +110,22 @@ func (m *minioS3) CopyObject(ctx context.Context, src types.ID, dest types.ID) e
return err
}
func (m *minioS3) StatObject(ctx context.Context, id types.ID) (*types.File, error) {
func (m *minioS3) StatObject(ctx context.Context, id types.ID) (*Object, error) {
info, err := m.client.StatObject(ctx, id.Bucket, id.Key, minio.GetObjectOptions{})
if err != nil {
return nil, err
}
return objInfoToFile(info, id), nil
return &Object{
ID: id,
Size: info.Size,
LastModified: info.LastModified,
ContentType: info.ContentType,
ETag: info.ETag,
}, nil
}
func (m *minioS3) RemoveObject(ctx context.Context, id types.ID) error {
return m.client.RemoveObject(ctx, id.Bucket, id.Key, minio.RemoveObjectOptions{})
}
func objInfoToFile(objInfo minio.ObjectInfo, id types.ID) *types.File {
return &types.File{
ID: id,
Name: id.Name(),
Size: objInfo.Size,
ContentType: objInfo.ContentType,
ETag: objInfo.ETag,
LastModified: objInfo.LastModified,
}
}
func obkInfoToDir(objInfo minio.ObjectInfo, id types.ID) *types.Directory {
return &types.Directory{
ID: id,
Name: id.Name(),
}
}

View File

@@ -7,6 +7,7 @@ import (
"fmt"
"io"
"io/ioutil"
"strings"
"time"
"git.kapelle.org/niklas/s3browser/internal/types"
@@ -39,35 +40,41 @@ func NewMockS3(buckets []string) (S3Service, error) {
}, nil
}
func (m *mockS3) ListBuckets(ctx context.Context) ([]Bucket, error) {
var rtn []Bucket
for _, v := range m.buckets {
rtn = append(rtn, Bucket(v))
}
return rtn, nil
func (m *mockS3) ListBuckets(ctx context.Context) ([]string, error) {
return m.buckets, nil
}
func (m *mockS3) ListObjects(ctx context.Context, id types.ID) ([]types.File, []types.Directory, error) {
var files []types.File
var dirs []types.Directory
func (m *mockS3) ListObjects(ctx context.Context, id types.ID) ([]Object, error) {
var results []Object
for k, v := range m.objects {
if k.Bucket == id.Bucket {
if k.Parent().Key == id.Key {
if k.IsDirectory() {
dirs = append(dirs, *mockObjToDir(v, k))
} else {
files = append(files, *mockObjToFile(v, k))
results = append(results, *mockObjToObject(v, k))
}
}
}
return results, nil
}
func (m *mockS3) ListObjectsRecursive(ctx context.Context, id types.ID) ([]Object, error) {
var results []Object
for k, v := range m.objects {
if k.Bucket == id.Bucket {
if strings.HasPrefix(k.Key, id.Key) {
if k.Parent().Key == id.Key {
results = append(results, *mockObjToObject(v, k))
}
}
}
}
return files, dirs, nil
return results, nil
}
func (m *mockS3) GetObject(ctx context.Context, id types.ID) (Object, error) {
func (m *mockS3) GetObject(ctx context.Context, id types.ID) (ObjectReader, error) {
mockObj, exist := m.objects[id]
if !exist {
@@ -107,14 +114,14 @@ func (m *mockS3) CopyObject(ctx context.Context, src types.ID, dest types.ID) er
return nil
}
func (m *mockS3) StatObject(ctx context.Context, id types.ID) (*types.File, error) {
func (m *mockS3) StatObject(ctx context.Context, id types.ID) (*Object, error) {
mockObj, exist := m.objects[id]
if !exist {
return nil, fmt.Errorf("Object not found")
}
return mockObjToFile(mockObj, id), nil
return mockObjToObject(mockObj, id), nil
}
func (m *mockS3) RemoveObject(ctx context.Context, id types.ID) error {
@@ -122,20 +129,12 @@ func (m *mockS3) RemoveObject(ctx context.Context, id types.ID) error {
return nil
}
func mockObjToFile(mockObj mockObject, id types.ID) *types.File {
return &types.File{
func mockObjToObject(mockObj mockObject, id types.ID) *Object {
return &Object{
ID: id,
Name: id.Name(),
Size: int64(len(mockObj.content)),
ContentType: mockObj.contentType,
LastModified: mockObj.lastMod,
ETag: fmt.Sprintf("%x", md5.Sum(mockObj.content)),
}
}
func mockObjToDir(mockObj mockObject, id types.ID) *types.Directory {
return &types.Directory{
ID: id,
Name: id.Name(),
}
}

View File

@@ -3,27 +3,35 @@ package s3
import (
"context"
"io"
"time"
"git.kapelle.org/niklas/s3browser/internal/types"
)
type Bucket string
type Object interface {
type ObjectReader interface {
io.Reader
io.Seeker
io.ReaderAt
io.Closer
}
type S3Service interface {
ListBuckets(ctx context.Context) ([]Bucket, error)
type Object struct {
ID types.ID
Size int64
LastModified time.Time
ContentType string
ETag string
}
GetObject(ctx context.Context, id types.ID) (Object, error)
type S3Service interface {
ListBuckets(ctx context.Context) ([]string, error)
GetObject(ctx context.Context, id types.ID) (ObjectReader, error)
PutObject(ctx context.Context, id types.ID, reader io.Reader, objectSize int64) error
ListObjects(ctx context.Context, id types.ID) ([]types.File, []types.Directory, error)
ListObjects(ctx context.Context, id types.ID) ([]Object, error)
ListObjectsRecursive(ctx context.Context, id types.ID) ([]Object, error)
CopyObject(ctx context.Context, src types.ID, dest types.ID) error
StatObject(ctx context.Context, id types.ID) (*types.File, error)
StatObject(ctx context.Context, id types.ID) (*Object, error)
RemoveObject(ctx context.Context, id types.ID) error
}