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.

package.go 6.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. package services
  2. import (
  3. "database/sql"
  4. "fmt"
  5. "github.com/jmoiron/sqlx"
  6. "gitlink.org.cn/cloudream/common/consts/errorcode"
  7. "gitlink.org.cn/cloudream/common/pkgs/logger"
  8. "gitlink.org.cn/cloudream/common/pkgs/mq"
  9. coormq "gitlink.org.cn/cloudream/storage-common/pkgs/mq/coordinator"
  10. scevt "gitlink.org.cn/cloudream/storage-common/pkgs/mq/scanner/event"
  11. )
  12. func (svc *Service) GetPackage(msg *coormq.GetPackage) (*coormq.GetPackageResp, *mq.CodeMessage) {
  13. pkg, err := svc.db.Package().GetByID(svc.db.SQLCtx(), msg.PackageID)
  14. if err != nil {
  15. logger.WithField("PackageID", msg.PackageID).
  16. Warnf("get package: %s", err.Error())
  17. return nil, mq.Failed(errorcode.OperationFailed, "get package failed")
  18. }
  19. return mq.ReplyOK(coormq.NewGetPackageResp(pkg))
  20. }
  21. func (svc *Service) GetPackageObjects(msg *coormq.GetPackageObjects) (*coormq.GetPackageObjectsResp, *mq.CodeMessage) {
  22. // TODO 检查用户是否有权限
  23. objs, err := svc.db.Object().GetPackageObjects(svc.db.SQLCtx(), msg.PackageID)
  24. if err != nil {
  25. logger.WithField("PackageID", msg.PackageID).
  26. Warnf("get package objects: %s", err.Error())
  27. return nil, mq.Failed(errorcode.OperationFailed, "get package objects failed")
  28. }
  29. return mq.ReplyOK(coormq.NewGetPackageObjectsResp(objs))
  30. }
  31. func (svc *Service) CreatePackage(msg *coormq.CreatePackage) (*coormq.CreatePackageResp, *mq.CodeMessage) {
  32. var pkgID int64
  33. err := svc.db.DoTx(sql.LevelDefault, func(tx *sqlx.Tx) error {
  34. var err error
  35. pkgID, err = svc.db.Package().Create(svc.db.SQLCtx(), msg.BucketID, msg.Name, msg.Redundancy)
  36. return err
  37. })
  38. if err != nil {
  39. logger.WithField("BucketID", msg.BucketID).
  40. WithField("Name", msg.Name).
  41. Warnf("creating package: %s", err.Error())
  42. return nil, mq.Failed(errorcode.OperationFailed, "creating package failed")
  43. }
  44. return mq.ReplyOK(coormq.NewCreatePackageResp(pkgID))
  45. }
  46. func (svc *Service) UpdateRepPackage(msg *coormq.UpdateRepPackage) (*coormq.UpdateRepPackageResp, *mq.CodeMessage) {
  47. _, err := svc.db.Package().GetByID(svc.db.SQLCtx(), msg.PackageID)
  48. if err != nil {
  49. logger.WithField("PackageID", msg.PackageID).
  50. Warnf("get package: %s", err.Error())
  51. return nil, mq.Failed(errorcode.OperationFailed, "get package failed")
  52. }
  53. err = svc.db.DoTx(sql.LevelDefault, func(tx *sqlx.Tx) error {
  54. // 先执行删除操作
  55. if len(msg.Deletes) > 0 {
  56. if err := svc.db.Object().BatchDelete(tx, msg.Deletes); err != nil {
  57. return fmt.Errorf("deleting objects: %w", err)
  58. }
  59. }
  60. // 再执行添加操作
  61. if len(msg.Adds) > 0 {
  62. if _, err := svc.db.Object().BatchAddRep(tx, msg.PackageID, msg.Adds); err != nil {
  63. return fmt.Errorf("adding objects: %w", err)
  64. }
  65. }
  66. return nil
  67. })
  68. if err != nil {
  69. logger.Warn(err.Error())
  70. return nil, mq.Failed(errorcode.OperationFailed, "update rep package failed")
  71. }
  72. // 紧急任务
  73. var affectFileHashes []string
  74. for _, add := range msg.Adds {
  75. affectFileHashes = append(affectFileHashes, add.FileHash)
  76. }
  77. err = svc.scanner.PostEvent(scevt.NewCheckRepCount(affectFileHashes), true, true)
  78. if err != nil {
  79. logger.Warnf("post event to scanner failed, but this will not affect creating, err: %s", err.Error())
  80. }
  81. return mq.ReplyOK(coormq.NewUpdateRepPackageResp())
  82. }
  83. func (svc *Service) UpdateECPackage(msg *coormq.UpdateECPackage) (*coormq.UpdateECPackageResp, *mq.CodeMessage) {
  84. _, err := svc.db.Package().GetByID(svc.db.SQLCtx(), msg.PackageID)
  85. if err != nil {
  86. logger.WithField("PackageID", msg.PackageID).
  87. Warnf("get package: %s", err.Error())
  88. return nil, mq.Failed(errorcode.OperationFailed, "get package failed")
  89. }
  90. err = svc.db.DoTx(sql.LevelDefault, func(tx *sqlx.Tx) error {
  91. // 先执行删除操作
  92. if len(msg.Deletes) > 0 {
  93. if err := svc.db.Object().BatchDelete(tx, msg.Deletes); err != nil {
  94. return fmt.Errorf("deleting objects: %w", err)
  95. }
  96. }
  97. // 再执行添加操作
  98. if len(msg.Adds) > 0 {
  99. if _, err := svc.db.Object().BatchAddEC(tx, msg.PackageID, msg.Adds); err != nil {
  100. return fmt.Errorf("adding objects: %w", err)
  101. }
  102. }
  103. return nil
  104. })
  105. if err != nil {
  106. logger.Warn(err.Error())
  107. return nil, mq.Failed(errorcode.OperationFailed, "update ec package failed")
  108. }
  109. return mq.ReplyOK(coormq.NewUpdateECPackageResp())
  110. }
  111. func (svc *Service) DeletePackage(msg *coormq.DeletePackage) (*coormq.DeletePackageResp, *mq.CodeMessage) {
  112. isAva, err := svc.db.Package().IsAvailable(svc.db.SQLCtx(), msg.UserID, msg.PackageID)
  113. if err != nil {
  114. logger.WithField("UserID", msg.UserID).
  115. WithField("PackageID", msg.PackageID).
  116. Warnf("check package available failed, err: %s", err.Error())
  117. return mq.ReplyFailed[coormq.DeletePackageResp](errorcode.OperationFailed, "check package available failed")
  118. }
  119. if !isAva {
  120. logger.WithField("UserID", msg.UserID).
  121. WithField("PackageID", msg.PackageID).
  122. Warnf("package is not available to the user")
  123. return mq.ReplyFailed[coormq.DeletePackageResp](errorcode.OperationFailed, "package is not available to the user")
  124. }
  125. err = svc.db.DoTx(sql.LevelDefault, func(tx *sqlx.Tx) error {
  126. return svc.db.Package().SoftDelete(tx, msg.PackageID)
  127. })
  128. if err != nil {
  129. logger.WithField("UserID", msg.UserID).
  130. WithField("PackageID", msg.PackageID).
  131. Warnf("set package deleted failed, err: %s", err.Error())
  132. return mq.ReplyFailed[coormq.DeletePackageResp](errorcode.OperationFailed, "set package deleted failed")
  133. }
  134. stgs, err := svc.db.StoragePackage().FindPackageStorages(svc.db.SQLCtx(), msg.PackageID)
  135. if err != nil {
  136. logger.Warnf("find package storages failed, but this will not affect the deleting, err: %s", err.Error())
  137. return mq.ReplyOK(coormq.NewDeletePackageResp())
  138. }
  139. // 不追求及时、准确
  140. if len(stgs) == 0 {
  141. // 如果没有被引用,直接投递CheckPackage的任务
  142. err := svc.scanner.PostEvent(scevt.NewCheckPackage([]int64{msg.PackageID}), false, false)
  143. if err != nil {
  144. logger.Warnf("post event to scanner failed, but this will not affect deleting, err: %s", err.Error())
  145. }
  146. logger.Debugf("post check package event")
  147. } else {
  148. // 有引用则让Agent去检查StoragePackage
  149. for _, stg := range stgs {
  150. err := svc.scanner.PostEvent(scevt.NewAgentCheckStorage(stg.StorageID, []int64{msg.PackageID}), false, false)
  151. if err != nil {
  152. logger.Warnf("post event to scanner failed, but this will not affect deleting, err: %s", err.Error())
  153. }
  154. }
  155. logger.Debugf("post agent check storage event")
  156. }
  157. return mq.ReplyOK(coormq.NewDeletePackageResp())
  158. }

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