114 lines
2.5 KiB
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
|
|
}
|