func MoveFromTmp(src, dest string) (err error) { err = os.Rename(src, dest) if err != nil { l := log.Errorf("Rename %v to %v error. %v", src, dest, err) logq.LogPutqueue(l) } return err }
func SetEnv(name string, value string) string { if e := os.Setenv(name, value); e != nil { log.Errorf("[setenv][%s] %s, error:%v\n", name, value, e) return "" } log.Debugf("[setenv][%s] %s\n", name, value) return name }
func connectMysql() { DB_ADDR := os.Getenv("MYSQL_PORT_3306_TCP_ADDR") DB_PORT := os.Getenv("MYSQL_PORT_3306_TCP_PORT") DB_DATABASE := os.Getenv("MYSQL_ENV_MYSQL_DATABASE") DB_USER := os.Getenv("MYSQL_ENV_MYSQL_USER") DB_PASSWORD := os.Getenv("MYSQL_ENV_MYSQL_PASSWORD") DB_URL := fmt.Sprintf(`%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true`, DB_USER, DB_PASSWORD, DB_ADDR, DB_PORT, DB_DATABASE) db, err := sql.Open("mysql", DB_URL) if err != nil { log.Errorf("error: %s\n", err) } else { g_ds.Db = db g_ds.DbType = "mysql" log.Println("Connect to Mysql successfully!") } }
func (fs *fsdriver) CheckDataAndGetSize(dpconn, itemlocation, fileName string) (exist bool, size int64, err error) { destFullPathFileName := dpconn + "/" + itemlocation + "/" + fileName if isFileExists(destFullPathFileName) == false { exist = false err = fmt.Errorf("%s not exist.", destFullPathFileName) return } exist = true size, err = GetFileSize(destFullPathFileName) if err != nil { l := log.Errorf("Get %s size error, %v", destFullPathFileName, err) logq.LogPutqueue(l) return exist, 0, err } return }
func CheckTagExist(repo, item, tag string) (exits bool, err error) { rpdmid, dpid, _ := GetRpdmidDpidItemdesc(repo, item) if rpdmid == 0 || dpid == 0 { l := log.Errorf("dataitem is not exist, %s/%s, rpdmid:%d, dpid:%d", repo, item, rpdmid, dpid) logq.LogPutqueue(l) return false, errors.New(fmt.Sprintf("Dataitem '%s' not found.", item)) } sqlCheckTag := fmt.Sprintf("SELECT COUNT(1) FROM DH_RPDM_TAG_MAP WHERE RPDMID=%d AND TAGNAME='%s' AND STATUS='A'", rpdmid, tag) row, err := g_ds.QueryRow(sqlCheckTag) var count int row.Scan(&count) if count > 0 { return true, nil } return }
func GetMetaAndSampleAndPricePlan(dpname, itemdesc string) (meta, sample string, plans []PricePlan) { dpconn := GetDataPoolDpconn(dpname) if len(dpconn) == 0 || len(itemdesc) == 0 { l := log.Errorf("dpconn:%s or itemdesc:%s is empty", dpconn, itemdesc) logq.LogPutqueue(l) return } path := dpconn + "/" + itemdesc meta = GetMetaData(path) sample = GetSampleData(path) plans = GetPricePlan(path) log.Debug(plans) return }
func GetItemslocationInDatapool(itemslocation map[string]string, dpname string, dpid int, dpconn string) error { sql := fmt.Sprintf("SELECT DISTINCT ITEMDESC, REPOSITORY, DATAITEM FROM DH_DP_RPDM_MAP WHERE DPID=%v AND STATUS='A';", dpid) log.Debug(sql) rows, err := g_ds.QueryRows(sql) if err != nil { l := log.Errorf("datapool name %s, dpid %v, dpconn %v, error:%v", dpname, dpid, dpconn, err) logq.LogPutqueue(l) return err } var location, repo, item string for rows.Next() { rows.Scan(&location, &repo, &item) log.Debug(location, repo, item) itemslocation[location] = repo + "/" + item } log.Trace(itemslocation) return err }
/*pull parses filename and target IP from HTTP GET method, and start downloading routine. */ func p2p_pull(rw http.ResponseWriter, r *http.Request, ps httprouter.Params) { l := log.Info("P2P PULL FROM", r.RemoteAddr, r.Method, r.URL.RequestURI(), r.Proto) logq.LogPutqueue(l) r.ParseForm() sRepoName := ps.ByName("repo") sDataItem := ps.ByName("dataitem") sTag := ps.ByName("tag") log.Info(sRepoName, sDataItem, sTag) jobtag := fmt.Sprintf("%s/%s:%s", sRepoName, sDataItem, sTag) var irpdmid, idpid int var stagdetail, itemdesc, dpconn, dpname, dptype string msg := &ds.MsgResp{} msg.Msg = "OK." irpdmid, idpid, itemdesc = GetRpdmidDpidItemdesc(sRepoName, sDataItem) if len(itemdesc) == 0 { itemdesc = sRepoName + "_" + sDataItem } log.Debug("dpid:", idpid, "rpdmid:", irpdmid, "itemdesc:", itemdesc) stagdetail = GetTagDetail(irpdmid, sTag) log.Debug("tagdetail", stagdetail) if len(stagdetail) == 0 { l := log.Warnf("%s(tag:%s) not found", stagdetail, sTag) logq.LogPutqueue(l) http.Error(rw, sTag+" not found", http.StatusNotFound) return } dpconn, dpname, dptype = GetDpconnDpnameDptypeByDpid(idpid) log.Debug("dpconn:", dpconn, "dpname:", dpname, "dptype:", dptype) datapool, err := dpdriver.New(dptype) if err != nil { WriteErrLogAndResp(rw, http.StatusInternalServerError, cmd.ErrorNoDatapoolDriver, err) return } filepathname := datapool.GetFileTobeSend(dpconn, dpname, itemdesc, stagdetail) //filepathname := dpconn + "/" + itemdesc + "/" + stagdetail log.Println("filename:", filepathname) if exists := isFileExists(filepathname); !exists { l := log.Error(filepathname, "not found") logq.LogPutqueue(l) putToJobQueue(jobtag, filepathname, "N/A", -1) msg.Msg = fmt.Sprintf("Tag:%s not found", sTag) resp, _ := json.Marshal(msg) respStr := string(resp) rw.WriteHeader(http.StatusNotFound) fmt.Fprintln(rw, respStr) return } tokenValid := false retmsg := "" token := r.Form.Get("token") username := r.Form.Get("username") log.Debug(r.URL, "----", r.FormValue("username"), "----", r.Form.Get("username")) if len(token) > 0 && len(username) > 0 { log.Println(r.URL.Path, "token:", token, "username:"******"/transaction/" + sRepoName + "/" + sDataItem + "/" + sTag + "?cypt_accesstoken=" + token + "&username="******"Get %s size error, %v", filepathname, err) logq.LogPutqueue(l) } log.Printf("Tag file full path name :%v, size:%v", filepathname, size) //rw.Header().Set("Source-FileName", stagdetail) bmd5, err := ComputeMd5(filepathname) strmd5 := fmt.Sprintf("%x", bmd5) if err != nil { log.Error(filepathname, err, bmd5, strmd5) } else { rw.Header().Set("X-Source-MD5", strmd5) } rw.Header().Set("X-Source-FileSize", strconv.FormatInt(size, 10)) l = log.Info("transfering", filepathname, bmd5, strmd5) logq.LogPutqueue(l) jobid := putToJobQueue(jobtag, filepathname, "transfering", size) http.ServeFile(rw, r, filepathname) updateJobQueue(jobid, "transfered", 0) return }
/*download routine, supports resuming broken downloads.*/ func download(uri string, p ds.DsPull, w http.ResponseWriter, c chan int) (int64, error) { log.Printf("we are going to download %s, save to dp=%s,name=%s\n", uri, p.Datapool, p.DestName) var out *os.File var err error var destfilename, tmpdestfilename, tmpdir, dpconn, dptype string dpconn, dptype = GetDataPoolDpconnAndDptype(p.Datapool) if len(dpconn) == 0 { err = fmt.Errorf("dpconn is null! datapool:%s ", p.Datapool) return ErrLogAndResp(c, w, http.StatusBadRequest, cmd.ErrorNoRecord, err) } //New a datapool object datapool, err := dpdriver.New(dptype) if err != nil { return ErrLogAndResp(c, w, http.StatusInternalServerError, cmd.ErrorNoDatapoolDriver, err) } destfilename, tmpdir, tmpdestfilename = datapool.GetDestFileName(dpconn, p.ItemDesc, p.DestName) os.MkdirAll(tmpdir, 0777) log.Info("open tmp destfile name:", tmpdestfilename) out, err = os.OpenFile(tmpdestfilename, os.O_RDWR|os.O_CREATE, 0644) if err != nil { return ErrLogAndResp(c, w, http.StatusInternalServerError, cmd.ErrorOpenFile, err) } stat, err := out.Stat() if err != nil { return ErrLogAndResp(c, w, http.StatusInternalServerError, cmd.ErrorStatFile, err) } out.Seek(stat.Size(), 0) req, err := http.NewRequest("GET", uri, nil) req.Header.Set("User-Agent", "go-downloader") /* Set download starting position with 'Range' in HTTP header*/ req.Header.Set("Range", "bytes="+strconv.FormatInt(stat.Size(), 10)+"-") log.Printf("%v bytes had already been downloaded.\n", stat.Size()) log.Debug(EnvDebug("http_proxy", false)) resp, err := http.DefaultClient.Do(req) /*Save response body to file only when HTTP 2xx received. TODO*/ if err != nil || (resp != nil && resp.StatusCode/100 != 2) { log.Error("http error", err) if resp != nil { body, _ := ioutil.ReadAll(resp.Body) l := log.Error("http status code:", resp.StatusCode, "response Body:", string(body), err) logq.LogPutqueue(l) struMsg := &ds.MsgResp{} json.Unmarshal(body, struMsg) msg := struMsg.Msg if resp.StatusCode == 416 { msg = tmpdestfilename + " has already been downloaded." } r, _ := buildResp(resp.StatusCode, msg, nil) w.WriteHeader(resp.StatusCode) w.Write(r) } else { HttpNoData(w, http.StatusInternalServerError, cmd.ErrorOtherError, err.Error()) } filesize := stat.Size() out.Close() if filesize == 0 { os.Remove(tmpdestfilename) } c <- -1 return 0, err } defer resp.Body.Close() HttpNoData(w, http.StatusOK, cmd.ResultOK, strret) //write channel c <- 1 jobtag := p.Repository + "/" + p.Dataitem + ":" + p.Tag srcsize, err := strconv.ParseInt(resp.Header.Get("X-Source-FileSize"), DECIMAL_BASE, INT_SIZE_64) md5str := resp.Header.Get("X-Source-MD5") status := "downloading" log.Info("pull tag:", jobtag, tmpdestfilename, status, srcsize) jobid := putToJobQueue(jobtag, tmpdestfilename, status, srcsize) n, err := io.Copy(out, resp.Body) if err != nil { out.Close() bl := log.Error(err) logq.LogPutqueue(bl) dlsize, e := GetFileSize(tmpdestfilename) if e != nil { l := log.Error(e) logq.LogPutqueue(l) } status = "failed" updateJobQueue(jobid, status, dlsize) return 0, err } out.Close() status = "downloaded" if len(md5str) > 0 { bmd5, err := ComputeMd5(tmpdestfilename) bmd5str := fmt.Sprintf("%x", bmd5) log.Debug("md5", md5str, tmpdestfilename, bmd5str) if err != nil { log.Error(tmpdestfilename, err, bmd5) } else if md5str != bmd5str { l := log.Errorf("check md5 code error! src md5:%v, local md5:%v", md5str, bmd5str) logq.LogPutqueue(l) status = "md5 error" updateJobQueue(jobid, status, 0) return n, nil } } log.Printf("%d bytes downloaded.", n) if err := MoveFromTmp(tmpdestfilename, destfilename); err != nil { status = "MoveFromTmp error" } dlsize, e := GetFileSize(destfilename) if e != nil { l := log.Error(e) logq.LogPutqueue(l) } status = datapool.StoreFile(status, destfilename, dpconn, p.Datapool, p.ItemDesc, p.DestName) updateJobQueue(jobid, status, dlsize) tagComment := GetTagComment(p.Repository, p.Dataitem, p.Tag) InsertTagToDb(true, p, tagComment) return n, nil }