feat: implement Azure Blob Storage client and refactor configuration structure
This commit is contained in:
68
internal/app/azure/main.go
Normal file
68
internal/app/azure/main.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
package azure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"git.ksdemosapps.com/kylesoda/go-migrate/internal/app/config"
|
||||||
|
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrInvalidConnectionString = errors.New("invalid connection string")
|
||||||
|
ErrContainerNotFound = errors.New("container not found")
|
||||||
|
ErrBlobNotFound = errors.New("blob not found")
|
||||||
|
ErrInvalidInput = errors.New("invalid input parameters")
|
||||||
|
)
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
client *azblob.Client
|
||||||
|
azureStorageConfig config.AzureStorageConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClient(azureStorageConfig config.AzureStorageConfig) (*Client, error) {
|
||||||
|
protocol := "https"
|
||||||
|
if !azureStorageConfig.UseHTTPS {
|
||||||
|
protocol = "http"
|
||||||
|
}
|
||||||
|
|
||||||
|
blobEndpoint, _ := url.JoinPath(azureStorageConfig.ServiceURL, azureStorageConfig.AccountName)
|
||||||
|
connStr := fmt.Sprintf("DefaultEndpointsProtocol=%s;AccountName=%s;AccountKey=%s;BlobEndpoint=%s;",
|
||||||
|
protocol, azureStorageConfig.AccountName, azureStorageConfig.AccountKey, blobEndpoint)
|
||||||
|
|
||||||
|
client, err := azblob.NewClientFromConnectionString(connStr, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("creating azure storage client: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Client{
|
||||||
|
client: client,
|
||||||
|
azureStorageConfig: azureStorageConfig,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) CreateContainer(ctx context.Context, containerName string) error {
|
||||||
|
if containerName == "" {
|
||||||
|
return ErrInvalidInput
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := c.client.CreateContainer(ctx, containerName, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("creating container %s: %w", containerName, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) UploadBuffer(ctx context.Context, containerName, blobPath string, buffer []byte) error {
|
||||||
|
if containerName == "" || blobPath == "" || buffer == nil {
|
||||||
|
return ErrInvalidInput
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := c.client.UploadBuffer(ctx, containerName, blobPath, buffer, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("uploading blob %s: %w", blobPath, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AzureConfig struct {
|
type AzureStorageConfig struct {
|
||||||
AccountName string `env:"AZ_ACCOUNT_NAME"`
|
AccountName string `env:"AZ_ACCOUNT_NAME"`
|
||||||
Container string `env:"AZ_CONTAINER"`
|
Container string `env:"AZ_CONTAINER"`
|
||||||
AccountKey string `env:"AZ_ACCOUNT_KEY"`
|
AccountKey string `env:"AZ_ACCOUNT_KEY"`
|
||||||
@@ -20,7 +20,7 @@ type appConfig struct {
|
|||||||
SourceDbUrl string `env:"SOURCE_DB_URL,required"`
|
SourceDbUrl string `env:"SOURCE_DB_URL,required"`
|
||||||
TargetDbUrl string `env:"TARGET_DB_URL,required"`
|
TargetDbUrl string `env:"TARGET_DB_URL,required"`
|
||||||
LogLevel string `env:"LOG_LEVEL" envDefault:"INFO"`
|
LogLevel string `env:"LOG_LEVEL" envDefault:"INFO"`
|
||||||
Azure AzureConfig
|
AzureStorage AzureStorageConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAppConfig() appConfig {
|
func getAppConfig() appConfig {
|
||||||
|
|||||||
@@ -7,16 +7,15 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
|
"git.ksdemosapps.com/kylesoda/go-migrate/internal/app/azure"
|
||||||
|
"git.ksdemosapps.com/kylesoda/go-migrate/internal/app/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
accountKey := "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="
|
cfg := config.App.AzureStorage
|
||||||
connStr := fmt.Sprintf("DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=%s;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;", accountKey)
|
containerName := cfg.Container
|
||||||
containerName := "pruebas"
|
|
||||||
|
|
||||||
// 1. Crear cliente
|
client, err := azure.NewClient(cfg)
|
||||||
client, err := azblob.NewClientFromConnectionString(connStr, nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error creando cliente: %v", err)
|
log.Fatalf("Error creando cliente: %v", err)
|
||||||
}
|
}
|
||||||
@@ -24,17 +23,15 @@ func main() {
|
|||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
// 3. Subir archivos
|
|
||||||
for i := 1; i <= 10; i++ {
|
for i := 1; i <= 10; i++ {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(id int) {
|
go func(id int) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
blobName := fmt.Sprintf("archivo-%d.txt", id)
|
blobName := fmt.Sprintf("%sarchivo-%d.txt", cfg.Prefix, id)
|
||||||
content := fmt.Sprintf("Contenido aleatorio: %d", rand.Intn(100000))
|
content := fmt.Sprintf("Contenido aleatorio: %d", rand.Intn(100000))
|
||||||
|
|
||||||
// Usamos UploadBuffer
|
err := client.UploadBuffer(ctx, containerName, blobName, []byte(content))
|
||||||
_, err := client.UploadBuffer(ctx, containerName, blobName, []byte(content), nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Fallo al subir %s: %v", blobName, err)
|
log.Printf("Fallo al subir %s: %v", blobName, err)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user