|
|
|
package storage
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"net/url"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/Masterminds/semver/v3"
|
|
|
|
"github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
|
|
|
|
"github.com/rocboss/paopao-ce/internal/core"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
_ core.ObjectStorageService = (*huaweiobsServant)(nil)
|
|
|
|
_ core.OssCreateService = (*hwobsCreateServant)(nil)
|
|
|
|
_ core.OssCreateService = (*hwobsCreateRetentionServant)(nil)
|
|
|
|
_ core.OssCreateService = (*hwobsCreateTempDirServant)(nil)
|
|
|
|
_ core.VersionInfo = (*huaweiobsServant)(nil)
|
|
|
|
)
|
|
|
|
|
|
|
|
type hwobsCreateServant struct {
|
|
|
|
client *obs.ObsClient
|
|
|
|
bucket string
|
|
|
|
domain string
|
|
|
|
}
|
|
|
|
|
|
|
|
type hwobsCreateRetentionServant struct {
|
|
|
|
client *obs.ObsClient
|
|
|
|
bucket string
|
|
|
|
domain string
|
|
|
|
retainInDays int64
|
|
|
|
retainUntilDays string
|
|
|
|
}
|
|
|
|
|
|
|
|
type hwobsCreateTempDirServant struct {
|
|
|
|
client *obs.ObsClient
|
|
|
|
bucket string
|
|
|
|
domain string
|
|
|
|
tempDir string
|
|
|
|
}
|
|
|
|
|
|
|
|
type huaweiobsServant struct {
|
|
|
|
core.OssCreateService
|
|
|
|
|
|
|
|
client *obs.ObsClient
|
|
|
|
bucket string
|
|
|
|
domain string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *hwobsCreateServant) PutObject(objectKey string, reader io.Reader, objectSize int64, contentType string, _persistance bool) (string, error) {
|
|
|
|
input := &obs.PutObjectInput{}
|
|
|
|
input.Bucket, input.Key, input.Body = s.bucket, objectKey, reader
|
|
|
|
input.ContentType, input.ContentLength = contentType, objectSize
|
|
|
|
_, err := s.client.PutObject(input)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return s.domain + objectKey, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *hwobsCreateServant) PersistObject(_objectKey string) error {
|
|
|
|
// empty
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *hwobsCreateRetentionServant) PutObject(objectKey string, reader io.Reader, objectSize int64, contentType string, persistance bool) (string, error) {
|
|
|
|
input := &obs.PutObjectInput{}
|
|
|
|
input.Bucket, input.Key, input.Body = s.bucket, objectKey, reader
|
|
|
|
input.ContentType, input.ContentLength = contentType, objectSize
|
|
|
|
if !persistance {
|
|
|
|
input.Expires = s.retainInDays
|
|
|
|
}
|
|
|
|
_, err := s.client.PutObject(input)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return s.domain + objectKey, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *hwobsCreateRetentionServant) PersistObject(objectKey string) error {
|
|
|
|
_, err := s.client.SetObjectMetadata(&obs.SetObjectMetadataInput{
|
|
|
|
Expires: s.retainUntilDays,
|
|
|
|
})
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *hwobsCreateTempDirServant) PutObject(objectKey string, reader io.Reader, objectSize int64, contentType string, persistance bool) (string, error) {
|
|
|
|
objectName := objectKey
|
|
|
|
if !persistance {
|
|
|
|
objectName = s.tempDir + objectKey
|
|
|
|
}
|
|
|
|
input := &obs.PutObjectInput{}
|
|
|
|
input.Bucket, input.Key, input.Body = s.bucket, objectName, reader
|
|
|
|
input.ContentType, input.ContentLength = contentType, objectSize
|
|
|
|
_, err := s.client.PutObject(input)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return s.domain + objectKey, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *hwobsCreateTempDirServant) PersistObject(objectKey string) error {
|
|
|
|
// is object exist that key equel objectKey
|
|
|
|
input := &obs.GetObjectMetadataInput{
|
|
|
|
Bucket: s.bucket,
|
|
|
|
Key: objectKey,
|
|
|
|
}
|
|
|
|
_, err := s.client.GetObjectMetadata(input)
|
|
|
|
if err == nil {
|
|
|
|
logrus.Debugf("object exist so do nothing objectKey: %s", objectKey)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpObjKey := s.tempDir + objectKey
|
|
|
|
copyInput := &obs.CopyObjectInput{
|
|
|
|
CopySourceBucket: s.bucket,
|
|
|
|
CopySourceKey: tmpObjKey,
|
|
|
|
}
|
|
|
|
copyInput.Bucket, copyInput.Key = s.bucket, objectKey
|
|
|
|
if _, err = s.client.CopyObject(copyInput); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = s.client.DeleteObject(&obs.DeleteObjectInput{
|
|
|
|
Bucket: s.bucket,
|
|
|
|
Key: tmpObjKey,
|
|
|
|
})
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *huaweiobsServant) DeleteObject(objectKey string) error {
|
|
|
|
_, err := s.client.DeleteObject(&obs.DeleteObjectInput{
|
|
|
|
Bucket: s.bucket,
|
|
|
|
Key: objectKey,
|
|
|
|
})
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *huaweiobsServant) DeleteObjects(objectKeys []string) error {
|
|
|
|
input := &obs.DeleteObjectsInput{
|
|
|
|
Bucket: s.bucket,
|
|
|
|
Objects: make([]obs.ObjectToDelete, 0, len(objectKeys)),
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, key := range objectKeys {
|
|
|
|
input.Objects = append(input.Objects, obs.ObjectToDelete{Key: key})
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err := s.client.DeleteObjects(input)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *huaweiobsServant) IsObjectExist(objectKey string) (bool, error) {
|
|
|
|
input := &obs.GetObjectMetadataInput{
|
|
|
|
Bucket: s.bucket,
|
|
|
|
Key: objectKey,
|
|
|
|
}
|
|
|
|
if _, err := s.client.GetObjectMetadata(input); err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *huaweiobsServant) SignURL(objectKey string, expiredInSec int64) (string, error) {
|
|
|
|
input := &obs.CreateSignedUrlInput{
|
|
|
|
Method: obs.HttpMethodGet,
|
|
|
|
Bucket: s.bucket,
|
|
|
|
Key: objectKey,
|
|
|
|
Expires: int(expiredInSec),
|
|
|
|
}
|
|
|
|
out, err := s.client.CreateSignedUrl(input)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Errorf("huaweiobsServant.SignURL err: %v", err)
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
ur, err := url.Parse(out.SignedUrl)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Errorf("url.Parse err: %v", err)
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
epath, err := url.PathUnescape(ur.Path)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Errorf("url.PathUnescape err: %v", err)
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
ur.Path, ur.RawPath = epath, epath
|
|
|
|
return ur.String(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *huaweiobsServant) ObjectURL(objetKey string) string {
|
|
|
|
return s.domain + objetKey
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *huaweiobsServant) ObjectKey(objectUrl string) string {
|
|
|
|
return strings.Replace(objectUrl, s.domain, "", -1)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *huaweiobsServant) Name() string {
|
|
|
|
return "HuaweiOBS"
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *huaweiobsServant) Version() *semver.Version {
|
|
|
|
return semver.MustParse("v0.2.0")
|
|
|
|
}
|