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

125 lines
3.0 KiB

9 years ago
10 years ago
9 years ago
9 years ago
  1. package operation
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "net/url"
  7. "strings"
  8. "sync"
  9. "net/http"
  10. "github.com/chrislusf/seaweedfs/weed/security"
  11. "github.com/chrislusf/seaweedfs/weed/util"
  12. )
  13. type DeleteResult struct {
  14. Fid string `json:"fid"`
  15. Size int `json:"size"`
  16. Status int `json:"status"`
  17. Error string `json:"error,omitempty"`
  18. }
  19. func DeleteFromVolumeServer(fileUrlOnVolume string, jwt security.EncodedJwt) error {
  20. err := util.Delete(fileUrlOnVolume, jwt)
  21. if err != nil {
  22. return fmt.Errorf("Failed to delete %s:%v", fileUrlOnVolume, err)
  23. }
  24. return nil
  25. }
  26. func DeleteFile(master string, fileId string, jwt security.EncodedJwt) error {
  27. fileUrl, err := LookupFileId(master, fileId)
  28. if err != nil {
  29. return fmt.Errorf("Failed to lookup %s:%v", fileId, err)
  30. }
  31. err = util.Delete(fileUrl, jwt)
  32. if err != nil {
  33. return fmt.Errorf("Failed to delete %s:%v", fileUrl, err)
  34. }
  35. return nil
  36. }
  37. func ParseFileId(fid string) (vid string, key_cookie string, err error) {
  38. commaIndex := strings.Index(fid, ",")
  39. if commaIndex <= 0 {
  40. return "", "", errors.New("Wrong fid format.")
  41. }
  42. return fid[:commaIndex], fid[commaIndex+1:], nil
  43. }
  44. type DeleteFilesResult struct {
  45. Errors []string
  46. Results []DeleteResult
  47. }
  48. func DeleteFiles(master string, fileIds []string) (*DeleteFilesResult, error) {
  49. vid_to_fileIds := make(map[string][]string)
  50. ret := &DeleteFilesResult{}
  51. var vids []string
  52. for _, fileId := range fileIds {
  53. vid, _, err := ParseFileId(fileId)
  54. if err != nil {
  55. ret.Results = append(ret.Results, DeleteResult{
  56. Fid: vid,
  57. Status: http.StatusBadRequest,
  58. Error: err.Error()},
  59. )
  60. continue
  61. }
  62. if _, ok := vid_to_fileIds[vid]; !ok {
  63. vid_to_fileIds[vid] = make([]string, 0)
  64. vids = append(vids, vid)
  65. }
  66. vid_to_fileIds[vid] = append(vid_to_fileIds[vid], fileId)
  67. }
  68. lookupResults, err := LookupVolumeIds(master, vids)
  69. if err != nil {
  70. return ret, err
  71. }
  72. server_to_fileIds := make(map[string][]string)
  73. for vid, result := range lookupResults {
  74. if result.Error != "" {
  75. ret.Errors = append(ret.Errors, result.Error)
  76. continue
  77. }
  78. for _, location := range result.Locations {
  79. if _, ok := server_to_fileIds[location.Url]; !ok {
  80. server_to_fileIds[location.Url] = make([]string, 0)
  81. }
  82. server_to_fileIds[location.Url] = append(
  83. server_to_fileIds[location.Url], vid_to_fileIds[vid]...)
  84. }
  85. }
  86. var wg sync.WaitGroup
  87. for server, fidList := range server_to_fileIds {
  88. wg.Add(1)
  89. go func(server string, fidList []string) {
  90. defer wg.Done()
  91. values := make(url.Values)
  92. for _, fid := range fidList {
  93. values.Add("fid", fid)
  94. }
  95. jsonBlob, err := util.Post("http://"+server+"/delete", values)
  96. if err != nil {
  97. ret.Errors = append(ret.Errors, err.Error()+" "+string(jsonBlob))
  98. return
  99. }
  100. var result []DeleteResult
  101. err = json.Unmarshal(jsonBlob, &result)
  102. if err != nil {
  103. ret.Errors = append(ret.Errors, err.Error()+" "+string(jsonBlob))
  104. return
  105. }
  106. ret.Results = append(ret.Results, result...)
  107. }(server, fidList)
  108. }
  109. wg.Wait()
  110. return ret, nil
  111. }