Browse Source

Merge pull request #1386 from unihorn/184

etcdserver: update member attribute when apply request
Yicheng Qin 11 years ago
parent
commit
49a68adcf1
2 changed files with 33 additions and 0 deletions
  1. 13 0
      etcdserver/server.go
  2. 20 0
      etcdserver/server_test.go

+ 13 - 0
etcdserver/server.go

@@ -25,6 +25,7 @@ import (
 	"net/http"
 	"os"
 	"path"
+	"regexp"
 	"strconv"
 	"sync/atomic"
 	"time"
@@ -65,6 +66,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() {
@@ -582,6 +585,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":

+ 20 - 0
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}