From b9da5c166e804ae25bc28e24e535ac080831a4ea Mon Sep 17 00:00:00 2001 From: stulzq Date: Wed, 23 Feb 2022 20:16:39 +0800 Subject: [PATCH 1/6] add file api impl tencent cloud oss --- cmd/layotto/main.go | 2 + cmd/layotto_multiple_api/main.go | 2 + components/file/s3/tencentcloud/oss.go | 303 ++++++++++++++++++ components/file/s3/tencentcloud/oss_test.go | 54 ++++ components/go.mod | 1 + components/go.sum | 9 + configs/config_file_tencentcloud_oss.json | 50 +++ demo/file/tencentcloud/client.go | 169 ++++++++++ .../file/images/create_tencent_oss_bucket.png | Bin 0 -> 109204 bytes .../component_specs/file/tencentcloud_oss.md | 48 +++ go.sum | 24 +- 11 files changed, 646 insertions(+), 16 deletions(-) create mode 100644 components/file/s3/tencentcloud/oss.go create mode 100644 components/file/s3/tencentcloud/oss_test.go create mode 100644 configs/config_file_tencentcloud_oss.json create mode 100644 demo/file/tencentcloud/client.go create mode 100644 docs/zh/component_specs/file/images/create_tencent_oss_bucket.png create mode 100644 docs/zh/component_specs/file/tencentcloud_oss.md diff --git a/cmd/layotto/main.go b/cmd/layotto/main.go index 822a4a8270..5968f460e6 100644 --- a/cmd/layotto/main.go +++ b/cmd/layotto/main.go @@ -28,6 +28,7 @@ import ( secretstore_env "github.com/dapr/components-contrib/secretstores/local/env" secretstore_file "github.com/dapr/components-contrib/secretstores/local/file" "mosn.io/api" + "mosn.io/layotto/components/file/s3/tencentcloud" component_actuators "mosn.io/layotto/components/pkg/actuators" "mosn.io/layotto/diagnostics" "mosn.io/layotto/pkg/grpc/default_api" @@ -221,6 +222,7 @@ func NewRuntimeGrpcServer(data json.RawMessage, opts ...grpc.ServerOption) (mgrp file.NewFileFactory("aliOSS", alicloud.NewAliCloudOSS), file.NewFileFactory("minioOSS", minio.NewMinioOss), file.NewFileFactory("awsOSS", aws.NewAwsOss), + file.NewFileFactory("tencentCloudOSS", tencentcloud.NewTencentCloudOSS), file.NewFileFactory("local", local.NewLocalStore), ), diff --git a/cmd/layotto_multiple_api/main.go b/cmd/layotto_multiple_api/main.go index f4a158fa72..66596a1c71 100644 --- a/cmd/layotto_multiple_api/main.go +++ b/cmd/layotto_multiple_api/main.go @@ -20,6 +20,7 @@ import ( "encoding/json" "mosn.io/api" helloworld_api "mosn.io/layotto/cmd/layotto_multiple_api/helloworld" + "mosn.io/layotto/components/file/s3/tencentcloud" component_actuators "mosn.io/layotto/components/pkg/actuators" l8_grpc "mosn.io/layotto/pkg/grpc" "mosn.io/layotto/pkg/grpc/dapr" @@ -218,6 +219,7 @@ func NewRuntimeGrpcServer(data json.RawMessage, opts ...grpc.ServerOption) (mgrp file.NewFileFactory("aliOSS", alicloud.NewAliCloudOSS), file.NewFileFactory("minioOSS", minio.NewMinioOss), file.NewFileFactory("awsOSS", aws.NewAwsOss), + file.NewFileFactory("tencentCloudOSS", tencentcloud.NewTencentCloudOSS), file.NewFileFactory("local", local.NewLocalStore), ), diff --git a/components/file/s3/tencentcloud/oss.go b/components/file/s3/tencentcloud/oss.go new file mode 100644 index 0000000000..d42befb4e3 --- /dev/null +++ b/components/file/s3/tencentcloud/oss.go @@ -0,0 +1,303 @@ +/* + * Copyright 2021 Layotto Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tencentcloud + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strconv" + "strings" + "time" + + "github.com/pkg/errors" + "github.com/tencentyun/cos-go-sdk-v5" + + "mosn.io/layotto/components/file" +) + +const ( + endpointKey = "endpoint" + aclKey = "ACL" + contentTypeKey = "content-type" +) + +var ( + ErrClientNotExist = errors.New("specific client not exist") + ErrNotSpecifyEndPoint = errors.New("not specify endpoint in metadata") +) + +type TencentCloudOSS struct { + metadata map[string]*OssMetadata + client map[string]*cos.Client +} + +type OssMetadata struct { + Endpoint string `json:"endpoint"` // bucket url https://console.cloud.tencent.com/cos/bucket + AccessKeyID string `json:"accessKeyID"` // SecretID https://console.cloud.tencent.com/cam/capi + AccessKeySecret string `json:"accessKeySecret"` // SecretKey + Timeout int `json:"timeout"` // timeout in milliseconds + bucketUrl *url.URL +} + +func NewTencentCloudOSS() file.File { + oss := &TencentCloudOSS{metadata: make(map[string]*OssMetadata), client: make(map[string]*cos.Client)} + return oss +} + +// Init does metadata parsing and connection creation +func (t *TencentCloudOSS) Init(ctx context.Context, metadata *file.FileConfig) error { + m := make([]*OssMetadata, 0) + err := json.Unmarshal(metadata.Metadata, &m) + if err != nil { + return file.ErrInvalid + } + + for _, v := range m { + if !t.checkMetadata(v) { + return file.ErrInvalid + } + client, err := t.getClient(v) + if err != nil { + return err + } + t.metadata[v.Endpoint] = v + t.client[v.Endpoint] = client + } + return nil +} + +func (t *TencentCloudOSS) checkMetadata(m *OssMetadata) bool { + if m.AccessKeySecret == "" || m.Endpoint == "" || m.AccessKeyID == "" { + return false + } + + var endpoint = m.Endpoint + if !strings.HasPrefix(m.Endpoint, "http") { + endpoint = "https://" + m.Endpoint + } + + if bucketUrl, err := url.Parse(endpoint); err != nil { + return false + } else { + m.bucketUrl = bucketUrl + } + + if m.Timeout <= 0 { + m.Timeout = 100 * 1000 //100s + } + + return true +} + +func (t *TencentCloudOSS) getClient(metadata *OssMetadata) (*cos.Client, error) { + u, _ := url.Parse("https://" + metadata.Endpoint) + b := &cos.BaseURL{BucketURL: u} + client := cos.NewClient(b, &http.Client{ + //set timeout + Timeout: time.Duration(metadata.Timeout) * time.Millisecond, + Transport: &cos.AuthorizationTransport{ + SecretID: metadata.AccessKeyID, + SecretKey: metadata.AccessKeySecret, + }, + }) + + return client, nil +} + +func (t *TencentCloudOSS) Put(ctx context.Context, st *file.PutFileStu) error { + if err := t.checkFileName(st.FileName); err != nil { + return err + } + + client, err := t.selectClient(st.Metadata) + if err != nil { + return err + } + + opt := &cos.ObjectPutOptions{} + if v, ok := st.Metadata[contentTypeKey]; ok { + opt.ObjectPutHeaderOptions = &cos.ObjectPutHeaderOptions{ + ContentType: v, + } + } + + if v, ok := st.Metadata[aclKey]; ok { + opt.ACLHeaderOptions = &cos.ACLHeaderOptions{ + XCosACL: v, + } + } else { + opt.ACLHeaderOptions = &cos.ACLHeaderOptions{ + XCosACL: "public-read", + } + } + + _, err = client.Object.Put(ctx, st.FileName, st.DataStream, opt) + return err +} + +func (t *TencentCloudOSS) Get(ctx context.Context, st *file.GetFileStu) (io.ReadCloser, error) { + if err := t.checkFileName(st.FileName); err != nil { + return nil, err + } + + client, err := t.selectClient(st.Metadata) + if err != nil { + return nil, err + } + + clientResp, err := client.Object.Get(ctx, st.FileName, nil) + if err != nil { + return nil, err + } + + return clientResp.Body, nil +} + +func (t *TencentCloudOSS) List(ctx context.Context, st *file.ListRequest) (*file.ListResp, error) { + client, err := t.selectClient(st.Metadata) + if err != nil { + return nil, err + } + + if st.PageSize > 1000 { + return nil, errors.New("PageSize must be <=1000") + } + + if st.PageSize < 0 { + return nil, errors.New("PageSize must be >0") + } + + opt := &cos.BucketGetOptions{ + Prefix: st.DirectoryName, + Delimiter: "/", + MaxKeys: int(st.PageSize), + Marker: st.Marker, + } + + result, _, err := client.Bucket.Get(ctx, opt) + if err != nil { + return nil, err + } + + resp := &file.ListResp{} + resp.IsTruncated = result.IsTruncated + resp.Marker = result.NextMarker + + for _, v := range result.Contents { + file := &file.FilesInfo{} + file.FileName = v.Key + file.Size = v.Size + file.LastModified = v.LastModified + resp.Files = append(resp.Files, file) + } + + return resp, nil +} + +func (t *TencentCloudOSS) Del(ctx context.Context, st *file.DelRequest) error { + if err := t.checkFileName(st.FileName); err != nil { + return err + } + + client, err := t.selectClient(st.Metadata) + if err != nil { + return err + } + + _, err = client.Object.Delete(ctx, st.FileName) + return err +} + +func (t *TencentCloudOSS) Stat(ctx context.Context, st *file.FileMetaRequest) (*file.FileMetaResp, error) { + if err := t.checkFileName(st.FileName); err != nil { + return nil, err + } + + client, err := t.selectClient(st.Metadata) + if err != nil { + return nil, err + } + + var clientResp *cos.Response + clientResp, err = client.Object.Head(ctx, st.FileName, nil) + if err != nil { + if err.(*cos.ErrorResponse).Code == "404" { + return nil, file.ErrNotExist + } + + return nil, err + } + + fmt.Println(*clientResp) + resp := &file.FileMetaResp{} + resp.Metadata = make(map[string][]string) + for k, v := range clientResp.Header { + if k == "Content-Length" { + if len(v) > 0 { + l, err := strconv.Atoi(v[0]) + if err == nil { + resp.Size = int64(l) + } + } + continue + } + if k == "Last-Modified" { + if len(v) > 0 { + resp.LastModified = v[0] + } + continue + } + resp.Metadata[k] = append(resp.Metadata[k], v...) + } + + return resp, nil +} + +func (t *TencentCloudOSS) selectClient(meta map[string]string) (*cos.Client, error) { + var ( + endpoint string + ok bool + client *cos.Client + ) + if endpoint, ok = meta[endpointKey]; !ok { + if len(t.client) == 1 { + for _, client := range t.client { + return client, nil + } + } + return nil, ErrNotSpecifyEndPoint + } + + if client, ok = t.client[endpoint]; !ok { + return nil, ErrClientNotExist + } + + return client, nil +} + +func (t *TencentCloudOSS) checkFileName(fileName string) error { + index := strings.Index(fileName, "/") + if index == 0 { + return fmt.Errorf("invalid fileName format") + } + + return nil +} diff --git a/components/file/s3/tencentcloud/oss_test.go b/components/file/s3/tencentcloud/oss_test.go new file mode 100644 index 0000000000..421eb219f7 --- /dev/null +++ b/components/file/s3/tencentcloud/oss_test.go @@ -0,0 +1,54 @@ +package tencentcloud + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/tencentyun/cos-go-sdk-v5" + + "mosn.io/layotto/components/file" +) + +func TestInit(t *testing.T) { + data := `[ + { + "endpoint": "endpoint_address", + "accessKeyID": "accessKey", + "accessKeySecret": "secret" + } + ]` + fc := file.FileConfig{} + oss := NewTencentCloudOSS() + err := oss.Init(context.TODO(), &fc) + assert.Equal(t, err.Error(), "invalid argument") + fc.Metadata = []byte(data) + err = oss.Init(context.TODO(), &fc) + assert.Nil(t, err) +} + +func TestSelectClient(t *testing.T) { + ossObject := &TencentCloudOSS{metadata: make(map[string]*OssMetadata), client: make(map[string]*cos.Client)} + + meta := make(map[string]string) + client, err := ossObject.selectClient(meta) + assert.Equal(t, err.Error(), "not specify endpoint in metadata") + assert.Nil(t, client) + + client1 := &cos.Client{} + ossObject.client["127.0.0.1"] = client1 + client, err = ossObject.selectClient(meta) + assert.Equal(t, client, client1) + assert.Nil(t, err) + + client2 := &cos.Client{} + ossObject.client["0.0.0.0"] = client2 + client, err = ossObject.selectClient(meta) + assert.Equal(t, err.Error(), "not specify endpoint in metadata") + assert.Nil(t, client) + + meta[endpointKey] = "0.0.0.0" + client, err = ossObject.selectClient(meta) + assert.Equal(t, err, nil) + assert.NotNil(t, client) +} diff --git a/components/go.mod b/components/go.mod index 6f517f21b8..d5120a2ccd 100644 --- a/components/go.mod +++ b/components/go.mod @@ -22,6 +22,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/spf13/afero v1.2.2 // indirect github.com/stretchr/testify v1.7.0 + github.com/tencentyun/cos-go-sdk-v5 v0.7.33 // indirect github.com/valyala/fasthttp v1.26.0 github.com/zouyx/agollo/v4 v4.0.7 go.beyondstorage.io/services/hdfs v0.3.0 diff --git a/components/go.sum b/components/go.sum index e612bf2998..4708054b93 100644 --- a/components/go.sum +++ b/components/go.sum @@ -44,6 +44,7 @@ github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb0 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/SkyAPM/go2sky v0.5.0/go.mod h1:TANzYw5EvIlTidGWvQxtvO87rM6C746HkM0xkWqnPQw= @@ -339,6 +340,8 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -583,6 +586,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ= +github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -765,6 +770,10 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.194/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.194/go.mod h1:yrBKWhChnDqNz1xuXdSbWXG56XawEq0G5j1lg4VwBD4= +github.com/tencentyun/cos-go-sdk-v5 v0.7.33 h1:5jmJU7U/1nf/7ZPDkrUL8KlF1oDUzTHsdtLNY6x0hq4= +github.com/tencentyun/cos-go-sdk-v5 v0.7.33/go.mod h1:4E4+bQ2gBVJcgEC9Cufwylio4mXOct2iu05WjgEBx1o= github.com/tevid/gohamcrest v1.1.1 h1:ou+xSqlIw1xfGTg1uq1nif/htZ2S3EzRqLm2BP+tYU0= github.com/tevid/gohamcrest v1.1.1/go.mod h1:3UvtWlqm8j5JbwYZh80D/PVBt0mJ1eJiYgZMibh0H/k= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= diff --git a/configs/config_file_tencentcloud_oss.json b/configs/config_file_tencentcloud_oss.json new file mode 100644 index 0000000000..441d1ab2b4 --- /dev/null +++ b/configs/config_file_tencentcloud_oss.json @@ -0,0 +1,50 @@ +{ + "servers": [ + { + "default_log_path": "stdout", + "default_log_level": "DEBUG", + "listeners": [ + { + "name": "grpc", + "address": "127.0.0.1:34904", + "bind_port": true, + "filter_chains": [ + { + "filters": [ + { + "type": "grpc", + "config": { + "server_name": "runtime", + "grpc_config": { + "hellos": { + "helloworld": { + "hello": "greeting" + } + }, + "files": { + "tencentCloudOSS": { + "metadata": [ + { + "endpoint": "", + "accessKeyID": "", + "accessKeySecret": "", + "timeout": 10000 + } + ] + } + } + } + } + } + ] + } + ] + } + ] + } + ], + "pprof": { + "debug": true, + "port_value": 34902 + } +} \ No newline at end of file diff --git a/demo/file/tencentcloud/client.go b/demo/file/tencentcloud/client.go new file mode 100644 index 0000000000..aff4a2aff3 --- /dev/null +++ b/demo/file/tencentcloud/client.go @@ -0,0 +1,169 @@ +package main + +import ( + "context" + "fmt" + "os" + + "google.golang.org/grpc/codes" + + "google.golang.org/grpc/status" + + runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" + + "google.golang.org/grpc" +) + +func TestGet(fileName string) { + conn, err := grpc.Dial("127.0.0.1:34904", grpc.WithInsecure()) + if err != nil { + fmt.Printf("conn build failed,err:%+v", err) + return + } + + c := runtimev1pb.NewRuntimeClient(conn) + req := &runtimev1pb.GetFileRequest{StoreName: "tencentCloudOSS", Name: fileName} + cli, err := c.GetFile(context.Background(), req) + if err != nil { + fmt.Printf("get file error: %+v", err) + return + } + pic := make([]byte, 0, 0) + for { + resp, err := cli.Recv() + if err != nil { + fmt.Errorf("recv file failed") + break + } + pic = append(pic, resp.Data...) + } + fmt.Println(string(pic)) +} + +func TestPut(fileName string, value string) { + conn, err := grpc.Dial("127.0.0.1:34904", grpc.WithInsecure()) + if err != nil { + fmt.Printf("conn build failed,err:%+v", err) + return + } + meta := make(map[string]string) + c := runtimev1pb.NewRuntimeClient(conn) + req := &runtimev1pb.PutFileRequest{StoreName: "tencentCloudOSS", Name: fileName, Metadata: meta} + stream, err := c.PutFile(context.TODO()) + if err != nil { + fmt.Printf("put file failed:%+v", err) + return + } + req.Data = []byte(value) + stream.Send(req) + _, err = stream.CloseAndRecv() + if err != nil { + fmt.Printf("cannot receive response: %+v", err) + } +} + +func TestList(bucketName string) { + conn, err := grpc.Dial("127.0.0.1:34904", grpc.WithInsecure()) + if err != nil { + fmt.Printf("conn build failed,err:%+v", err) + return + } + meta := make(map[string]string) + meta["storageType"] = "Standard" + c := runtimev1pb.NewRuntimeClient(conn) + marker := "" + for { + req := &runtimev1pb.FileRequest{StoreName: "tencentCloudOSS", Name: bucketName, Metadata: meta} + listReq := &runtimev1pb.ListFileRequest{Request: req, PageSize: 1, Marker: marker} + resp, err := c.ListFile(context.Background(), listReq) + if err != nil { + fmt.Printf("list file fail, err: %+v", err) + return + } + marker = resp.Marker + if !resp.IsTruncated { + fmt.Printf("files under bucket is: %+v, %+v \n", resp.Files, marker) + fmt.Printf("finish list \n") + return + } + fmt.Printf("files under bucket is: %+v, %+v \n", resp.Files, marker) + } + +} + +func TestDel(fileName string) { + conn, err := grpc.Dial("127.0.0.1:34904", grpc.WithInsecure()) + if err != nil { + fmt.Printf("conn build failed,err:%+v", err) + return + } + meta := make(map[string]string) + meta["storageType"] = "Standard" + c := runtimev1pb.NewRuntimeClient(conn) + req := &runtimev1pb.FileRequest{StoreName: "tencentCloudOSS", Name: fileName, Metadata: meta} + listReq := &runtimev1pb.DelFileRequest{Request: req} + _, err = c.DelFile(context.Background(), listReq) + if err != nil { + fmt.Printf("list file fail, err: %+v \n", err) + return + } + fmt.Printf("delete file success \n") +} + +func TestStat(fileName string) { + conn, err := grpc.Dial("127.0.0.1:34904", grpc.WithInsecure()) + if err != nil { + fmt.Printf("conn build failed,err:%+v", err) + return + } + meta := make(map[string]string) + meta["storageType"] = "Standard" + c := runtimev1pb.NewRuntimeClient(conn) + req := &runtimev1pb.FileRequest{StoreName: "tencentCloudOSS", Name: fileName, Metadata: meta} + statReq := &runtimev1pb.GetFileMetaRequest{Request: req} + data, err := c.GetFileMeta(context.Background(), statReq) + //here use grpc error code check file exist or not. + if m, ok := status.FromError(err); ok { + if m.Code() == codes.NotFound { + fmt.Println("file not exist") + return + } else { + if m != nil { + fmt.Printf("stat file fail,err:%+v \n", err) + return + } + } + } + fmt.Printf("get meta data of file: size:%+v, modifyTime:%+v \n", data.Size, data.LastModified) + for k, v := range data.Response.Metadata { + fmt.Printf("metadata:key:%+v,value:%+v \n", k, v) + } + +} + +func main() { + if len(os.Args) < 3 { + fmt.Printf("you can use client like: client put/get/del/list fileName/directryName\n") + fmt.Println("eg:") + fmt.Println(" ./main put dir/a.txt aaa") + fmt.Println(" ./main get dir/a.txt") + fmt.Println(" ./main list dir/") + fmt.Println(" ./main del dir/a.txt") + return + } + if os.Args[1] == "put" { + TestPut(os.Args[2], os.Args[3]) + } + if os.Args[1] == "get" { + TestGet(os.Args[2]) + } + if os.Args[1] == "del" { + TestDel(os.Args[2]) + } + if os.Args[1] == "list" { + TestList(os.Args[2]) + } + if os.Args[1] == "stat" { + TestStat(os.Args[2]) + } +} diff --git a/docs/zh/component_specs/file/images/create_tencent_oss_bucket.png b/docs/zh/component_specs/file/images/create_tencent_oss_bucket.png new file mode 100644 index 0000000000000000000000000000000000000000..7d9efb6e1e6a5c4370788ba17b0f9fb4d3949c3a GIT binary patch literal 109204 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

Rj!iVT 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 Date: Wed, 23 Feb 2022 20:19:53 +0800 Subject: [PATCH 2/6] optimiza --- components/file/s3/tencentcloud/oss.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/file/s3/tencentcloud/oss.go b/components/file/s3/tencentcloud/oss.go index d42befb4e3..19d24d0e14 100644 --- a/components/file/s3/tencentcloud/oss.go +++ b/components/file/s3/tencentcloud/oss.go @@ -108,8 +108,7 @@ func (t *TencentCloudOSS) checkMetadata(m *OssMetadata) bool { } func (t *TencentCloudOSS) getClient(metadata *OssMetadata) (*cos.Client, error) { - u, _ := url.Parse("https://" + metadata.Endpoint) - b := &cos.BaseURL{BucketURL: u} + b := &cos.BaseURL{BucketURL: metadata.bucketUrl} client := cos.NewClient(b, &http.Client{ //set timeout Timeout: time.Duration(metadata.Timeout) * time.Millisecond, From e3b234630bc0ffd510b1dbb2400e6b5e17560989 Mon Sep 17 00:00:00 2001 From: stulzq Date: Wed, 23 Feb 2022 20:25:36 +0800 Subject: [PATCH 3/6] add license header --- components/file/s3/tencentcloud/oss_test.go | 16 ++++++++++++++++ demo/file/tencentcloud/client.go | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/components/file/s3/tencentcloud/oss_test.go b/components/file/s3/tencentcloud/oss_test.go index 421eb219f7..a030c95126 100644 --- a/components/file/s3/tencentcloud/oss_test.go +++ b/components/file/s3/tencentcloud/oss_test.go @@ -1,3 +1,19 @@ +/* + * Copyright 2021 Layotto Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package tencentcloud import ( diff --git a/demo/file/tencentcloud/client.go b/demo/file/tencentcloud/client.go index aff4a2aff3..b5f0e7720b 100644 --- a/demo/file/tencentcloud/client.go +++ b/demo/file/tencentcloud/client.go @@ -1,3 +1,19 @@ +/* + * Copyright 2021 Layotto Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package main import ( From bc9ebc4978918edb590b64fff725a1d2efa54a48 Mon Sep 17 00:00:00 2001 From: stulzq Date: Thu, 24 Feb 2022 11:19:34 +0800 Subject: [PATCH 4/6] fix: remove docs images to docs/img dir --- .../file}/create_tencent_oss_bucket.png | Bin docs/zh/component_specs/file/tencentcloud_oss.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename docs/{zh/component_specs/file/images => img/file}/create_tencent_oss_bucket.png (100%) diff --git a/docs/zh/component_specs/file/images/create_tencent_oss_bucket.png b/docs/img/file/create_tencent_oss_bucket.png similarity index 100% rename from docs/zh/component_specs/file/images/create_tencent_oss_bucket.png rename to docs/img/file/create_tencent_oss_bucket.png diff --git a/docs/zh/component_specs/file/tencentcloud_oss.md b/docs/zh/component_specs/file/tencentcloud_oss.md index 8af06a111e..e86997c2ef 100644 --- a/docs/zh/component_specs/file/tencentcloud_oss.md +++ b/docs/zh/component_specs/file/tencentcloud_oss.md @@ -19,7 +19,7 @@ 访问 https://console.cloud.tencent.com/cos/bucket 创建存储桶 -![](images/create_tencent_oss_bucket.png) +![](../../../img/file/create_tencent_oss_bucket.png) 3.创建 AK 和 SK From a10669c3a8b6ed6dc2cbe7bd06899d4f011f8e4a Mon Sep 17 00:00:00 2001 From: stulzq Date: Thu, 24 Feb 2022 21:46:52 +0800 Subject: [PATCH 5/6] add oss ut --- components/file/s3/tencentcloud/oss.go | 2 +- components/file/s3/tencentcloud/oss_test.go | 257 ++++++++++++++++++++ 2 files changed, 258 insertions(+), 1 deletion(-) diff --git a/components/file/s3/tencentcloud/oss.go b/components/file/s3/tencentcloud/oss.go index 19d24d0e14..6402ff902d 100644 --- a/components/file/s3/tencentcloud/oss.go +++ b/components/file/s3/tencentcloud/oss.go @@ -180,7 +180,7 @@ func (t *TencentCloudOSS) List(ctx context.Context, st *file.ListRequest) (*file return nil, errors.New("PageSize must be <=1000") } - if st.PageSize < 0 { + if st.PageSize <= 0 { return nil, errors.New("PageSize must be >0") } diff --git a/components/file/s3/tencentcloud/oss_test.go b/components/file/s3/tencentcloud/oss_test.go index a030c95126..8fc629aedc 100644 --- a/components/file/s3/tencentcloud/oss_test.go +++ b/components/file/s3/tencentcloud/oss_test.go @@ -18,6 +18,8 @@ package tencentcloud import ( "context" + "io" + "strings" "testing" "github.com/stretchr/testify/assert" @@ -41,6 +43,94 @@ func TestInit(t *testing.T) { fc.Metadata = []byte(data) err = oss.Init(context.TODO(), &fc) assert.Nil(t, err) + + tcOSS := oss.(*TencentCloudOSS) + mt := tcOSS.metadata["endpoint_address1"] + assert.Nil(t, mt) + + mt = tcOSS.metadata["endpoint_address"] + assert.Equal(t, "endpoint_address", mt.Endpoint) + assert.Equal(t, "secret", mt.AccessKeySecret) + assert.Equal(t, "accessKey", mt.AccessKeyID) + + client, ce := tcOSS.getClient(mt) + assert.NotNil(t, client) + assert.NoError(t, ce) +} + +func TestInitTimeout(t *testing.T) { + data := `[ + { + "endpoint": "endpoint_address", + "accessKeyID": "accessKey", + "accessKeySecret": "secret", + "timeout": 3000 + } + ]` + fc := file.FileConfig{} + oss := NewTencentCloudOSS() + err := oss.Init(context.TODO(), &fc) + assert.Equal(t, err.Error(), "invalid argument") + fc.Metadata = []byte(data) + err = oss.Init(context.TODO(), &fc) + assert.Nil(t, err) + + tcOSS := oss.(*TencentCloudOSS) + mt := tcOSS.metadata["endpoint_address"] + assert.NotNil(t, mt) + assert.Equal(t, 3000, mt.Timeout) +} + +func TestInitTimeoutReset(t *testing.T) { + data := `[ + { + "endpoint": "endpoint_address", + "accessKeyID": "accessKey", + "accessKeySecret": "secret", + "timeout": -1 + } + ]` + fc := file.FileConfig{} + oss := NewTencentCloudOSS() + err := oss.Init(context.TODO(), &fc) + assert.Equal(t, err.Error(), "invalid argument") + fc.Metadata = []byte(data) + err = oss.Init(context.TODO(), &fc) + assert.Nil(t, err) + + tcOSS := oss.(*TencentCloudOSS) + mt := tcOSS.metadata["endpoint_address"] + assert.NotNil(t, mt) + assert.Equal(t, 100*1000, mt.Timeout) +} + +func TestCheckMetadata(t *testing.T) { + oss := NewTencentCloudOSS() + tcOSS := oss.(*TencentCloudOSS) + + mt := &OssMetadata{} + assert.False(t, tcOSS.checkMetadata(mt)) + + mt.Endpoint = "1" + assert.False(t, tcOSS.checkMetadata(mt)) + + mt.AccessKeySecret = "2" + assert.False(t, tcOSS.checkMetadata(mt)) + + mt.AccessKeyID = "3" + assert.True(t, tcOSS.checkMetadata(mt)) + + mt.AccessKeySecret = "" + assert.False(t, tcOSS.checkMetadata(mt)) + + mt.AccessKeySecret = "x" + mt.Endpoint = "example.com" + tcOSS.checkMetadata(mt) + assert.Equal(t, "https", mt.bucketUrl.Scheme) + + mt.Endpoint = "http://example.com" + tcOSS.checkMetadata(mt) + assert.Equal(t, "http", mt.bucketUrl.Scheme) } func TestSelectClient(t *testing.T) { @@ -68,3 +158,170 @@ func TestSelectClient(t *testing.T) { assert.Equal(t, err, nil) assert.NotNil(t, client) } + +func TestPut(t *testing.T) { + data := `[ + { + "endpoint": "https://xxx-1251058690.cos.ap-chengdu.myqcloud.com", + "accessKeyID": "accessKey", + "accessKeySecret": "secret", + "timeout": 1000 + } + ]` + fc := file.FileConfig{} + oss := NewTencentCloudOSS() + fc.Metadata = []byte(data) + err := oss.Init(context.TODO(), &fc) + assert.Nil(t, err) + + st := &file.PutFileStu{ + FileName: "b/a.txt", + DataStream: strings.NewReader("aaaa"), + } + + err = oss.Put(context.Background(), st) + assert.Error(t, err) + assert.True(t, strings.Contains(err.Error(), "The specified bucket does not exist")) + + st.FileName = "/b/a.txt" + err = oss.Put(context.Background(), st) + assert.Error(t, err) +} + +func TestStat(t *testing.T) { + data := `[ + { + "endpoint": "https://xxx-1251058690.cos.ap-chengdu.myqcloud.com", + "accessKeyID": "accessKey", + "accessKeySecret": "secret", + "timeout": 1000 + } + ]` + fc := file.FileConfig{} + oss := NewTencentCloudOSS() + fc.Metadata = []byte(data) + err := oss.Init(context.TODO(), &fc) + assert.Nil(t, err) + + st := &file.FileMetaRequest{ + FileName: "b/a.txt", + } + + var resp *file.FileMetaResp + resp, err = oss.Stat(context.Background(), st) + assert.Error(t, err) + assert.True(t, strings.Contains(err.Error(), "404")) + assert.Nil(t, resp) + +} + +func TestList(t *testing.T) { + data := `[ + { + "endpoint": "https://xxx-1251058690.cos.ap-chengdu.myqcloud.com", + "accessKeyID": "accessKey", + "accessKeySecret": "secret", + "timeout": 1000 + } + ]` + fc := file.FileConfig{} + oss := NewTencentCloudOSS() + fc.Metadata = []byte(data) + err := oss.Init(context.TODO(), &fc) + assert.Nil(t, err) + + st := &file.ListRequest{ + DirectoryName: "/a", + PageSize: 10, + } + + var resp *file.ListResp + resp, err = oss.List(context.Background(), st) + assert.Error(t, err) + assert.True(t, strings.Contains(err.Error(), "404")) + assert.Nil(t, resp) + + st.PageSize = 1001 + resp, err = oss.List(context.Background(), st) + assert.Error(t, err) + assert.Equal(t, err.Error(), "PageSize must be <=1000") + assert.Nil(t, resp) + + st.PageSize = 0 + resp, err = oss.List(context.Background(), st) + assert.Error(t, err) + assert.Equal(t, err.Error(), "PageSize must be >0") + assert.Nil(t, resp) +} + +func TestGet(t *testing.T) { + data := `[ + { + "endpoint": "https://xxx-1251058690.cos.ap-chengdu.myqcloud.com", + "accessKeyID": "accessKey", + "accessKeySecret": "secret", + "timeout": 1000 + } + ]` + fc := file.FileConfig{} + oss := NewTencentCloudOSS() + fc.Metadata = []byte(data) + err := oss.Init(context.TODO(), &fc) + assert.Nil(t, err) + + st := &file.GetFileStu{ + FileName: "a.txt", + } + + var resp io.ReadCloser + resp, err = oss.Get(context.Background(), st) + assert.Error(t, err) + assert.True(t, strings.Contains(err.Error(), "404")) + assert.Nil(t, resp) +} + +func TestDel(t *testing.T) { + data := `[ + { + "endpoint": "https://xxx-1251058690.cos.ap-chengdu.myqcloud.com", + "accessKeyID": "accessKey", + "accessKeySecret": "secret", + "timeout": 1000 + } + ]` + fc := file.FileConfig{} + oss := NewTencentCloudOSS() + fc.Metadata = []byte(data) + err := oss.Init(context.TODO(), &fc) + assert.Nil(t, err) + + st := &file.DelRequest{ + FileName: "a.txt", + } + + err = oss.Del(context.Background(), st) + assert.Error(t, err) + assert.True(t, strings.Contains(err.Error(), "404")) +} + +func TestCheckFileName(t *testing.T) { + data := `[ + { + "endpoint": "https://xxx-1251058690.cos.ap-chengdu.myqcloud.com", + "accessKeyID": "accessKey", + "accessKeySecret": "secret", + "timeout": 1000 + } + ]` + fc := file.FileConfig{} + oss := NewTencentCloudOSS() + fc.Metadata = []byte(data) + err := oss.Init(context.TODO(), &fc) + assert.Nil(t, err) + + tcOSS := oss.(*TencentCloudOSS) + assert.Error(t, tcOSS.checkFileName("/")) + assert.Error(t, tcOSS.checkFileName("/a")) + assert.Nil(t, tcOSS.checkFileName("a")) + assert.Nil(t, tcOSS.checkFileName("a/aa.txt")) +} From c96040b42d94afcb2adad7d58de3e7d033a700b6 Mon Sep 17 00:00:00 2001 From: stulzq Date: Thu, 24 Feb 2022 22:41:03 +0800 Subject: [PATCH 6/6] fix ut --- components/file/s3/tencentcloud/oss.go | 4 ---- components/file/s3/tencentcloud/oss_test.go | 5 ----- 2 files changed, 9 deletions(-) diff --git a/components/file/s3/tencentcloud/oss.go b/components/file/s3/tencentcloud/oss.go index 6402ff902d..da6052aa8b 100644 --- a/components/file/s3/tencentcloud/oss.go +++ b/components/file/s3/tencentcloud/oss.go @@ -238,10 +238,6 @@ func (t *TencentCloudOSS) Stat(ctx context.Context, st *file.FileMetaRequest) (* var clientResp *cos.Response clientResp, err = client.Object.Head(ctx, st.FileName, nil) if err != nil { - if err.(*cos.ErrorResponse).Code == "404" { - return nil, file.ErrNotExist - } - return nil, err } diff --git a/components/file/s3/tencentcloud/oss_test.go b/components/file/s3/tencentcloud/oss_test.go index 8fc629aedc..27c8a9ba16 100644 --- a/components/file/s3/tencentcloud/oss_test.go +++ b/components/file/s3/tencentcloud/oss_test.go @@ -181,7 +181,6 @@ func TestPut(t *testing.T) { err = oss.Put(context.Background(), st) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "The specified bucket does not exist")) st.FileName = "/b/a.txt" err = oss.Put(context.Background(), st) @@ -210,7 +209,6 @@ func TestStat(t *testing.T) { var resp *file.FileMetaResp resp, err = oss.Stat(context.Background(), st) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "404")) assert.Nil(t, resp) } @@ -238,7 +236,6 @@ func TestList(t *testing.T) { var resp *file.ListResp resp, err = oss.List(context.Background(), st) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "404")) assert.Nil(t, resp) st.PageSize = 1001 @@ -276,7 +273,6 @@ func TestGet(t *testing.T) { var resp io.ReadCloser resp, err = oss.Get(context.Background(), st) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "404")) assert.Nil(t, resp) } @@ -301,7 +297,6 @@ func TestDel(t *testing.T) { err = oss.Del(context.Background(), st) assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "404")) } func TestCheckFileName(t *testing.T) {