Files
chain33-dtalk/pkg/oss/minio/minio.go
2022-03-17 15:59:24 +08:00

126 lines
3.2 KiB
Go

package minio
import (
"context"
"fmt"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
"github.com/pkg/errors"
"gitlab.33.cn/chat/dtalk/pkg/oss"
"io"
"sort"
)
var _ oss.Oss = (*Minio)(nil)
type Minio struct {
cfg *oss.Config
client *minio.Core
}
func New(cfg *oss.Config) *Minio {
m := &Minio{
cfg: cfg,
client: nil,
}
err := m.createClient()
if err != nil {
panic(err)
}
return m
}
func (m *Minio) Config() *oss.Config {
return m.cfg
}
func (m *Minio) AssumeRole() (*oss.AssumeRoleResp, error) {
return nil, errors.New("minio not support assume role")
}
func (m *Minio) Upload(key string, body io.Reader, size int64) (url, uri string, err error) {
ctx := context.Background()
_, err = m.client.PutObject(ctx, m.cfg.Bucket, key, body, size, "", "", minio.PutObjectOptions{})
if err != nil {
return "", "", errors.WithMessage(err, "minio.client.PutObject")
}
return m.parseUrl(key), m.parseUri(key), nil
}
func (m *Minio) InitiateMultipartUpload(key string) (uploadId string, err error) {
ctx := context.Background()
uploadId, err = m.client.NewMultipartUpload(ctx, m.cfg.Bucket, key, minio.PutObjectOptions{})
if err != nil {
return "", errors.WithMessage(err, "minio.client.NewMultipartUpload")
}
return uploadId, nil
}
func (m *Minio) UploadPart(key, uploadId string, body io.Reader, partNumber int32, offset,
partSize int64) (ETag string, err error) {
ctx := context.Background()
output, err := m.client.PutObjectPart(ctx, m.cfg.Bucket, key, uploadId, int(partNumber), body, partSize, "", "", nil)
if err != nil {
return "", errors.WithMessage(err, "minio.client.PutObjectPart")
}
return output.ETag, nil
}
func (m *Minio) CompleteMultipartUpload(key, uploadId string, parts []oss.Part) (url, uri string, err error) {
ctx := context.Background()
minioParts := make([]minio.CompletePart, len(parts), len(parts))
sort.Sort(oss.Parts(parts))
for i := range parts {
minioParts[i] = minio.CompletePart{
ETag: parts[i].ETag,
PartNumber: int(parts[i].PartNumber),
}
}
_, err = m.client.CompleteMultipartUpload(ctx, m.cfg.Bucket, key, uploadId, minioParts, minio.PutObjectOptions{})
if err != nil {
return "", "", errors.WithMessage(err, "minio.client.CompleteMultipartUpload")
}
return m.parseUrl(key), m.parseUri(key), nil
}
func (m *Minio) AbortMultipartUpload(key, uploadId string) error {
ctx := context.Background()
err := m.client.AbortMultipartUpload(ctx, m.cfg.Bucket, key, uploadId)
if err != nil {
return errors.WithMessage(err, "minio.client.AbortMultipartUpload")
}
return nil
}
func (m *Minio) createClient() (err error) {
m.client, err = minio.NewCore(
m.cfg.EndPoint,
&minio.Options{
Creds: credentials.NewStaticV4(m.cfg.AccessKeyId, m.cfg.AccessKeySecret, ""),
// todo
Secure: false,
})
if err != nil {
return errors.WithMessage(err, "minio minio.NewCore")
}
return nil
}
// parseUrl 获取对象在 minio 上的完整访问URL
func (m *Minio) parseUrl(key string) string {
return fmt.Sprintf("%s/%s/%s", m.cfg.PublicUrl, m.cfg.Bucket, key)
}
// parseUri ...
func (m *Minio) parseUri(key string) string {
return fmt.Sprintf("/%s/%s", m.cfg.Bucket, key)
}
// GetHost ...
func (m *Minio) GetHost() string {
return fmt.Sprintf("http://%s", m.cfg.EndPoint)
}