You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

efile.go 2.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package efile
  2. import (
  3. "fmt"
  4. "net/url"
  5. "sync"
  6. "time"
  7. "gitlink.org.cn/cloudream/common/utils/http2"
  8. "gitlink.org.cn/cloudream/common/utils/serder"
  9. "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/factory/reg"
  10. stgtypes "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/types"
  11. jcstypes "gitlink.org.cn/cloudream/jcs-pub/common/types"
  12. )
  13. func init() {
  14. reg.RegisterBuilder[*jcstypes.EFileType](func(detail *jcstypes.UserSpaceDetail) stgtypes.StorageBuilder {
  15. return &builder{
  16. detail: detail,
  17. }
  18. })
  19. }
  20. type builder struct {
  21. stgtypes.EmptyBuilder
  22. detail *jcstypes.UserSpaceDetail
  23. token string
  24. tokenLock sync.Mutex
  25. getTokenTime time.Time
  26. }
  27. func (b *builder) getToken() (string, error) {
  28. stgType := b.detail.UserSpace.Storage.(*jcstypes.EFileType)
  29. cred := b.detail.UserSpace.Credential.(*jcstypes.EFileCred)
  30. b.tokenLock.Lock()
  31. defer b.tokenLock.Unlock()
  32. if b.token != "" {
  33. dt := time.Since(b.getTokenTime)
  34. if dt < time.Second*time.Duration(cred.TokenExpire) {
  35. return b.token, nil
  36. }
  37. }
  38. u, err := url.JoinPath(cred.TokenURL, "/ac/openapi/v2/tokens")
  39. if err != nil {
  40. return "", err
  41. }
  42. resp, err := http2.PostJSON(u, http2.RequestParam{
  43. Header: map[string]string{
  44. "user": cred.User,
  45. "password": cred.Password,
  46. "orgId": cred.OrgID,
  47. },
  48. })
  49. if err != nil {
  50. return "", err
  51. }
  52. type Response struct {
  53. Code string `json:"code"`
  54. Msg string `json:"msg"`
  55. Data []struct {
  56. ClusterID string `json:"clusterId"`
  57. Token string `json:"token"`
  58. } `json:"data"`
  59. }
  60. var r Response
  61. err = serder.JSONToObjectStream(resp.Body, &r)
  62. if err != nil {
  63. return "", err
  64. }
  65. if r.Code != "0" {
  66. return "", fmt.Errorf("code:%s, msg:%s", r.Code, r.Msg)
  67. }
  68. for _, d := range r.Data {
  69. if d.ClusterID == stgType.ClusterID {
  70. b.token = d.Token
  71. b.getTokenTime = time.Now()
  72. return d.Token, nil
  73. }
  74. }
  75. return "", fmt.Errorf("clusterID %s not found", stgType.ClusterID)
  76. }
  77. func (b *builder) CreateECMultiplier(typeOnly bool) (stgtypes.ECMultiplier, error) {
  78. feat := stgtypes.FindFeature[*jcstypes.ECMultiplierFeature](b.detail)
  79. if feat == nil {
  80. return nil, fmt.Errorf("feature ECMultiplier not found")
  81. }
  82. cred, ok := b.detail.UserSpace.Credential.(*jcstypes.EFileCred)
  83. if !ok {
  84. return nil, fmt.Errorf("invalid storage credential type %T for efile storage", b.detail.UserSpace.Credential)
  85. }
  86. if typeOnly {
  87. return (*ECMultiplier)(nil), nil
  88. }
  89. return &ECMultiplier{
  90. blder: b,
  91. url: cred.APIURL,
  92. feat: feat,
  93. }, nil
  94. }

本项目旨在将云际存储公共基础设施化,使个人及企业可低门槛使用高效的云际存储服务(安装开箱即用云际存储客户端即可,无需关注其他组件的部署),同时支持用户灵活便捷定制云际存储的功能细节。