weather/internal/storage/s3.go

76 lines
1.9 KiB
Go

package storage
import (
"context"
"fmt"
"go/weather/pkg/logger"
"io"
"time"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
"go.elastic.co/apm"
"go.elastic.co/apm/module/apmzap"
"go.uber.org/zap"
)
//AwsDefaultSection toml default section
type AwsDefaultSection struct {
// attribute should be public ! for go-toml
EndpointURL string `hcl:"endpoint_url"`
BucketName string `hcl:"bucket_name"`
}
//WeatherS3StorageConfig interface abstracting storageConfig
type WeatherS3StorageConfig struct {
AwsDefaultSection `hcl:",nested"`
Region string `hcl:"region"`
AwsAccessKeyID string `hcl:"aws_access_key_id"`
AwsSecretAccessKey string `hcl:"aws_secret_access_key"`
}
//s3Storage classe used to store oi.Reader to s3
type S3Storage struct {
logger *logger.WeatherLogger
Session *minio.Client
S3Config *WeatherS3StorageConfig
}
//NewS3Storage instanciate storage object
func NewS3Storage(log *logger.WeatherLogger, config *WeatherS3StorageConfig) *S3Storage {
s3 := S3Storage{
logger: log,
S3Config: config,
}
var err error
// Initialize minio client object.
s3.Session, err = minio.New(config.EndpointURL, &minio.Options{
Region: config.Region,
Creds: credentials.NewStaticV4(config.AwsAccessKeyID, config.AwsSecretAccessKey, ""),
Secure: false,
})
if err != nil {
s3.logger.Fatal("Storage error", zap.Error(err))
}
return &s3
}
//Store send data to s3 bucket
func (ss *S3Storage) Store(ctx context.Context, content io.Reader) {
span, ctx := apm.StartSpan(ctx, "s3StoreWeatherInfo", "custom")
defer span.End()
name := fmt.Sprintf("%s.json", time.Now().UTC().Format(time.RFC3339))
_, err := ss.Session.PutObject(ctx, ss.S3Config.BucketName, name, content, -1, minio.PutObjectOptions{
ContentType: "application/json",
})
if err != nil {
ss.logger.Error("Storage error", zap.Error(err))
} else {
ss.logger.Debug("Storage success", apmzap.TraceContext(ctx)...)
}
}