// Copyright 2022 ROC. All rights reserved. // Use of this source code is governed by a MIT style // license that can be found in the LICENSE file. package storage import ( "io" "net/url" "strings" "time" "github.com/Masterminds/semver/v3" "github.com/aliyun/aliyun-oss-go-sdk/oss" "github.com/rocboss/paopao-ce/internal/core" "github.com/sirupsen/logrus" ) var ( _ core.ObjectStorageService = (*aliossServant)(nil) _ core.OssCreateService = (*aliossCreateServant)(nil) _ core.OssCreateService = (*aliossCreateRetentionServant)(nil) _ core.OssCreateService = (*aliossCreateTempDirServant)(nil) _ core.VersionInfo = (*aliossServant)(nil) ) type aliossCreateServant struct { bucket *oss.Bucket domain string } type aliossCreateRetentionServant struct { bucket *oss.Bucket domain string retainInDays time.Duration retainUntilDate time.Time } type aliossCreateTempDirServant struct { bucket *oss.Bucket domain string tempDir string } type aliossServant struct { core.OssCreateService bucket *oss.Bucket domain string } func (s *aliossCreateServant) PutObject(objectKey string, reader io.Reader, objectSize int64, contentType string, _persistance bool) (string, error) { options := []oss.Option{ oss.ContentLength(objectSize), oss.ContentType(contentType), } err := s.bucket.PutObject(objectKey, reader, options...) if err != nil { return "", err } return s.domain + objectKey, nil } func (s *aliossCreateServant) PersistObject(_objectKey string) error { // empty return nil } func (s *aliossCreateRetentionServant) PutObject(objectKey string, reader io.Reader, objectSize int64, contentType string, persistance bool) (string, error) { options := []oss.Option{ oss.ContentLength(objectSize), oss.ContentType(contentType), } if !persistance { options = append(options, oss.Expires(time.Now().Add(s.retainInDays))) } err := s.bucket.PutObject(objectKey, reader, options...) if err != nil { return "", err } return s.domain + objectKey, nil } func (s *aliossCreateRetentionServant) PersistObject(objectKey string) error { return s.bucket.SetObjectMeta(objectKey, oss.Expires(s.retainUntilDate)) } func (s *aliossCreateTempDirServant) PutObject(objectKey string, reader io.Reader, objectSize int64, contentType string, persistance bool) (string, error) { objectName := objectKey if !persistance { objectName = s.tempDir + objectKey } options := []oss.Option{ oss.ContentLength(objectSize), oss.ContentType(contentType), } err := s.bucket.PutObject(objectName, reader, options...) if err != nil { return "", err } return s.domain + objectKey, nil } func (s *aliossCreateTempDirServant) PersistObject(objectKey string) error { exsit, err := s.bucket.IsObjectExist(objectKey) if err != nil { return err } if exsit { logrus.Debugf("object exist so do nothing objectKey: %s", objectKey) return nil } if _, err := s.bucket.CopyObject(s.tempDir+objectKey, objectKey); err != nil { return err } return s.bucket.DeleteObject(s.tempDir + objectKey) } func (s *aliossServant) DeleteObject(objectKey string) error { return s.bucket.DeleteObject(objectKey) } func (s *aliossServant) DeleteObjects(objectKeys []string) error { _, err := s.bucket.DeleteObjects(objectKeys) return err } func (s *aliossServant) IsObjectExist(objectKey string) (bool, error) { return s.bucket.IsObjectExist(objectKey) } func (s *aliossServant) SignURL(objectKey string, expiredInSec int64) (string, error) { signedURL, err := s.bucket.SignURL(objectKey, oss.HTTPGet, expiredInSec) if err != nil { logrus.Errorf("client.SignURL err: %v", err) return "", err } ur, err := url.Parse(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 *aliossServant) ObjectURL(objetKey string) string { return s.domain + objetKey } func (s *aliossServant) ObjectKey(objectUrl string) string { return strings.Replace(objectUrl, s.domain, "", -1) } func (s *aliossServant) Name() string { return "AliOSS" } func (s *aliossServant) Version() *semver.Version { return semver.MustParse("v0.2.0") }