Skip to content

Commit

Permalink
Implement GSP-93, GSP-97, GSP-109 and GSP-117 (#58)
Browse files Browse the repository at this point in the history
* Implement GSP-93 and GSP-109

* Implement GSP-117 Rename Service to System as the Opposite to Global

* pkg/endpoint deprecated by go-endpoint

* Implement GSP-97 Add Restrictions In Storage Metadata

* Add direr test

* Fix direr test not pass

* Fix unit test not pass
  • Loading branch information
JinnyYi authored Jun 28, 2021
1 parent 0587517 commit 7c850b2
Show file tree
Hide file tree
Showing 9 changed files with 485 additions and 415 deletions.
698 changes: 317 additions & 381 deletions generated.go

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ go 1.14

require (
bou.ke/monkey v1.0.2
github.com/beyondstorage/go-integration-test/v4 v4.0.0
github.com/beyondstorage/go-storage/v4 v4.0.1-0.20210530044854-1c928ddbe52d
github.com/beyondstorage/go-endpoint v1.0.1
github.com/beyondstorage/go-integration-test/v4 v4.1.1
github.com/beyondstorage/go-storage/v4 v4.2.0
github.com/golang/mock v1.5.0
github.com/google/uuid v1.2.0
github.com/pengsrc/go-shared v0.2.1-0.20190131101655-1999055a4a14
Expand Down
28 changes: 17 additions & 11 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,23 @@ github.com/Xuanwo/go-bufferpool v0.0.0-20200622083641-bc954721ce54 h1:wA7f87ODtF
github.com/Xuanwo/go-bufferpool v0.0.0-20200622083641-bc954721ce54/go.mod h1:Mle++9GGouhOwGj52i9PJLNAPmW2nb8PWBP7JJzNCzk=
github.com/Xuanwo/templateutils v0.1.0 h1:WpkWOqQtIQ2vAIpJLa727DdN8WtxhUkkbDGa6UhntJY=
github.com/Xuanwo/templateutils v0.1.0/go.mod h1:OdE0DJ+CJxDBq6psX5DPV+gOZi8bhuHuVUpPCG++Wb8=
github.com/beyondstorage/go-integration-test/v4 v4.0.0 h1:tdXQV9yxQ3Q6p9xfyQKzK3MEo9r9j9g3uT5+3sbVtnQ=
github.com/beyondstorage/go-integration-test/v4 v4.0.0/go.mod h1:26/JF4b0XxRN0pL4kihpnVNhbbw+QWvmmvgxfnFJDfA=
github.com/beyondstorage/go-storage/v4 v4.0.0/go.mod h1:oa2dYco+xplPj99WSBnYVw/xXvRkIKWSSVDQKNZ5Kz8=
github.com/beyondstorage/go-storage/v4 v4.0.1-0.20210530044854-1c928ddbe52d h1:s9t6VNNRDqmg+PXyXtVEsxIM7xZQIJOYlma28IpkbNQ=
github.com/beyondstorage/go-storage/v4 v4.0.1-0.20210530044854-1c928ddbe52d/go.mod h1:kXMu07IDZaKtxbqI1ufuhqo0FjYe0nH7zPCbBanln/Y=
github.com/beyondstorage/specs/go v0.0.0-20210521044836-3d41c1d9c97f/go.mod h1:f5VvmLHc/dNJwl+/yAv/TOHdev3phvuEswx8DIXiSQQ=
github.com/beyondstorage/specs/go v0.0.0-20210530044123-3ff75e192bc9 h1:YSiF27cAHlDZk9q+oaEHQbA8dH8XTvYxeTOoPzNCwOQ=
github.com/beyondstorage/specs/go v0.0.0-20210530044123-3ff75e192bc9/go.mod h1:f5VvmLHc/dNJwl+/yAv/TOHdev3phvuEswx8DIXiSQQ=
github.com/beyondstorage/go-endpoint v1.0.1 h1:F8x2dGLMu9je6g7zPbKoxCXDlug97K26SeCx7KEHgyg=
github.com/beyondstorage/go-endpoint v1.0.1/go.mod h1:P2hknaGrziOJJKySv/XnAiVw/d3v12/LZu2gSxEx4nM=
github.com/beyondstorage/go-integration-test/v4 v4.1.1 h1:9bSXKbr6hLb4+ZsmAhWE32fvqhyrpub4U4qgBGeth4A=
github.com/beyondstorage/go-integration-test/v4 v4.1.1/go.mod h1:ihtCaOJvaHGE0v+IhY6ZUF5NU1IND6xmdrJI9Lq/jhc=
github.com/beyondstorage/go-storage/v4 v4.2.0 h1:J0xqqy4qEQRtIS2zUWMA5wRXVHx/cxX5fHsU2ezA3+I=
github.com/beyondstorage/go-storage/v4 v4.2.0/go.mod h1:rUNzOXcikYk5w0ewvNsKbztg7ndQDyDvjDuP0bznSLU=
github.com/beyondstorage/specs/go v0.0.0-20210623065218-d1c2d7d81259 h1:mW9XpHLc6pdXBRnsha1VlqF0rNsB/Oc+8l+5UYngmRA=
github.com/beyondstorage/specs/go v0.0.0-20210623065218-d1c2d7d81259/go.mod h1:vF/Q0P1tCvhVAUrxg7i6NvrARRMQVTAuQdDNqpSzR1w=
github.com/dave/dst v0.26.2 h1:lnxLAKI3tx7MgLNVDirFCsDTlTG9nKTk7GcptKcWSwY=
github.com/dave/dst v0.26.2/go.mod h1:UMDJuIRPfyUCC78eFuB+SV/WI8oDeyFDvM/JR6NI3IU=
github.com/dave/gopackages v0.0.0-20170318123100-46e7023ec56e/go.mod h1:i00+b/gKdIDIxuLDFob7ustLAVqhsZRk2qVZrArELGQ=
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
github.com/dave/kerr v0.0.0-20170318121727-bc25dd6abe8e/go.mod h1:qZqlPyPvfsDJt+3wHJ1EvSXDuVjFTK0j2p/ca+gtsb8=
github.com/dave/rebecca v0.9.1/go.mod h1:N6XYdMD/OKw3lkF3ywh8Z6wPGuwNFDNtWYEMFWEmXBA=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/google/pprof v0.0.0-20181127221834-b4f47329b966/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
Expand All @@ -37,8 +38,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pelletier/go-toml v1.9.1 h1:a6qW1EVNZWH9WGI6CsYdD8WAylkoXBS5yv0XHlh17Tc=
github.com/pelletier/go-toml v1.9.1/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ=
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pengsrc/go-shared v0.2.1-0.20190131101655-1999055a4a14 h1:XeOYlK9W1uCmhjJSsY78Mcuh7MVkNjTzmHx1yBzizSU=
github.com/pengsrc/go-shared v0.2.1-0.20190131101655-1999055a4a14/go.mod h1:jVblp62SafmidSkvWrXyxAme3gaTfEtWwRPGz5cpvHg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand All @@ -49,11 +50,14 @@ github.com/qingstor/qingstor-sdk-go/v4 v4.3.0 h1:+qcVqBiuGUsTPJZCHc5QK81NgfIMLjo
github.com/qingstor/qingstor-sdk-go/v4 v4.3.0/go.mod h1:GT0QY+LwqnOQhsRkbxUds8cTYR4inZpgOQEkCKYRiAs=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
Expand All @@ -73,6 +77,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
Expand Down
12 changes: 8 additions & 4 deletions service.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,24 @@ optional = ["location"]
optional = ["location"]

[namespace.storage]
implement = ["appender", "copier", "fetcher", "mover", "multiparter", "reacher"]
features = ["virtual_dir"]
implement = ["appender", "copier", "direr", "fetcher", "mover", "multiparter", "reacher"]

[namespace.storage.new]
required = ["name"]
optional = ["storage_features", "default_storage_pairs", "disable_uri_cleaning", "http_client_options", "location", "work_dir"]

[namespace.storage.op.create]
optional = ["multipart_id"]
optional = ["multipart_id", "object_mode"]

[namespace.storage.op.create_dir]
optional = ["storage_class"]

[namespace.storage.op.delete]
optional = ["multipart_id"]
optional = ["multipart_id", "object_mode"]

[namespace.storage.op.stat]
optional = ["multipart_id"]
optional = ["multipart_id", "object_mode"]

[namespace.storage.op.list]
optional = ["list_mode"]
Expand Down
109 changes: 99 additions & 10 deletions storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package qingstor

import (
"context"
"fmt"
"io"

"github.com/pengsrc/go-shared/convert"
"github.com/qingstor/qingstor-sdk-go/v4/service"

ps "github.com/beyondstorage/go-storage/v4/pairs"
"github.com/beyondstorage/go-storage/v4/pkg/headers"
"github.com/beyondstorage/go-storage/v4/pkg/iowrap"
"github.com/beyondstorage/go-storage/v4/services"
Expand Down Expand Up @@ -67,17 +69,29 @@ func (s *Storage) copy(ctx context.Context, src string, dst string, opt pairStor
}

func (s *Storage) create(path string, opt pairStorageCreate) (o *Object) {
rp := s.getAbsPath(path)

// handle create multipart object separately
// if opt has multipartID, set object done, because we can't stat multipart object in QingStor
if opt.HasMultipartID {
o = s.newObject(true)
o.Mode = ModePart
o.SetMultipartID(opt.MultipartID)
} else {
o = s.newObject(false)
o.Mode = ModeRead
if opt.HasObjectMode && opt.ObjectMode.IsDir() {
if !s.features.VirtualDir {
return
}

rp += "/"
o = s.newObject(true)
o.Mode = ModeDir
} else {
o = s.newObject(false)
o.Mode = ModeRead
}
}
o.ID = s.getAbsPath(path)
o.ID = rp
o.Path = path
return o
}
Expand Down Expand Up @@ -116,6 +130,37 @@ func (s *Storage) createAppend(ctx context.Context, path string, opt pairStorage
return o, nil
}

func (s *Storage) createDir(ctx context.Context, path string, opt pairStorageCreateDir) (o *Object, err error) {
if !s.features.VirtualDir {
err = NewOperationNotImplementedError("create_dir")
return
}

rp := s.getAbsPath(path)

// Add `/` at the end of path to simulate a directory.
// ref: https://docs.qingcloud.com/qingstor/api/object/put.html
rp += "/"

input := &service.PutObjectInput{
ContentLength: service.Int64(0),
}
if opt.HasStorageClass {
input.XQSStorageClass = service.String(opt.StorageClass)
}

_, err = s.bucket.PutObjectWithContext(ctx, rp, input)
if err != nil {
return
}

o = s.newObject(true)
o.Path = path
o.ID = rp
o.Mode = ModeDir
return
}

func (s *Storage) createMultipart(ctx context.Context, path string, opt pairStorageCreateMultipart) (o *Object, err error) {
input := &service.InitiateMultipartUploadInput{}
if opt.HasEncryptionCustomerAlgorithm {
Expand All @@ -137,10 +182,6 @@ func (s *Storage) createMultipart(ctx context.Context, path string, opt pairStor
o.Path = path
o.Mode |= ModePart
o.SetMultipartID(*output.UploadID)
// set multipart restriction
o.SetMultipartNumberMaximum(multipartNumberMaximum)
o.SetMultipartSizeMaximum(multipartSizeMaximum)
o.SetMultipartSizeMinimum(multipartSizeMinimum)

return o, nil
}
Expand All @@ -163,6 +204,15 @@ func (s *Storage) delete(ctx context.Context, path string, opt pairStorageDelete
return
}

if opt.HasObjectMode && opt.ObjectMode.IsDir() {
if !s.features.VirtualDir {
err = services.PairUnsupportedError{Pair: ps.WithObjectMode(opt.ObjectMode)}
return
}

rp += "/"
}

// QingStor DeleteObject is idempotent, so we don't need to check object_not_exists error.
//
// - [GSP-46](https://github.com/beyondstorage/specs/blob/master/rfcs/46-idempotent-delete.md)
Expand Down Expand Up @@ -219,6 +269,17 @@ func (s *Storage) metadata(opt pairStorageMetadata) (meta *StorageMeta) {
meta.Name = *s.properties.BucketName
meta.WorkDir = s.workDir
meta.SetLocation(*s.properties.Zone)
// set write restriction
meta.SetWriteSizeMaximum(writeSizeMaximum)
// set copy restriction
meta.SetCopySizeMaximum(copySizeMaximum)
// set append restrictions
meta.SetAppendSizeMaximum(appendSizeMaximum)
meta.SetAppendTotalSizeMaximum(appendTotalSizeMaximum)
// set multipart restrictions
meta.SetMultipartNumberMaximum(multipartNumberMaximum)
meta.SetMultipartSizeMaximum(multipartSizeMaximum)
meta.SetMultipartSizeMinimum(multipartSizeMinimum)
return meta
}

Expand Down Expand Up @@ -462,6 +523,15 @@ func (s *Storage) stat(ctx context.Context, path string, opt pairStorageStat) (o
return o, nil
}

if opt.HasObjectMode && opt.ObjectMode.IsDir() {
if !s.features.VirtualDir {
err = services.PairUnsupportedError{Pair: ps.WithObjectMode(opt.ObjectMode)}
return
}

rp += "/"
}

input := &service.HeadObjectInput{}
output, err := s.bucket.HeadObjectWithContext(ctx, rp, input)
if err != nil {
Expand All @@ -471,7 +541,11 @@ func (s *Storage) stat(ctx context.Context, path string, opt pairStorageStat) (o
o = s.newObject(true)
o.ID = rp
o.Path = path
o.Mode |= ModeRead
if opt.HasObjectMode && opt.ObjectMode.IsDir() {
o.Mode |= ModeDir
} else {
o.Mode |= ModeRead
}

o.SetContentLength(service.Int64Value(output.ContentLength))
o.SetLastModified(service.TimeValue(output.LastModified))
Expand All @@ -483,19 +557,24 @@ func (s *Storage) stat(ctx context.Context, path string, opt pairStorageStat) (o
o.SetEtag(service.StringValue(output.ETag))
}

var sm ObjectMetadata
var sm ObjectSystemMetadata
if v := service.StringValue(output.XQSStorageClass); v != "" {
sm.StorageClass = v
}
if v := service.StringValue(output.XQSEncryptionCustomerAlgorithm); v != "" {
sm.EncryptionCustomerAlgorithm = v
}
o.SetServiceMetadata(sm)
o.SetSystemMetadata(sm)

return o, nil
}

func (s *Storage) write(ctx context.Context, path string, r io.Reader, size int64, opt pairStorageWrite) (n int64, err error) {
if size > writeSizeMaximum {
err = fmt.Errorf("size limit exceeded: %w", services.ErrRestrictionDissatisfied)
return
}

if opt.HasIoCallback {
r = iowrap.CallbackReader(r, opt.IoCallback)
}
Expand Down Expand Up @@ -527,6 +606,11 @@ func (s *Storage) write(ctx context.Context, path string, r io.Reader, size int6
}

func (s *Storage) writeAppend(ctx context.Context, o *Object, r io.Reader, size int64, opt pairStorageWriteAppend) (n int64, err error) {
if size > appendSizeMaximum {
err = fmt.Errorf("size limit exceeded: %w", services.ErrRestrictionDissatisfied)
return
}

rp := o.GetID()

offset, _ := o.GetAppendOffset()
Expand Down Expand Up @@ -560,6 +644,11 @@ func (s *Storage) writeMultipart(ctx context.Context, o *Object, r io.Reader, si
err = ErrPartNumberInvalid
return
}
if size > multipartSizeMaximum {
err = fmt.Errorf("size limit exceeded: %w", services.ErrRestrictionDissatisfied)
return
}

input := &service.UploadMultipartInput{
PartNumber: service.Int(index),
UploadID: service.String(o.MustGetMultipartID()),
Expand Down
2 changes: 1 addition & 1 deletion storager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ func TestStorage_Stat(t *testing.T) {
assert.True(t, ok)
assert.Equal(t, "test_etag", checkSum)

om := GetObjectMetadata(o)
om := GetObjectSystemMetadata(o)
assert.Equal(t, StorageClassStandard, om.StorageClass)
}
}
Expand Down
7 changes: 7 additions & 0 deletions tests/storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,10 @@ func TestAppend(t *testing.T) {
}
tests.TestAppender(t, setupTest(t))
}

func TestDirer(t *testing.T) {
if os.Getenv("STORAGE_QINGSTOR_INTEGRATION_TEST") != "on" {
t.Skipf("STORAGE_QINGSTOR_INTEGRATION_TEST is not 'on', skipped")
}
tests.TestDirer(t, setupTest(t))
}
3 changes: 3 additions & 0 deletions tests/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ func setupTest(t *testing.T) types.Storager {
ps.WithEndpoint(os.Getenv("STORAGE_QINGSTOR_ENDPOINT")),
ps.WithName(os.Getenv("STORAGE_QINGSTOR_NAME")),
ps.WithWorkDir("/"+uuid.New().String()+"/"),
qingstor.WithStorageFeatures(qingstor.StorageFeatures{
VirtualDir: true,
}),
)
if err != nil {
t.Errorf("new storager: %v", err)
Expand Down
Loading

0 comments on commit 7c850b2

Please sign in to comment.