admin_backend/middleware/alibaba/oss.go
hahwu ddae026231 ab test and notification
Co-authored-by: Copilot <copilot@github.com>
2026-04-24 17:23:55 +08:00

180 lines
4.8 KiB
Go

package alibaba
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"log"
"strings"
"sync"
"time"
"gitea.bywaystudios.com/pet_home/nacos"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
const (
defaultOSSRegion = "us-west-1"
defaultOSSBucket = "merge-pet-us"
defaultOSSObjectKey = "static/notification.json"
defaultNacosDataID = "oss.json"
defaultNacosGroup = "server"
defaultNacosLogDir = "./log/nacos"
defaultNacosCacheDir = "./runtime/nacos"
)
type ossConfig struct {
Region string `json:"region" yaml:"region"`
Bucket string `json:"bucket" yaml:"bucket"`
ObjectKey string `json:"objectKey" yaml:"objectKey"`
AccessKeyID string `json:"accessKeyId" yaml:"accessKeyId"`
AccessKeySecret string `json:"accessKeySecret" yaml:"accessKeySecret"`
SessionToken string `json:"sessionToken" yaml:"sessionToken"`
}
type ossRuntime struct {
mu sync.RWMutex
config ossConfig
}
var (
globalOSSRuntime ossRuntime
ossInitOnce sync.Once
dotenvLoadOnce sync.Once
ossCnf ossConfig
)
type OSSObjectContent struct {
Bucket string `json:"bucket"`
Key string `json:"key"`
Region string `json:"region"`
Config map[string]interface{} `json:"config"`
ContentType string `json:"contentType,omitempty"`
ETag string `json:"etag,omitempty"`
LastModified string `json:"lastModified,omitempty"`
}
func Osscreate(content string) {
config, err := initOSSConfig()
if err != nil {
log.Fatalf("加载 OSS 配置失败: %v", err)
}
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewStaticCredentialsProvider(config.AccessKeyID, config.AccessKeySecret, config.SessionToken)).
WithRegion(config.Region)
client := oss.NewClient(cfg)
body := strings.NewReader(content)
request := &oss.PutObjectRequest{
Bucket: oss.Ptr(config.Bucket),
Key: oss.Ptr(config.ObjectKey),
Body: body,
}
result, err := client.PutObject(context.TODO(), request)
if err != nil {
log.Fatalf("上传失败: %v", err)
}
log.Printf("上传成功! ETag: %s\n", *result.ETag)
}
func GetNotificationConfig() (*OSSObjectContent, error) {
config, err := initOSSConfig()
if err != nil {
return nil, fmt.Errorf("加载 OSS 配置失败: %w", err)
}
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewStaticCredentialsProvider(config.AccessKeyID, config.AccessKeySecret, config.SessionToken)).
WithRegion(config.Region)
client := oss.NewClient(cfg)
request := &oss.GetObjectRequest{
Bucket: oss.Ptr(config.Bucket),
Key: oss.Ptr(config.ObjectKey),
}
result, err := client.GetObject(context.TODO(), request)
if err != nil {
return nil, fmt.Errorf("获取 OSS 文件失败: %w", err)
}
defer result.Body.Close()
body, err := io.ReadAll(result.Body)
if err != nil {
return nil, fmt.Errorf("读取 OSS 文件内容失败: %w", err)
}
content := bytes.TrimSpace(body)
log.Printf("获取 OSS 文件成功: bucket=%s key=%s size=%d", config.Bucket, config.ObjectKey, len(content))
var data map[string]interface{}
if err := json.Unmarshal(content, &data); err != nil {
log.Printf("解析 OSS 文件内容失败: %v", err)
} else {
log.Printf("OSS 文件内容解析成功: %v", data)
}
response := &OSSObjectContent{
Bucket: config.Bucket,
Key: config.ObjectKey,
Region: config.Region,
Config: data,
}
if result.ContentType != nil {
response.ContentType = *result.ContentType
}
if result.ETag != nil {
response.ETag = *result.ETag
}
if result.LastModified != nil {
response.LastModified = result.LastModified.Format(time.RFC3339)
}
return response, nil
}
func initOSSConfig() (ossConfig, error) {
ossInitOnce.Do(func() {
nacosClient, err := nacos.GetNacosClient()
ossCnf = ossConfig{
Region: defaultOSSRegion,
Bucket: defaultOSSBucket,
ObjectKey: defaultOSSObjectKey,
}
if err != nil {
log.Printf("创建 Nacos 客户端失败: %v", err)
return
}
err = nacosClient.GetJSON(defaultNacosDataID, defaultNacosGroup, &ossCnf)
if err != nil {
log.Printf("从 Nacos 获取 OSS 配置失败: %v", err)
}
if ossCnf.Region == "" {
ossCnf.Region = defaultOSSRegion
}
if ossCnf.Bucket == "" {
ossCnf.Bucket = defaultOSSBucket
}
if ossCnf.ObjectKey == "" {
ossCnf.ObjectKey = defaultOSSObjectKey
}
nacosClient.Listen(defaultNacosDataID, defaultNacosGroup, func(event nacos.ChangeEvent) {
err = nacosClient.GetJSON(defaultNacosDataID, defaultNacosGroup, &ossCnf)
if err != nil {
log.Printf("从 Nacos 获取 OSS 配置失败: %v", err)
return
}
log.Printf("Nacos 配置已更新: %v", ossCnf)
})
})
return ossCnf, nil
}