minio.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package storage
  2. import (
  3. "context"
  4. "io"
  5. "github.com/minio/minio-go/v7"
  6. "github.com/minio/minio-go/v7/pkg/credentials"
  7. )
  8. type MinioClient struct {
  9. client *minio.Client
  10. bucketName string
  11. }
  12. func NewMinioClient(config *Config) (*MinioClient, error) {
  13. if config.Endpoint == "" {
  14. return nil, NewError("initialize", ErrInvalidConfig, "endpoint is required")
  15. }
  16. client, err := minio.New(config.Endpoint, &minio.Options{
  17. Creds: credentials.NewStaticV4(config.AccessKeyID, config.SecretAccessKey, ""),
  18. Secure: config.UseSSL,
  19. })
  20. if err != nil {
  21. return nil, NewError("create_client", ErrClientInitFailed, err.Error())
  22. }
  23. // Ensure bucket exists
  24. ctx := context.Background()
  25. exists, err := client.BucketExists(ctx, config.BucketName)
  26. if err != nil {
  27. return nil, NewBucketError("check_bucket", config.BucketName, err, "failed to check bucket existence")
  28. }
  29. if !exists {
  30. err = client.MakeBucket(ctx, config.BucketName, minio.MakeBucketOptions{})
  31. if err != nil {
  32. return nil, NewBucketError("create_bucket", config.BucketName, ErrBucketCreationFailed, err.Error())
  33. }
  34. }
  35. return &MinioClient{
  36. client: client,
  37. bucketName: config.BucketName,
  38. }, nil
  39. }
  40. // Client returns the underlying Minio client
  41. func (m *MinioClient) Client() *minio.Client {
  42. return m.client
  43. }
  44. // BucketName returns the name of the bucket
  45. func (m *MinioClient) BucketName() string {
  46. return m.bucketName
  47. }
  48. // PutObject is a helper method to upload an object to the bucket
  49. func (m *MinioClient) PutObject(ctx context.Context, objectName string, reader io.Reader, objectSize int64, opts minio.PutObjectOptions) (minio.UploadInfo, error) {
  50. if objectName == "" {
  51. return minio.UploadInfo{}, NewError("put_object", ErrInvalidObjectName, "object name is required")
  52. }
  53. if objectSize < 0 {
  54. return minio.UploadInfo{}, NewError("put_object", ErrInvalidObjectSize, "object size must be non-negative")
  55. }
  56. info, err := m.client.PutObject(ctx, m.bucketName, objectName, reader, objectSize, opts)
  57. if err != nil {
  58. return minio.UploadInfo{}, NewObjectError("put_object", m.bucketName, objectName, ErrUploadFailed, err.Error())
  59. }
  60. return info, nil
  61. }
  62. // GetObject is a helper method to download an object from the bucket
  63. func (m *MinioClient) GetObject(ctx context.Context, objectName string, opts minio.GetObjectOptions) (*minio.Object, error) {
  64. if objectName == "" {
  65. return nil, NewError("get_object", ErrInvalidObjectName, "object name is required")
  66. }
  67. obj, err := m.client.GetObject(ctx, m.bucketName, objectName, opts)
  68. if err != nil {
  69. return nil, NewObjectError("get_object", m.bucketName, objectName, ErrDownloadFailed, err.Error())
  70. }
  71. // Check if object exists by trying to get its stats
  72. _, err = obj.Stat()
  73. if err != nil {
  74. return nil, NewObjectError("get_object", m.bucketName, objectName, ErrObjectNotFound, "object does not exist")
  75. }
  76. return obj, nil
  77. }