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  }