Skip to content

Commit

Permalink
feat(minio): add expiry tag and rule
Browse files Browse the repository at this point in the history
  • Loading branch information
joremysh committed Oct 25, 2024
1 parent e96ce6b commit 20cdb1a
Show file tree
Hide file tree
Showing 3 changed files with 386 additions and 246 deletions.
115 changes: 102 additions & 13 deletions minio/minio.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,36 @@ import (
)

type MinioI interface {
UploadFile(ctx context.Context, logger *zap.Logger, filePath string, fileContent any, fileMimeType string) (url string, objectInfo *miniogo.ObjectInfo, err error)
UploadFileBytes(ctx context.Context, logger *zap.Logger, filePath string, fileBytes []byte, fileMimeType string) (url string, objectInfo *miniogo.ObjectInfo, err error)
UploadFile(ctx context.Context, logger *zap.Logger, param *UploadFileParam) (url string, objectInfo *miniogo.ObjectInfo, err error)
UploadFileBytes(ctx context.Context, logger *zap.Logger, param *UploadFileBytesParam) (url string, objectInfo *miniogo.ObjectInfo, err error)
DeleteFile(ctx context.Context, logger *zap.Logger, filePath string) (err error)
GetFile(ctx context.Context, logger *zap.Logger, filePath string) ([]byte, error)
GetFilesByPaths(ctx context.Context, logger *zap.Logger, filePaths []string) ([]FileContent, error)
}

const Location = "us-east-1"
type ExpiryGroup string

func (g ExpiryGroup) String() string {
return string(g)
}

const (
Location = "us-east-1"

StatusEnabled = "Enabled"
ExpiryTag = "expiry-group"

FreePlanExpiry ExpiryGroup = "free-plan-expiry"
ProPlanExpiry ExpiryGroup = "pro-plan-expiry"
TeamPlanExpiry ExpiryGroup = "team-plan-expiry"
EnterprisePlanExpiry ExpiryGroup = "enterprise-plan-expiry"
)

var expiryTimeConfig = map[ExpiryGroup]int{
FreePlanExpiry: 3,
ProPlanExpiry: 7,
TeamPlanExpiry: 30,
}

