package efile import ( "fmt" "net/url" "sync" "time" "gitlink.org.cn/cloudream/common/utils/http2" "gitlink.org.cn/cloudream/common/utils/serder" "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/factory/reg" stgtypes "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/types" jcstypes "gitlink.org.cn/cloudream/jcs-pub/common/types" ) func init() { reg.RegisterBuilder[*jcstypes.EFileType](func(detail *jcstypes.UserSpaceDetail) stgtypes.StorageBuilder { return &builder{ detail: detail, } }) } type builder struct { stgtypes.EmptyBuilder detail *jcstypes.UserSpaceDetail token string tokenLock sync.Mutex getTokenTime time.Time } func (b *builder) getToken() (string, error) { stgType := b.detail.UserSpace.Storage.(*jcstypes.EFileType) cred := b.detail.UserSpace.Credential.(*jcstypes.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) (stgtypes.ECMultiplier, error) { feat := stgtypes.FindFeature[*jcstypes.ECMultiplierFeature](b.detail) if feat == nil { return nil, fmt.Errorf("feature ECMultiplier not found") } cred, ok := b.detail.UserSpace.Credential.(*jcstypes.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 }