github.com/0chain/gosdk@v1.17.11/zboxcore/sdk/filestatsworker.go (about) 1 package sdk 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/json" 7 "io/ioutil" 8 "mime/multipart" 9 "net/http" 10 "strings" 11 "time" 12 13 "github.com/0chain/errors" 14 "github.com/0chain/gosdk/zboxcore/blockchain" 15 "github.com/0chain/gosdk/zboxcore/fileref" 16 l "github.com/0chain/gosdk/zboxcore/logger" 17 "github.com/0chain/gosdk/zboxcore/zboxutil" 18 ) 19 20 // FileStats - file stats structure 21 type FileStats struct { 22 Name string `json:"name"` 23 Size int64 `json:"size"` 24 PathHash string `json:"path_hash"` 25 Path string `json:"path"` 26 NumBlocks int64 `json:"num_of_blocks"` 27 NumUpdates int64 `json:"num_of_updates"` 28 NumBlockDownloads int64 `json:"num_of_block_downloads"` 29 SuccessChallenges int64 `json:"num_of_challenges"` 30 FailedChallenges int64 `json:"num_of_failed_challenges"` 31 LastChallengeResponseTxn string `json:"last_challenge_txn"` 32 WriteMarkerRedeemTxn string `json:"write_marker_txn"` 33 BlobberID string `json:"blobber_id"` 34 BlobberURL string `json:"blobber_url"` 35 BlockchainAware bool `json:"blockchain_aware"` 36 CreatedAt time.Time `json:"CreatedAt"` 37 FileID string `json:"file_id"` 38 } 39 40 type fileStatsResponse struct { 41 filestats *FileStats 42 responseStr string 43 blobberIdx int 44 err error 45 } 46 47 func (req *ListRequest) getFileStatsInfoFromBlobber(blobber *blockchain.StorageNode, blobberIdx int, rspCh chan<- *fileStatsResponse) { 48 body := new(bytes.Buffer) 49 formWriter := multipart.NewWriter(body) 50 51 var fileStats *FileStats 52 var s strings.Builder 53 var err error 54 fileMetaRetFn := func() { 55 if fileStats == nil { 56 fileStats = &FileStats{} 57 fileStats.BlobberID = blobber.ID 58 fileStats.BlobberURL = blobber.Baseurl 59 } 60 rspCh <- &fileStatsResponse{filestats: fileStats, responseStr: s.String(), blobberIdx: blobberIdx, err: err} 61 } 62 defer fileMetaRetFn() 63 if len(req.remotefilepath) > 0 { 64 req.remotefilepathhash = fileref.GetReferenceLookup(req.allocationID, req.remotefilepath) 65 } 66 err = formWriter.WriteField("path_hash", req.remotefilepathhash) 67 if err != nil { 68 l.Logger.Error("File meta info request error: ", err.Error()) 69 return 70 } 71 72 formWriter.Close() 73 httpreq, err := zboxutil.NewFileStatsRequest(blobber.Baseurl, req.allocationID, req.allocationTx, req.sig, body) 74 if err != nil { 75 l.Logger.Error("File meta info request error: ", err.Error()) 76 return 77 } 78 79 httpreq.Header.Add("Content-Type", formWriter.FormDataContentType()) 80 ctx, cncl := context.WithTimeout(req.ctx, (time.Second * 30)) 81 err = zboxutil.HttpDo(ctx, cncl, httpreq, func(resp *http.Response, err error) error { 82 if err != nil { 83 l.Logger.Error("GetFileStats : ", err) 84 return err 85 } 86 defer resp.Body.Close() 87 resp_body, err := ioutil.ReadAll(resp.Body) 88 if err != nil { 89 return errors.Wrap(err, "Error: Resp") 90 } 91 s.WriteString(string(resp_body)) 92 if resp.StatusCode == http.StatusOK { 93 err = json.Unmarshal(resp_body, &fileStats) 94 if err != nil { 95 return errors.Wrap(err, "file stats response parse error") 96 } 97 if len(fileStats.WriteMarkerRedeemTxn) > 0 { 98 fileStats.BlockchainAware = true 99 } else { 100 fileStats.BlockchainAware = false 101 } 102 fileStats.BlobberID = blobber.ID 103 fileStats.BlobberURL = blobber.Baseurl 104 return nil 105 } 106 return errors.New(resp.Status, s.String()) 107 }) 108 } 109 110 func (req *ListRequest) getFileStatsFromBlobbers() map[string]*FileStats { 111 numList := len(req.blobbers) 112 //fmt.Printf("%v\n", req.blobbers) 113 rspCh := make(chan *fileStatsResponse, numList) 114 for i := 0; i < numList; i++ { 115 go req.getFileStatsInfoFromBlobber(req.blobbers[i], i, rspCh) 116 } 117 fileInfos := make(map[string]*FileStats) 118 for i := 0; i < numList; i++ { 119 ch := <-rspCh 120 if ch.err == nil { 121 fileInfos[ch.filestats.BlobberID] = ch.filestats 122 } 123 } 124 return fileInfos 125 }