diff --git a/etcdnaming/etcdnaming.go b/etcdnaming/etcdnaming.go new file mode 100644 index 00000000..10727f90 --- /dev/null +++ b/etcdnaming/etcdnaming.go @@ -0,0 +1,73 @@ +package etcdnaming + +import ( + "io/ioutil" + "net/http" + "strings" +) + +func parser(body string) map[string]string { + if body == "" { + return nil + } + res := make(map[string]string) + str := strings.Replace(body, "nodes", "Nodes", -1) + subStr := strings.Split(str, "node") + for _, entry := range subStr { + i := 0 + var last int + if strings.Contains(entry, "prevNode") { + last = strings.IndexAny(entry, "prevNode") + } else { + last = len(entry) + } + for i < last { + if entry[i] == '{' { + j := i + 1 + subEntry := []byte{} + for j < len(entry) && entry[j] != '{' && entry[j] != '}' { + subEntry = append(subEntry, entry[j]) + j++ + } + if j < len(entry) && entry[j] == '}' { + var ( + key string + value string + ) + for _, val := range strings.Split(string(subEntry), ",") { + if strings.Contains(val, "key") { + key = strings.Replace(strings.SplitN(val, ":", 2)[1], `"`, "", -1) + } + if strings.Contains(val, "value") { + value = strings.Replace(strings.SplitN(val, ":", 2)[1], `"`, "", -1) + } + res[key] = value + + } + } + i = j + } else { + i++ + } + } + } + return res +} + +func Etcdnaming(host string, key string, watch bool) map[string]string { + var comm string + if !watch { + comm = "http://" + host + "/v2/keys/" + key + "/?recursive=true" + } else { + comm = "http://" + host + "/v2/keys/" + key + `?wait=true&recursive=true` + } + resp, err := http.Get(comm) + if err != nil { + panic(err) + } + defer resp.Body.Close() + var body []byte + body, err = ioutil.ReadAll(resp.Body) + res := parser(string(body)) + return res +} diff --git a/etcdnaming/etcdnaming_test.go b/etcdnaming/etcdnaming_test.go new file mode 100644 index 00000000..d3370977 --- /dev/null +++ b/etcdnaming/etcdnaming_test.go @@ -0,0 +1,29 @@ +package etcdnaming + +import ( + "testing" +) + +func TestEtcdParsing(t *testing.T) { + for _, test := range []struct { + // input + body string + // expected + expected map[string]string + }{ + {"", nil}, + {`{"action":"set","node":{"key":"/foo","value":"bar5","modifiedIndex":30,"createdIndex":30}}`, map[string]string{"/foo": "bar5"}}, + {`{"action":"set","node":{"key":"/foo_dir/foo2","value":"bar2","modifiedIndex":59,"createdIndex":59},"prevNode":{"key":"/foo_dir/foo2","value":"bar","modifiedIndex":58,"createdIndex":58}}`, map[string]string{"/foo_dir/foo2": "bar2"}}, + {`{"action":"get","node":{"key":"/foo_dir","dir":true,"nodes":[{"key":"/foo_dir/foo2","value":"bar2","modifiedIndex":33,"createdIndex":33},{"key":"/foo_dir/bar_dir","dir":true,"nodes":[{"key":"/foo_dir/bar_dir/bar1","value":"a","modifiedIndex":35,"createdIndex":35},{"key":"/foo_dir/bar_dir/bar2","value":"b","modifiedIndex":36,"createdIndex":36}],"modifiedIndex":34,"createdIndex":34},{"key":"/foo_dir/bar_dir2","dir":true,"nodes":[{"key":"/foo_dir/bar_dir2/bar3","value":"c","modifiedIndex":39,"createdIndex":39}],"modifiedIndex":38,"createdIndex":38},{"key":"/foo_dir/foo6","value":"newbar2","modifiedIndex":48,"createdIndex":48},{"key":"/foo_dir/foo3","value":"newbar2","modifiedIndex":50,"createdIndex":50},{"key":"/foo_dir/foo","value":"newbar","modifiedIndex":42,"createdIndex":42}],"modifiedIndex":32,"createdIndex":32}}`, map[string]string{"/foo_dir/foo2": "bar2", "/foo_dir/bar_dir/bar1": "a", "/foo_dir/bar_dir/bar2": "b", "/foo_dir/bar_dir2/bar3": "c", "/foo_dir/foo6": "newbar2", "/foo_dir/foo3": "newbar2", "/foo_dir/foo": "newbar"}}, + } { + out := parser(test.body) + if len(test.expected) != len(out) { + t.Fatalf("want result length %v, get %v", len(test.expected), len(out)) + } + for key, _ := range out { + if test.expected[key] != out[key] { + t.Fatalf("expected result error!, want %v get %v", test.expected[key], out[key]) + } + } + } +}