/*
# Basic Usage:
curl http://localhost:9333/dir/assign
{"count":1,"fid":"3,01637037d6","url":"127.0.0.1:8080",
"publicUrl":"localhost:8080"}

# To assign with a specific replication type:
curl "http://localhost:9333/dir/assign?replication=001"

# To specify how many file ids to reserve
curl "http://localhost:9333/dir/assign?count=5"

# To assign a specific data center
curl "http://localhost:9333/dir/assign?dataCenter=dc1"
*/
func Assign(server string, count int, replication string, collection string, ttl string) (*AssignResult, error) {
	values := make(url.Values)
	values.Add("count", strconv.Itoa(count))
	if replication != "" {
		values.Add("replication", replication)
	}
	if collection != "" {
		values.Add("collection", collection)
	}
	if ttl != "" {
		values.Add("ttl", ttl)
	}
	jsonBlob, err := util.Post("http://"+server+"/dir/assign", values)
	glog.V(2).Info("assign result :", string(jsonBlob))
	if err != nil {
		return nil, err
	}
	var ret AssignResult
	err = json.Unmarshal(jsonBlob, &ret)
	if err != nil {
		return nil, err
	}
	if ret.Count <= 0 {
		return nil, errors.New(ret.Error)
	}
	return &ret, nil
}
Exemple #2
0
//按volume查找
//http://192.168.1.2:80/vol/lookup
func LookupVolumeIds(server string, vids []string) (map[string]LookupResult, error) {
	values := make(url.Values)
	for _, vid := range vids {
		values.Add("volumeId", vid)
	}
	jsonBlob, err := util.Post("http://"+server+"/vol/lookup", values)
	if err != nil {
		return nil, err
	}
	ret := make(map[string]LookupResult)
	err = json.Unmarshal(jsonBlob, &ret)
	if err != nil {
		return nil, errors.New(err.Error() + " " + string(jsonBlob))
	}
	return ret, nil
}
Exemple #3
0
//http://192.168.1.2:80/dir/lookup
func do_lookup(server string, vid string) (*LookupResult, error) {
	values := make(url.Values)
	values.Add("volumeId", vid)
	jsonBlob, err := util.Post("http://"+server+"/dir/lookup", values)
	if err != nil {
		return nil, err
	}
	var ret LookupResult
	err = json.Unmarshal(jsonBlob, &ret)
	if err != nil {
		return nil, err
	}
	if ret.Error != "" {
		return nil, errors.New(ret.Error)
	}
	return &ret, nil
}
func call(server string, request ApiRequest, ret interface{}) error {
	b, err := json.Marshal(request)
	if err != nil {
		fmt.Println("error:", err)
		return nil
	}
	values := make(url.Values)
	values.Add("request", string(b))
	jsonBlob, err := util.Post("http://"+server+"/__api__", values)
	if err != nil {
		return err
	}
	err = json.Unmarshal(jsonBlob, ret)
	if err != nil {
		return err
	}
	return nil
}
//http://192.168.1.1:8080/admin/assign_volume
func AllocateVolume(dn *DataNode, vid storage.VolumeId, option *VolumeGrowOption) error {
	values := make(url.Values)
	values.Add("volume", vid.String())
	values.Add("collection", option.Collection)
	values.Add("replication", option.ReplicaPlacement.String())
	values.Add("ttl", option.Ttl.String())
	jsonBlob, err := util.Post("http://"+dn.PublicUrl+"/admin/assign_volume", values)
	if err != nil {
		return err
	}
	var ret AllocateVolumeResult
	if err := json.Unmarshal(jsonBlob, &ret); err != nil {
		return err
	}
	if ret.Error != "" {
		return errors.New(ret.Error)
	}
	return nil
}
Exemple #6
0
func DeleteFiles(master string, fileIds []string) (*DeleteFilesResult, error) {
	vid_to_fileIds := make(map[string][]string)
	ret := &DeleteFilesResult{}
	var vids []string
	for _, fileId := range fileIds {
		vid, _, err := ParseFileId(fileId)
		if err != nil {
			ret.Results = append(ret.Results, DeleteResult{Fid: vid, Error: err.Error()})
			continue
		}
		if _, ok := vid_to_fileIds[vid]; !ok {
			vid_to_fileIds[vid] = make([]string, 0)
			vids = append(vids, vid)
		}
		vid_to_fileIds[vid] = append(vid_to_fileIds[vid], fileId)
	}

	lookupResults, err := LookupVolumeIds(master, vids)
	if err != nil {
		return ret, err
	}

	server_to_fileIds := make(map[string][]string)
	for vid, result := range lookupResults {
		if result.Error != "" {
			ret.Errors = append(ret.Errors, result.Error)
			continue
		}
		for _, location := range result.Locations {
			if _, ok := server_to_fileIds[location.Url]; !ok {
				server_to_fileIds[location.Url] = make([]string, 0)
			}
			server_to_fileIds[location.Url] = append(
				server_to_fileIds[location.Url], vid_to_fileIds[vid]...)
		}
	}

	var wg sync.WaitGroup
	for server, fidList := range server_to_fileIds {
		wg.Add(1)
		go func(server string, fidList []string) {
			defer wg.Done()
			values := make(url.Values)
			for _, fid := range fidList {
				values.Add("fid", fid)
			}
			jsonBlob, err := util.Post("http://"+server+"/delete", values)
			if err != nil {
				ret.Errors = append(ret.Errors, err.Error()+" "+string(jsonBlob))
				return
			}
			var result []DeleteResult
			err = json.Unmarshal(jsonBlob, &result)
			if err != nil {
				ret.Errors = append(ret.Errors, err.Error()+" "+string(jsonBlob))
				return
			}
			ret.Results = append(ret.Results, result...)
		}(server, fidList)
	}
	wg.Wait()

	return ret, nil
}
/*
此函数的作用是从集群中删除一组文件它的执行步骤如下:
1.将文件按volume 分组
2.将volume归并出最终的volume集合
3.从master中获得volumes所在服务器的列表,因为一个server可能会有多个volumes
4.将文件按服务器分组
5.从服务器上将所持有的文件删除

*/
func DeleteFiles(master string, fileIds []string) (*DeleteFilesResult, error) {
	vid_to_fileIds := make(map[string][]string)
	ret := &DeleteFilesResult{}
	var vids []string

	/*
		此循环做了两件事情:
		1.将参数fileIds所指定的所有的file所存入的volume找出来放到vids中 即统计出哪些volume参与了操作
		2.将fileIds按volume分组
	*/
	for _, fileId := range fileIds {
		vid, _, err := ParseFileId(fileId)
		if err != nil {
			ret.Results = append(ret.Results, DeleteResult{Fid: vid, Error: err.Error()})
			continue
		}

		//如果此vid尚未cache
		if _, ok := vid_to_fileIds[vid]; !ok {
			vid_to_fileIds[vid] = make([]string, 0)
			vids = append(vids, vid) //cache新的vid
		}

		//某个volume下的所有field
		vid_to_fileIds[vid] = append(vid_to_fileIds[vid], fileId)
	}

	//从master获得所有的vid的urls
	lookupResults, err := LookupVolumeIds(master, vids)
	if err != nil {
		return ret, err
	}

	server_to_fileIds := make(map[string][]string)
	for vid, result := range lookupResults {
		if result.Error != "" {
			ret.Errors = append(ret.Errors, result.Error)
			continue
		}

		//此循环的作用是按PublicUrl即server将所有的files分组
		for _, location := range result.Locations {
			if _, ok := server_to_fileIds[location.PublicUrl]; !ok {
				server_to_fileIds[location.PublicUrl] = make([]string, 0)
			}
			server_to_fileIds[location.PublicUrl] = append(
				server_to_fileIds[location.PublicUrl], vid_to_fileIds[vid]...)
		}
	}

	var wg sync.WaitGroup
	for server, fidList := range server_to_fileIds {
		wg.Add(1)
		go func(server string, fidList []string) {
			defer wg.Done()
			values := make(url.Values)
			for _, fid := range fidList {
				values.Add("fid", fid)
			}

			//从某个server删除此server上的所有files
			jsonBlob, err := util.Post("http://"+server+"/delete", values)
			if err != nil {
				ret.Errors = append(ret.Errors, err.Error()+" "+string(jsonBlob))
				return
			}
			var result []DeleteResult
			err = json.Unmarshal(jsonBlob, &result)
			if err != nil {
				ret.Errors = append(ret.Errors, err.Error()+" "+string(jsonBlob))
				return
			}
			ret.Results = append(ret.Results, result...)
		}(server, fidList)
	}
	wg.Wait()

	return ret, nil
}