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.

127 lines
3.1 KiB

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