type minio struct {
client *miniogo.Client
Expand Down Expand Up @@ -71,12 +93,52 @@ func NewMinioClientAndInitBucket(ctx context.Context, cfg *Config, logger *zap.L
lccfg.Rules = []lifecycle.Rule{
{
ID: "expire-bucket-objects",
Status: "Enabled",
Status: StatusEnabled,
Expiration: lifecycle.Expiration{
Days: lifecycle.ExpirationDays(30),
},
},
{
ID: "free-plan-rule",
Status: StatusEnabled,
Expiration: lifecycle.Expiration{
Days: lifecycle.ExpirationDays(expiryTimeConfig[FreePlanExpiry]),
},
RuleFilter: lifecycle.Filter{
Tag: lifecycle.Tag{
Key: ExpiryTag,
Value: FreePlanExpiry.String(),
},
},
},
{
ID: "pro-plan-rule",
Status: StatusEnabled,
Expiration: lifecycle.Expiration{
Days: lifecycle.ExpirationDays(expiryTimeConfig[ProPlanExpiry]),
},
RuleFilter: lifecycle.Filter{
Tag: lifecycle.Tag{
Key: ExpiryTag,
Value: ProPlanExpiry.String(),
},
},
},
{
ID: "team-plan-rule",
Status: StatusEnabled,
Expiration: lifecycle.Expiration{
Days: lifecycle.ExpirationDays(expiryTimeConfig[TeamPlanExpiry]),
},
RuleFilter: lifecycle.Filter{
Tag: lifecycle.Tag{
Key: ExpiryTag,
Value: TeamPlanExpiry.String(),
},
},
},
}

err = client.SetBucketLifecycle(ctx, cfg.BucketName, lccfg)
if err != nil {
logger.Error("setting Bucket lifecycle failed", zap.Error(err))
Expand All @@ -86,30 +148,57 @@ func NewMinioClientAndInitBucket(ctx context.Context, cfg *Config, logger *zap.L
return &minio{client: client, bucket: cfg.BucketName}, nil
}

func (m *minio) UploadFile(ctx context.Context, logger *zap.Logger, filePath string, fileContent any, fileMimeType string) (url string, objectInfo *miniogo.ObjectInfo, err error) {
jsonData, _ := json.Marshal(fileContent)
return m.UploadFileBytes(ctx, logger, filePath, jsonData, fileMimeType)
type UploadFileParam struct {
FilePath string
FileContent any
FileMimeType string
ExpiryGroup ExpiryGroup
}

func (m *minio) UploadFileBytes(ctx context.Context, logger *zap.Logger, filePath string, fileBytes []byte, fileMimeType string) (url string, objectInfo *miniogo.ObjectInfo, err error) {
logger.Info("start to upload file to minio", zap.String("filePath", filePath))
reader := bytes.NewReader(fileBytes)
type UploadFileBytesParam struct {
FilePath string
FileBytes []byte
FileMimeType string
ExpiryGroup ExpiryGroup
}

func (m *minio) UploadFile(ctx context.Context, logger *zap.Logger, param *UploadFileParam) (url string, objectInfo *miniogo.ObjectInfo, err error) {
jsonData, _ := json.Marshal(param.FileContent)
return m.UploadFileBytes(ctx, logger, &UploadFileBytesParam{
FilePath: param.FilePath,
FileBytes: jsonData,
FileMimeType: param.FileMimeType,
ExpiryGroup: param.ExpiryGroup,
})
}

func (m *minio) UploadFileBytes(ctx context.Context, logger *zap.Logger, param *UploadFileBytesParam) (url string, objectInfo *miniogo.ObjectInfo, err error) {
logger.Info("start to upload file to minio", zap.String("filePath", param.FilePath))
reader := bytes.NewReader(param.FileBytes)

// Create the file path with folder structure
_, err = m.client.PutObject(ctx, m.bucket, filePath, reader, int64(len(fileBytes)), miniogo.PutObjectOptions{ContentType: fileMimeType})
_, err = m.client.PutObject(ctx, m.bucket, param.FilePath, reader, int64(len(param.FileBytes)), miniogo.PutObjectOptions{
ContentType: param.FileMimeType,
UserTags: map[string]string{ExpiryTag: param.ExpiryGroup.String()},
})
if err != nil {
logger.Error("Failed to upload file to MinIO", zap.Error(err))
return "", nil, err
}

// Get the object stat (metadata)
stat, err := m.client.StatObject(ctx, m.bucket, filePath, miniogo.StatObjectOptions{})
stat, err := m.client.StatObject(ctx, m.bucket, param.FilePath, miniogo.StatObjectOptions{})
if err != nil {
return "", nil, err
}

// Generate the presigned URL
presignedURL, err := m.client.PresignedGetObject(ctx, m.bucket, filePath, time.Hour*24*7, nil)
expiryDays, ok := expiryTimeConfig[param.ExpiryGroup]
if !ok {
expiryDays = 30
}
expiryDuration := time.Hour * 24 * time.Duration(expiryDays)
presignedURL, err := m.client.PresignedGetObject(ctx, m.bucket, param.FilePath, expiryDuration, nil)
if err != nil {
return "", nil, err
}
Expand Down
7 changes: 6 additions & 1 deletion minio/minio_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ func TestMinio(t *testing.T) {
data["uid"] = uid.String()
jsonBytes, _ := json.Marshal(data)

url, stat, err := mc.UploadFile(ctx, log, fileName.String(), data, "application/json")
url, stat, err := mc.UploadFile(ctx, log, &miniox.UploadFileParam{
FilePath: fileName.String(),
FileContent: data,
FileMimeType: "application/json",
ExpiryGroup: miniox.FreePlanExpiry,
})
require.NoError(t, err)
t.Log("url:", url)
t.Log("size:", stat.Size)
Expand Down
Loading

0 comments on commit 20cdb1a

Please sign in to comment.