func (dir *Directory) createVolumeHandler(w http.ResponseWriter, r *http.Request) {
	// increase volumeID
	createVolCmd := &CreateVolCommand{ReplicateStr: r.FormValue("replication")}
	// fmt.Println("replication: ", createVolCmd.ReplicateStr)
	v, err := dir.raftServer.Do(createVolCmd)
	if err != nil {
		helper.WriteJson(w, createVolResult{Error: err.Error()}, http.StatusInternalServerError)
		return
	}
	volidip := v.(VolumeIDIP)
	for _, ip := range volidip.IP {
		var b bytes.Buffer
		bytes, err := json.Marshal(volidip)
		if err != nil {
			helper.WriteJson(w, createVolResult{Error: err.Error()}, http.StatusInternalServerError)
			return
		}
		b.Write(bytes)
		_, err = postAndError(fmt.Sprintf("http://%s/vol/create", ip), "application/json", &b)
		if err != nil {
			helper.WriteJson(w, createVolResult{Error: err.Error()}, http.StatusInternalServerError)
			return
		}
	}
	helper.WriteJson(w, volidip, http.StatusOK)
}
func (dir *Directory) assignFileIDHandler(w http.ResponseWriter, r *http.Request) {
	u4 := uuid.NewV4()
	keyBytes := u4.Bytes()
	needleid := helper.BytesToUInt64(keyBytes[:8])
	volIDIP, err := dir.pickVolume(r.FormValue("replication"))
	if err != nil {
		helper.WriteJson(w, assignFileIDResult{Error: err.Error()}, http.StatusInternalServerError)
		return
	}
	cookie := rand.Uint32()
	fid := fmt.Sprintf("%d,%d,%d", volIDIP.ID, needleid, cookie)
	a := assignFileIDResult{
		FID:   fid,
		VolIP: volIDIP.IP[rand.Intn(len(volIDIP.IP))],
	}
	helper.WriteJson(w, a, http.StatusOK)
}
Example #3
0
func (ss *StoreServer) uploadHandler(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	vars := mux.Vars(r)
	fileIDStr := vars["fileID"]
	volID, needleID, cookie, err := newFileID(fileIDStr)
	if err != nil {
		helper.WriteJson(w, result{Error: err.Error()}, http.StatusInternalServerError)
		return
	}
	if ss.volumeMap[volID] == nil {
		helper.WriteJson(w, result{Error: fmt.Sprintf("no volume %d", volID)}, http.StatusInternalServerError)
		return
	}
	data, name, err := parseUpload(r)
	if err != nil {
		helper.WriteJson(w, result{Error: err.Error()}, http.StatusInternalServerError)
		return
	}
	n := storage.NewNeedle(cookie, needleID, data, name)
	if err = ss.volumeMap[volID].AppendNeedle(n); err != nil {
		helper.WriteJson(w, result{Error: err.Error()}, http.StatusInternalServerError)
		return
	}

	fi, _ := ss.volumeMap[volID].StoreFile.Stat()
	vi := volumeInfo{
		ID:   volID,
		Size: fi.Size(),
	}
	viBytes, _ := json.Marshal(vi)
	for i := range ss.conf.Directories { // send volume information to directory server
		var b bytes.Buffer
		b.Write(viBytes)
		_, err := postAndError("http://"+ss.conf.Directories[i]+"/vol/info", "application/json", &b)
		if err == nil {
			break
		} else {
			log4go.Warn("send volumeInfo to directory get err: %s", err.Error())
		}
	}
	for _, localVolIDIP := range ss.localVolIDIPs {
		if localVolIDIP.ID == volID {
			for _, ip := range localVolIDIP.IP {
				if ip != ss.Addr {
					if err = replicateUpload(fmt.Sprintf("http://%s/replicate/%s", ip, fileIDStr), string(name), data); err != nil {
						helper.WriteJson(w, result{Error: err.Error()}, http.StatusInternalServerError)
						return
					}
				}
			}
			break
		}
	}
	res := result{
		Name: string(name),
		Size: len(data),
	}
	helper.WriteJson(w, res, http.StatusOK)

}
Example #4
0
func (ss *StoreServer) getFileHandler(w http.ResponseWriter, r *http.Request) {
	fileIDStr := mux.Vars(r)["fileID"]
	if li := strings.LastIndex(fileIDStr, "."); li != -1 {
		fileIDStr = fileIDStr[:li]
	}
	volID, needleID, cookie, err := newFileID(fileIDStr)
	if err != nil {
		helper.WriteJson(w, result{Error: err.Error()}, http.StatusInternalServerError)
		return
	}
	if ss.volumeMap[volID] == nil {
		helper.WriteJson(w, result{Error: fmt.Sprintf("no volume %d", volID)}, http.StatusInternalServerError)
		return
	}
	n, err := ss.volumeMap[volID].GetNeedle(needleID, cookie)
	if err != nil {
		helper.WriteJson(w, result{Error: err.Error()}, http.StatusInternalServerError)
		return
	}
	filename := string(n.Name)
	dotIndex := strings.LastIndex(filename, ".")
	contentType := ""
	if dotIndex > 0 {
		ext := filename[dotIndex:]
		contentType = mime.TypeByExtension(ext)
	}
	if contentType != "" {
		w.Header().Set("Content-Type", contentType)
	}
	// TODO: Add ETAG
	w.Header().Set("Content-Disposition", fmt.Sprintf("filename=\"%s\"", filename))
	w.Header().Set("Content-Length", strconv.Itoa(len(n.Data)))
	_, err = w.Write(n.Data)
	if err != nil {
		log4go.Error(err.Error())
	}
}
Example #5
0
func (dir *Directory) proxyToLeader(f func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		if dir.raftServer.Leader() == dir.raftServer.Name() {
			f(w, r)
		} else {
			targetURL, err := url.Parse(dir.raftServer.Leader())
			if err != nil {
				helper.WriteJson(w, err.Error(), http.StatusInternalServerError)
				return
			}
			log4go.Info("proxying to raft leader: %s", dir.raftServer.Leader())
			proxy := httputil.NewSingleHostReverseProxy(targetURL)
			proxy.Transport = transport
			proxy.ServeHTTP(w, r)
		}
	}
}