JCS-pub/common/pkgs/storage/efile/efile.go

114 lines
2.5 KiB
Go

package efile
import (
"fmt"
"net/url"
"sync"
"time"
"gitlink.org.cn/cloudream/common/utils/http2"
"gitlink.org.cn/cloudream/common/utils/serder"
clitypes "gitlink.org.cn/cloudream/jcs-pub/client/types"
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/factory/reg"
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/types"
cortypes "gitlink.org.cn/cloudream/jcs-pub/coordinator/types"
)
func init() {
reg.RegisterBuilder[*cortypes.EFileType](func(detail *clitypes.UserSpaceDetail) types.StorageBuilder {
return &builder{
detail: detail,
}
})
}
type builder struct {
types.EmptyBuilder
detail *clitypes.UserSpaceDetail
token string
tokenLock sync.Mutex
getTokenTime time.Time
}
func (b *builder) getToken() (string, error) {
stgType := b.detail.UserSpace.Storage.(*cortypes.EFileType)
cred := b.detail.UserSpace.Credential.(*cortypes.EFileCred)
b.tokenLock.Lock()
defer b.tokenLock.Unlock()
if b.token != "" {
dt := time.Since(b.getTokenTime)
if dt < time.Second*time.Duration(cred.TokenExpire) {
return b.token, nil
}
}
u, err := url.JoinPath(cred.TokenURL, "/ac/openapi/v2/tokens")
if err != nil {
return "", err
}
resp, err := http2.PostJSON(u, http2.RequestParam{
Header: map[string]string{
"user": cred.User,
"password": cred.Password,
"orgId": cred.OrgID,
},
})
if err != nil {
return "", err
}
type Response struct {
Code string `json:"code"`
Msg string `json:"msg"`
Data []struct {
ClusterID string `json:"clusterId"`
Token string `json:"token"`
} `json:"data"`
}
var r Response
err = serder.JSONToObjectStream(resp.Body, &r)
if err != nil {
return "", err
}
if r.Code != "0" {
return "", fmt.Errorf("code:%s, msg:%s", r.Code, r.Msg)
}
for _, d := range r.Data {
if d.ClusterID == stgType.ClusterID {
b.token = d.Token
b.getTokenTime = time.Now()
return d.Token, nil
}
}
return "", fmt.Errorf("clusterID %s not found", stgType.ClusterID)
}
func (b *builder) CreateECMultiplier(typeOnly bool) (types.ECMultiplier, error) {
feat := types.FindFeature[*cortypes.ECMultiplierFeature](b.detail)
if feat == nil {
return nil, fmt.Errorf("feature ECMultiplier not found")
}
cred, ok := b.detail.UserSpace.Credential.(*cortypes.EFileCred)
if !ok {
return nil, fmt.Errorf("invalid storage credential type %T for efile storage", b.detail.UserSpace.Credential)
}
if typeOnly {
return (*ECMultiplier)(nil), nil
}
return &ECMultiplier{
blder: b,
url: cred.APIURL,
feat: feat,
}, nil
}