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

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. package http
  2. import (
  3. "mime/multipart"
  4. "net/http"
  5. "time"
  6. "github.com/gin-gonic/gin"
  7. "gitlink.org.cn/cloudream/common/consts/errorcode"
  8. "gitlink.org.cn/cloudream/common/pkgs/iterator"
  9. "gitlink.org.cn/cloudream/common/pkgs/logger"
  10. cdssdk "gitlink.org.cn/cloudream/common/sdks/storage"
  11. "gitlink.org.cn/cloudream/storage/common/pkgs/db/model"
  12. stgiter "gitlink.org.cn/cloudream/storage/common/pkgs/iterator"
  13. )
  14. type PackageService struct {
  15. *Server
  16. }
  17. func (s *Server) PackageSvc() *PackageService {
  18. return &PackageService{
  19. Server: s,
  20. }
  21. }
  22. type PackageGetReq struct {
  23. UserID *cdssdk.UserID `form:"userID" binding:"required"`
  24. PackageID *cdssdk.PackageID `form:"packageID" binding:"required"`
  25. }
  26. type PackageGetResp struct {
  27. model.Package
  28. }
  29. func (s *PackageService) Get(ctx *gin.Context) {
  30. log := logger.WithField("HTTP", "Package.Get")
  31. var req PackageGetReq
  32. if err := ctx.ShouldBindQuery(&req); err != nil {
  33. log.Warnf("binding body: %s", err.Error())
  34. ctx.JSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "missing argument or invalid argument"))
  35. return
  36. }
  37. pkg, err := s.svc.PackageSvc().Get(*req.UserID, *req.PackageID)
  38. if err != nil {
  39. log.Warnf("getting package: %s", err.Error())
  40. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get package failed"))
  41. return
  42. }
  43. ctx.JSON(http.StatusOK, OK(PackageGetResp{Package: *pkg}))
  44. }
  45. type PackageUploadReq struct {
  46. Info PackageUploadInfo `form:"info" binding:"required"`
  47. Files []*multipart.FileHeader `form:"files"`
  48. }
  49. type PackageUploadInfo struct {
  50. UserID *cdssdk.UserID `json:"userID" binding:"required"`
  51. BucketID *cdssdk.BucketID `json:"bucketID" binding:"required"`
  52. Name string `json:"name" binding:"required"`
  53. NodeAffinity *cdssdk.NodeID `json:"nodeAffinity"`
  54. }
  55. type PackageUploadResp struct {
  56. PackageID cdssdk.PackageID `json:"packageID,string"`
  57. }
  58. func (s *PackageService) Upload(ctx *gin.Context) {
  59. log := logger.WithField("HTTP", "Package.Upload")
  60. var req PackageUploadReq
  61. if err := ctx.ShouldBind(&req); err != nil {
  62. log.Warnf("binding body: %s", err.Error())
  63. ctx.JSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "missing argument or invalid argument"))
  64. return
  65. }
  66. s.uploadEC(ctx, &req)
  67. }
  68. func (s *PackageService) uploadEC(ctx *gin.Context, req *PackageUploadReq) {
  69. log := logger.WithField("HTTP", "Package.Upload")
  70. var err error
  71. objIter := mapMultiPartFileToUploadingObject(req.Files)
  72. taskID, err := s.svc.PackageSvc().StartCreatingPackage(*req.Info.UserID, *req.Info.BucketID, req.Info.Name, objIter, req.Info.NodeAffinity)
  73. if err != nil {
  74. log.Warnf("start uploading ec package task: %s", err.Error())
  75. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "start uploading task failed"))
  76. return
  77. }
  78. for {
  79. complete, createResult, err := s.svc.PackageSvc().WaitCreatingPackage(taskID, time.Second*5)
  80. if complete {
  81. if err != nil {
  82. log.Warnf("uploading ec package: %s", err.Error())
  83. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "uploading ec package failed"))
  84. return
  85. }
  86. ctx.JSON(http.StatusOK, OK(PackageUploadResp{
  87. PackageID: createResult.PackageID,
  88. }))
  89. return
  90. }
  91. if err != nil {
  92. log.Warnf("waiting task: %s", err.Error())
  93. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "wait uploading task failed"))
  94. return
  95. }
  96. }
  97. }
  98. type PackageDeleteReq struct {
  99. UserID *cdssdk.UserID `json:"userID" binding:"required"`
  100. PackageID *cdssdk.PackageID `json:"packageID" binding:"required"`
  101. }
  102. func (s *PackageService) Delete(ctx *gin.Context) {
  103. log := logger.WithField("HTTP", "Package.Delete")
  104. var req PackageDeleteReq
  105. if err := ctx.ShouldBindJSON(&req); err != nil {
  106. log.Warnf("binding body: %s", err.Error())
  107. ctx.JSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "missing argument or invalid argument"))
  108. return
  109. }
  110. err := s.svc.PackageSvc().DeletePackage(*req.UserID, *req.PackageID)
  111. if err != nil {
  112. log.Warnf("deleting package: %s", err.Error())
  113. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "delete package failed"))
  114. return
  115. }
  116. ctx.JSON(http.StatusOK, OK(nil))
  117. }
  118. type GetCachedNodesReq struct {
  119. UserID *cdssdk.UserID `json:"userID" binding:"required"`
  120. PackageID *cdssdk.PackageID `json:"packageID" binding:"required"`
  121. }
  122. type GetCachedNodesResp struct {
  123. cdssdk.PackageCachingInfo
  124. }
  125. func (s *PackageService) GetCachedNodes(ctx *gin.Context) {
  126. log := logger.WithField("HTTP", "Package.GetCachedNodes")
  127. var req GetCachedNodesReq
  128. if err := ctx.ShouldBindJSON(&req); err != nil {
  129. log.Warnf("binding body: %s", err.Error())
  130. ctx.JSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "missing argument or invalid argument"))
  131. return
  132. }
  133. resp, err := s.svc.PackageSvc().GetCachedNodes(*req.UserID, *req.PackageID)
  134. if err != nil {
  135. log.Warnf("get package cached nodes failed: %s", err.Error())
  136. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get package cached nodes failed"))
  137. return
  138. }
  139. ctx.JSON(http.StatusOK, OK(GetCachedNodesResp{resp}))
  140. }
  141. type GetLoadedNodesReq struct {
  142. UserID *cdssdk.UserID `json:"userID" binding:"required"`
  143. PackageID *cdssdk.PackageID `json:"packageID" binding:"required"`
  144. }
  145. type GetLoadedNodesResp struct {
  146. NodeIDs []cdssdk.NodeID `json:"nodeIDs"`
  147. }
  148. func (s *PackageService) GetLoadedNodes(ctx *gin.Context) {
  149. log := logger.WithField("HTTP", "Package.GetLoadedNodes")
  150. var req GetLoadedNodesReq
  151. if err := ctx.ShouldBindJSON(&req); err != nil {
  152. log.Warnf("binding body: %s", err.Error())
  153. ctx.JSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "missing argument or invalid argument"))
  154. return
  155. }
  156. nodeIDs, err := s.svc.PackageSvc().GetLoadedNodes(*req.UserID, *req.PackageID)
  157. if err != nil {
  158. log.Warnf("get package loaded nodes failed: %s", err.Error())
  159. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get package loaded nodes failed"))
  160. return
  161. }
  162. ctx.JSON(http.StatusOK, OK(GetLoadedNodesResp{
  163. NodeIDs: nodeIDs,
  164. }))
  165. }
  166. func mapMultiPartFileToUploadingObject(files []*multipart.FileHeader) stgiter.UploadingObjectIterator {
  167. return iterator.Map[*multipart.FileHeader](
  168. iterator.Array(files...),
  169. func(file *multipart.FileHeader) (*stgiter.IterUploadingObject, error) {
  170. stream, err := file.Open()
  171. if err != nil {
  172. return nil, err
  173. }
  174. return &stgiter.IterUploadingObject{
  175. Path: file.Filename,
  176. Size: file.Size,
  177. File: stream,
  178. }, nil
  179. },
  180. )
  181. }

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