Browse Source

feat(peer_server): add State field to machineMessage

State field indicates the state of each machine.
For now, its value could be follower or leader.
Yicheng Qin 11 years ago
parent
commit
04f09d2fd0
2 changed files with 35 additions and 4 deletions
  1. 12 4
      server/peer_server_handlers.go
  2. 23 0
      tests/functional/cluster_config_test.go

+ 12 - 4
server/peer_server_handlers.go

@@ -223,8 +223,9 @@ func (ps *PeerServer) setClusterConfigHttpHandler(w http.ResponseWriter, req *ht
 // Retrieves a list of peers and standbys.
 // Retrieves a list of peers and standbys.
 func (ps *PeerServer) getMachinesHttpHandler(w http.ResponseWriter, req *http.Request) {
 func (ps *PeerServer) getMachinesHttpHandler(w http.ResponseWriter, req *http.Request) {
 	machines := make([]*machineMessage, 0)
 	machines := make([]*machineMessage, 0)
+	leader := ps.raftServer.Leader()
 	for _, name := range ps.registry.Names() {
 	for _, name := range ps.registry.Names() {
-		machines = append(machines, ps.getMachineMessage(name))
+		machines = append(machines, ps.getMachineMessage(name, leader))
 	}
 	}
 	json.NewEncoder(w).Encode(&machines)
 	json.NewEncoder(w).Encode(&machines)
 }
 }
@@ -232,21 +233,27 @@ func (ps *PeerServer) getMachinesHttpHandler(w http.ResponseWriter, req *http.Re
 // Retrieve single peer or standby.
 // Retrieve single peer or standby.
 func (ps *PeerServer) getMachineHttpHandler(w http.ResponseWriter, req *http.Request) {
 func (ps *PeerServer) getMachineHttpHandler(w http.ResponseWriter, req *http.Request) {
 	vars := mux.Vars(req)
 	vars := mux.Vars(req)
-	json.NewEncoder(w).Encode(ps.getMachineMessage(vars["name"]))
+	m := ps.getMachineMessage(vars["name"], ps.raftServer.Leader())
+	json.NewEncoder(w).Encode(m)
 }
 }
 
 
-func (ps *PeerServer) getMachineMessage(name string) *machineMessage {
+func (ps *PeerServer) getMachineMessage(name string, leader string) *machineMessage {
 	if !ps.registry.Exists(name) {
 	if !ps.registry.Exists(name) {
 		return nil
 		return nil
 	}
 	}
 
 
 	clientURL, _ := ps.registry.ClientURL(name)
 	clientURL, _ := ps.registry.ClientURL(name)
 	peerURL, _ := ps.registry.PeerURL(name)
 	peerURL, _ := ps.registry.PeerURL(name)
-	return &machineMessage{
+	msg := &machineMessage{
 		Name:      name,
 		Name:      name,
+		State:     raft.Follower,
 		ClientURL: clientURL,
 		ClientURL: clientURL,
 		PeerURL:   peerURL,
 		PeerURL:   peerURL,
 	}
 	}
+	if name == leader {
+		msg.State = raft.Leader
+	}
+	return msg
 }
 }
 
 
 // Response to the name request
 // Response to the name request
@@ -298,6 +305,7 @@ func (ps *PeerServer) UpgradeHttpHandler(w http.ResponseWriter, req *http.Reques
 // machineMessage represents information about a peer or standby in the registry.
 // machineMessage represents information about a peer or standby in the registry.
 type machineMessage struct {
 type machineMessage struct {
 	Name      string `json:"name"`
 	Name      string `json:"name"`
+	State     string `json:"state"`
 	ClientURL string `json:"clientURL"`
 	ClientURL string `json:"clientURL"`
 	PeerURL   string `json:"peerURL"`
 	PeerURL   string `json:"peerURL"`
 }
 }

+ 23 - 0
tests/functional/cluster_config_test.go

@@ -2,6 +2,7 @@ package test
 
 
 import (
 import (
 	"bytes"
 	"bytes"
+	"encoding/json"
 	"os"
 	"os"
 	"testing"
 	"testing"
 	"time"
 	"time"
@@ -27,3 +28,25 @@ func TestClusterConfig(t *testing.T) {
 	assert.Equal(t, body["activeSize"], 3)
 	assert.Equal(t, body["activeSize"], 3)
 	assert.Equal(t, body["promoteDelay"], 60)
 	assert.Equal(t, body["promoteDelay"], 60)
 }
 }
+
+// TestGetMachines tests '/v2/admin/machines' sends back messages of all machines.
+func TestGetMachines(t *testing.T) {
+	_, etcds, err := CreateCluster(3, &os.ProcAttr{Files: []*os.File{nil, os.Stdout, os.Stderr}}, false)
+	assert.NoError(t, err)
+	defer DestroyCluster(etcds)
+
+	time.Sleep(1 * time.Second)
+
+	resp, err := tests.Get("http://localhost:7001/v2/admin/machines")
+	if !assert.Equal(t, err, nil) {
+		t.FailNow()
+	}
+	assert.Equal(t, resp.StatusCode, 200)
+	machines := make([]map[string]interface{}, 0)
+	b := tests.ReadBody(resp)
+	json.Unmarshal(b, &machines)
+	assert.Equal(t, len(machines), 3)
+	if machines[0]["state"] != "leader" && machines[1]["state"] != "leader" && machines[2]["state"] != "leader" {
+		t.Errorf("no leader in the cluster")
+	}
+}