From ea0bff80c010f3ec96f99819b27ac7dd3da48d91 Mon Sep 17 00:00:00 2001 From: Yicheng Qin Date: Fri, 24 Oct 2014 01:13:47 -0700 Subject: [PATCH] etcdserver: update member attribute when apply request --- etcdserver/server.go | 13 +++++++++++++ etcdserver/server_test.go | 20 ++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/etcdserver/server.go b/etcdserver/server.go index b11f8df9b..fc7d3deb5 100644 --- a/etcdserver/server.go +++ b/etcdserver/server.go @@ -23,6 +23,7 @@ import ( "math/rand" "os" "path" + "regexp" "strconv" "sync/atomic" "time" @@ -63,6 +64,8 @@ var ( storeMembersPrefix = path.Join(StoreAdminPrefix, "members") storeRemovedMembersPrefix = path.Join(StoreAdminPrefix, "removed_members") + + storeMemberAttributeRegexp = regexp.MustCompile(path.Join(storeMembersPrefix, "[[:xdigit:]]{1,16}", attributesSuffix)) ) func init() { @@ -568,6 +571,16 @@ func (s *EtcdServer) applyRequest(r pb.Request) Response { case r.PrevIndex > 0 || r.PrevValue != "": return f(s.store.CompareAndSwap(r.Path, r.PrevValue, r.PrevIndex, r.Val, expr)) default: + if storeMemberAttributeRegexp.MatchString(r.Path) { + id := parseMemberID(path.Dir(r.Path)) + m := s.Cluster.Member(id) + if m == nil { + log.Fatalf("fetch member %x should never fail", id) + } + if err := json.Unmarshal([]byte(r.Val), &m.Attributes); err != nil { + log.Fatalf("unmarshal %s should never fail: %v", r.Val, err) + } + } return f(s.store.Set(r.Path, r.Dir, r.Val, expr)) } case "DELETE": diff --git a/etcdserver/server_test.go b/etcdserver/server_test.go index 26d7e807a..110e6028e 100644 --- a/etcdserver/server_test.go +++ b/etcdserver/server_test.go @@ -22,6 +22,7 @@ import ( "math/rand" "path" "reflect" + "strconv" "sync" "testing" "time" @@ -384,6 +385,25 @@ func TestApplyRequest(t *testing.T) { } } +func TestApplyRequestOnAdminMemberAttributes(t *testing.T) { + cl := newTestCluster([]Member{{ID: 1}}) + srv := &EtcdServer{ + store: &storeRecorder{}, + Cluster: cl, + } + req := pb.Request{ + Method: "PUT", + ID: 1, + Path: path.Join(storeMembersPrefix, strconv.FormatUint(1, 16), attributesSuffix), + Val: `{"Name":"abc","ClientURLs":["http://127.0.0.1:4001"]}`, + } + srv.applyRequest(req) + w := Attributes{Name: "abc", ClientURLs: []string{"http://127.0.0.1:4001"}} + if g := cl.Member(1).Attributes; !reflect.DeepEqual(g, w) { + t.Errorf("attributes = %v, want %v", g, w) + } +} + // TODO: test ErrIDRemoved func TestApplyConfChangeError(t *testing.T) { nodes := []uint64{1, 2, 3}