package storage import ( "context" "io" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" ) type MinioClient struct { client *minio.Client bucketName string } func NewMinioClient(config *Config) (*MinioClient, error) { if config.Endpoint == "" { return nil, NewError("initialize", ErrInvalidConfig, "endpoint is required") } client, err := minio.New(config.Endpoint, &minio.Options{ Creds: credentials.NewStaticV4(config.AccessKeyID, config.SecretAccessKey, ""), Secure: config.UseSSL, }) if err != nil { return nil, NewError("create_client", ErrClientInitFailed, err.Error()) } // Ensure bucket exists ctx := context.Background() exists, err := client.BucketExists(ctx, config.BucketName) if err != nil { return nil, NewBucketError("check_bucket", config.BucketName, err, "failed to check bucket existence") } if !exists { err = client.MakeBucket(ctx, config.BucketName, minio.MakeBucketOptions{}) if err != nil { return nil, NewBucketError("create_bucket", config.BucketName, ErrBucketCreationFailed, err.Error()) } } return &MinioClient{ client: client, bucketName: config.BucketName, }, nil } // Client returns the underlying Minio client func (m *MinioClient) Client() *minio.Client { return m.client } // BucketName returns the name of the bucket func (m *MinioClient) BucketName() string { return m.bucketName } // PutObject is a helper method to upload an object to the bucket func (m *MinioClient) PutObject(ctx context.Context, objectName string, reader io.Reader, objectSize int64, opts minio.PutObjectOptions) (minio.UploadInfo, error) { if objectName == "" { return minio.UploadInfo{}, NewError("put_object", ErrInvalidObjectName, "object name is required") } if objectSize < 0 { return minio.UploadInfo{}, NewError("put_object", ErrInvalidObjectSize, "object size must be non-negative") } info, err := m.client.PutObject(ctx, m.bucketName, objectName, reader, objectSize, opts) if err != nil { return minio.UploadInfo{}, NewObjectError("put_object", m.bucketName, objectName, ErrUploadFailed, err.Error()) } return info, nil } // GetObject is a helper method to download an object from the bucket func (m *MinioClient) GetObject(ctx context.Context, objectName string, opts minio.GetObjectOptions) (*minio.Object, error) { if objectName == "" { return nil, NewError("get_object", ErrInvalidObjectName, "object name is required") } obj, err := m.client.GetObject(ctx, m.bucketName, objectName, opts) if err != nil { return nil, NewObjectError("get_object", m.bucketName, objectName, ErrDownloadFailed, err.Error()) } // Check if object exists by trying to get its stats _, err = obj.Stat() if err != nil { return nil, NewObjectError("get_object", m.bucketName, objectName, ErrObjectNotFound, "object does not exist") } return obj, nil }