Skip to content

Commit 13f5154

Browse files
authored
feat: add file qiniu cloud oss (#401)
1 parent 8abb21d commit 13f5154

File tree

15 files changed

+1459
-19
lines changed

15 files changed

+1459
-19
lines changed

cmd/layotto/main.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import (
2828
secretstore_env "github.com/dapr/components-contrib/secretstores/local/env"
2929
secretstore_file "github.com/dapr/components-contrib/secretstores/local/file"
3030
"mosn.io/api"
31-
"mosn.io/layotto/components/file/s3/tencentcloud"
3231
component_actuators "mosn.io/layotto/components/pkg/actuators"
3332
"mosn.io/layotto/diagnostics"
3433
"mosn.io/layotto/pkg/grpc/default_api"
@@ -120,6 +119,10 @@ import (
120119
sequencer_redis "mosn.io/layotto/components/sequencer/redis"
121120
sequencer_zookeeper "mosn.io/layotto/components/sequencer/zookeeper"
122121

122+
// File
123+
"mosn.io/layotto/components/file/s3/qiniu"
124+
"mosn.io/layotto/components/file/s3/tencentcloud"
125+
123126
// Actuator
124127
_ "mosn.io/layotto/pkg/actuator"
125128
"mosn.io/layotto/pkg/actuator/health"
@@ -226,6 +229,7 @@ func NewRuntimeGrpcServer(data json.RawMessage, opts ...grpc.ServerOption) (mgrp
226229
file.NewFileFactory("awsOSS", aws.NewAwsOss),
227230
file.NewFileFactory("tencentCloudOSS", tencentcloud.NewTencentCloudOSS),
228231
file.NewFileFactory("local", local.NewLocalStore),
232+
file.NewFileFactory("qiniuOSS", qiniu.NewQiniuOSS),
229233
),
230234

231235
// PubSub

cmd/layotto_multiple_api/main.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"encoding/json"
2121
"mosn.io/api"
2222
helloworld_api "mosn.io/layotto/cmd/layotto_multiple_api/helloworld"
23-
"mosn.io/layotto/components/file/s3/tencentcloud"
2423
component_actuators "mosn.io/layotto/components/pkg/actuators"
2524
l8_grpc "mosn.io/layotto/pkg/grpc"
2625
"mosn.io/layotto/pkg/grpc/dapr"
@@ -112,6 +111,10 @@ import (
112111
sequencer_redis "mosn.io/layotto/components/sequencer/redis"
113112
sequencer_zookeeper "mosn.io/layotto/components/sequencer/zookeeper"
114113

114+
// File
115+
"mosn.io/layotto/components/file/s3/qiniu"
116+
"mosn.io/layotto/components/file/s3/tencentcloud"
117+
115118
// Actuator
116119
_ "mosn.io/layotto/pkg/actuator"
117120
"mosn.io/layotto/pkg/actuator/health"
@@ -223,6 +226,7 @@ func NewRuntimeGrpcServer(data json.RawMessage, opts ...grpc.ServerOption) (mgrp
223226
file.NewFileFactory("awsOSS", aws.NewAwsOss),
224227
file.NewFileFactory("tencentCloudOSS", tencentcloud.NewTencentCloudOSS),
225228
file.NewFileFactory("local", local.NewLocalStore),
229+
file.NewFileFactory("qiniuOSS", qiniu.NewQiniuOSS),
226230
),
227231

228232
// PubSub
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/*
2+
* Copyright 2021 Layotto Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package qiniu
18+
19+
import (
20+
"context"
21+
"errors"
22+
"fmt"
23+
"io"
24+
"net/http"
25+
"strings"
26+
"time"
27+
28+
"github.com/qiniu/go-sdk/v7/auth/qbox"
29+
"github.com/qiniu/go-sdk/v7/storage"
30+
)
31+
32+
type QiniuOSSClient struct {
33+
AccessKey string
34+
SecretKey string
35+
Bucket string
36+
Domain string
37+
Private bool
38+
39+
mac *qbox.Mac
40+
fu FormUploader
41+
bm BucketManager
42+
}
43+
44+
type FormUploader interface {
45+
Put(ctx context.Context, ret interface{}, uptoken, key string, data io.Reader, size int64, extra *storage.PutExtra) (err error)
46+
}
47+
48+
type BucketManager interface {
49+
Stat(bucket, key string) (storage.FileInfo, error)
50+
Delete(bucket, key string) (err error)
51+
ListFiles(bucket, prefix, delimiter, marker string,
52+
limit int) (entries []storage.ListItem, commonPrefixes []string, nextMarker string, hasNext bool, err error)
53+
}
54+
55+
func newQiniuOSSClient(ak, sk, bucket, domain string, private bool, useHttps, userCdnDomains bool) *QiniuOSSClient {
56+
cfg := storage.Config{
57+
UseHTTPS: useHttps,
58+
UseCdnDomains: userCdnDomains,
59+
}
60+
61+
mac := qbox.NewMac(ak, sk)
62+
s := &QiniuOSSClient{
63+
AccessKey: ak,
64+
SecretKey: sk,
65+
Bucket: bucket,
66+
fu: storage.NewFormUploader(&cfg),
67+
Domain: domain,
68+
Private: private,
69+
mac: mac,
70+
bm: storage.NewBucketManager(mac, &cfg),
71+
}
72+
return s
73+
}
74+
75+
func (s *QiniuOSSClient) put(ctx context.Context, fileName string, data io.Reader, dataSize int64) error {
76+
if err := s.checkFileName(fileName); err != nil {
77+
return err
78+
}
79+
80+
putPolicy := storage.PutPolicy{
81+
Scope: s.Bucket,
82+
}
83+
84+
upToken := putPolicy.UploadToken(qbox.NewMac(s.AccessKey, s.SecretKey))
85+
86+
ret := storage.PutRet{}
87+
err := s.fu.Put(ctx, &ret, upToken, fileName, data, dataSize, nil)
88+
89+
return err
90+
}
91+
92+
func (s *QiniuOSSClient) get(_ context.Context, fileName string) (io.ReadCloser, error) {
93+
if err := s.checkFileName(fileName); err != nil {
94+
return nil, err
95+
}
96+
97+
var accessUrl string
98+
99+
if !s.Private {
100+
accessUrl = storage.MakePublicURL(s.Domain, fileName)
101+
102+
} else {
103+
deadline := time.Now().Add(time.Second * 60).Unix() //1小时有效期
104+
accessUrl = storage.MakePrivateURL(s.mac, s.Domain, fileName, deadline)
105+
}
106+
107+
resp, err := http.Get(accessUrl)
108+
if err != nil {
109+
return nil, err
110+
}
111+
112+
return resp.Body, nil
113+
}
114+
115+
func (s *QiniuOSSClient) stat(_ context.Context, fileName string) (*storage.FileInfo, error) {
116+
if err := s.checkFileName(fileName); err != nil {
117+
return nil, err
118+
}
119+
120+
resp, err := s.bm.Stat(s.Bucket, fileName)
121+
return &resp, err
122+
}
123+
124+
func (s *QiniuOSSClient) del(_ context.Context, fileName string) error {
125+
if err := s.checkFileName(fileName); err != nil {
126+
return err
127+
}
128+
129+
return s.bm.Delete(s.Bucket, fileName)
130+
}
131+
132+
func (s *QiniuOSSClient) list(_ context.Context, prefix string, limit int, marker string) (entries []storage.ListItem, commonPrefixes []string, nextMarker string, hasNext bool, err error) {
133+
if limit > 1000 {
134+
return nil, nil, "", false, errors.New("limit must be <=1000")
135+
}
136+
137+
if limit <= 0 {
138+
return nil, nil, "", false, errors.New("limit must be >0")
139+
}
140+
141+
return s.bm.ListFiles(s.Bucket, prefix, "", marker, limit)
142+
}
143+
144+
func (s *QiniuOSSClient) checkFileName(fileName string) error {
145+
index := strings.Index(fileName, "/")
146+
if index == 0 {
147+
return fmt.Errorf("invalid fileName format")
148+
}
149+
150+
return nil
151+
}

0 commit comments

Comments
 (0)