From afafaf027d5e061f6a94fe23ad5d4aaa0624325c Mon Sep 17 00:00:00 2001 From: ShuNing Date: Wed, 7 Nov 2018 13:26:34 +0800 Subject: [PATCH] server/api: fix the issue about `regions/check` API (#1311) * server/api: fix region check API interface --- server/api/region.go | 75 ++++++++++++++++----------------------- server/api/region_test.go | 25 +++++++++++++ 2 files changed, 56 insertions(+), 44 deletions(-) diff --git a/server/api/region.go b/server/api/region.go index d743d1bc9b1c..cb65b5097889 100644 --- a/server/api/region.go +++ b/server/api/region.go @@ -122,21 +122,25 @@ func newRegionsHandler(svr *server.Server, rd *render.Render) *regionsHandler { } } -func (h *regionsHandler) GetAll(w http.ResponseWriter, r *http.Request) { - cluster := h.svr.GetRaftCluster() - if cluster == nil { - h.rd.JSON(w, http.StatusInternalServerError, server.ErrNotBootstrapped.Error()) - return - } - regions := cluster.GetRegions() +func convertToAPIRegions(regions []*core.RegionInfo) *regionsInfo { regionInfos := make([]*regionInfo, len(regions)) for i, r := range regions { regionInfos[i] = newRegionInfo(r) } - regionsInfo := ®ionsInfo{ + return ®ionsInfo{ Count: len(regions), Regions: regionInfos, } +} + +func (h *regionsHandler) GetAll(w http.ResponseWriter, r *http.Request) { + cluster := h.svr.GetRaftCluster() + if cluster == nil { + h.rd.JSON(w, http.StatusInternalServerError, server.ErrNotBootstrapped.Error()) + return + } + regions := cluster.GetRegions() + regionsInfo := convertToAPIRegions(regions) h.rd.JSON(w, http.StatusOK, regionsInfo) } @@ -162,15 +166,7 @@ func (h *regionsHandler) ScanRegionsByKey(w http.ResponseWriter, r *http.Request limit = maxRegionLimit } regions := cluster.ScanRegionsByKey([]byte(startKey), limit) - - regionInfos := make([]*regionInfo, 0, len(regions)) - for _, region := range regions { - regionInfos = append(regionInfos, newRegionInfo(region)) - } - regionsInfo := ®ionsInfo{ - Count: len(regionInfos), - Regions: regionInfos, - } + regionsInfo := convertToAPIRegions(regions) h.rd.JSON(w, http.StatusOK, regionsInfo) } @@ -188,65 +184,63 @@ func (h *regionsHandler) GetStoreRegions(w http.ResponseWriter, r *http.Request) return } regions := cluster.GetStoreRegions(uint64(id)) - regionInfos := make([]*regionInfo, len(regions)) - for i, r := range regions { - regionInfos[i] = newRegionInfo(r) - } - regionsInfo := ®ionsInfo{ - Count: len(regions), - Regions: regionInfos, - } + regionsInfo := convertToAPIRegions(regions) h.rd.JSON(w, http.StatusOK, regionsInfo) } func (h *regionsHandler) GetMissPeerRegions(w http.ResponseWriter, r *http.Request) { handler := h.svr.GetHandler() - res, err := handler.GetMissPeerRegions() + regions, err := handler.GetMissPeerRegions() if err != nil { h.rd.JSON(w, http.StatusInternalServerError, err.Error()) return } - h.rd.JSON(w, http.StatusOK, res) + regionsInfo := convertToAPIRegions(regions) + h.rd.JSON(w, http.StatusOK, regionsInfo) } func (h *regionsHandler) GetExtraPeerRegions(w http.ResponseWriter, r *http.Request) { handler := h.svr.GetHandler() - res, err := handler.GetExtraPeerRegions() + regions, err := handler.GetExtraPeerRegions() if err != nil { h.rd.JSON(w, http.StatusInternalServerError, err.Error()) return } - h.rd.JSON(w, http.StatusOK, res) + regionsInfo := convertToAPIRegions(regions) + h.rd.JSON(w, http.StatusOK, regionsInfo) } func (h *regionsHandler) GetPendingPeerRegions(w http.ResponseWriter, r *http.Request) { handler := h.svr.GetHandler() - res, err := handler.GetPendingPeerRegions() + regions, err := handler.GetPendingPeerRegions() if err != nil { h.rd.JSON(w, http.StatusInternalServerError, err.Error()) return } - h.rd.JSON(w, http.StatusOK, res) + regionsInfo := convertToAPIRegions(regions) + h.rd.JSON(w, http.StatusOK, regionsInfo) } func (h *regionsHandler) GetDownPeerRegions(w http.ResponseWriter, r *http.Request) { handler := h.svr.GetHandler() - res, err := handler.GetDownPeerRegions() + regions, err := handler.GetDownPeerRegions() if err != nil { h.rd.JSON(w, http.StatusInternalServerError, err.Error()) return } - h.rd.JSON(w, http.StatusOK, res) + regionsInfo := convertToAPIRegions(regions) + h.rd.JSON(w, http.StatusOK, regionsInfo) } func (h *regionsHandler) GetIncorrectNamespaceRegions(w http.ResponseWriter, r *http.Request) { handler := h.svr.GetHandler() - res, err := handler.GetIncorrectNamespaceRegions() + regions, err := handler.GetIncorrectNamespaceRegions() if err != nil { h.rd.JSON(w, http.StatusInternalServerError, err.Error()) return } - h.rd.JSON(w, http.StatusOK, res) + regionsInfo := convertToAPIRegions(regions) + h.rd.JSON(w, http.StatusOK, regionsInfo) } func (h *regionsHandler) GetRegionSiblings(w http.ResponseWriter, r *http.Request) { @@ -323,15 +317,8 @@ func (h *regionsHandler) GetTopNRegions(w http.ResponseWriter, r *http.Request, limit = maxRegionLimit } regions := topNRegions(cluster.GetRegions(), less, limit) - regionInfos := make([]*regionInfo, len(regions)) - for i, r := range regions { - regionInfos[i] = newRegionInfo(r) - } - res := ®ionsInfo{ - Count: len(regions), - Regions: regionInfos, - } - h.rd.JSON(w, http.StatusOK, res) + regionsInfo := convertToAPIRegions(regions) + h.rd.JSON(w, http.StatusOK, regionsInfo) } // RegionHeap implements heap.Interface, used for selecting top n regions. diff --git a/server/api/region_test.go b/server/api/region_test.go index 40a25a4e8b29..53ff9b076108 100644 --- a/server/api/region_test.go +++ b/server/api/region_test.go @@ -21,6 +21,7 @@ import ( . "github.com/pingcap/check" "github.com/pingcap/kvproto/pkg/metapb" + "github.com/pingcap/kvproto/pkg/pdpb" "github.com/pingcap/pd/server" "github.com/pingcap/pd/server/core" ) @@ -84,6 +85,30 @@ func (s *testRegionSuite) TestRegion(c *C) { c.Assert(r2, DeepEquals, newRegionInfo(r)) } +func (s *testRegionSuite) TestRegionCheck(c *C) { + r := newTestRegionInfo(2, 1, []byte("a"), []byte("b")) + downPeer := &metapb.Peer{Id: 13, StoreId: 2} + r = r.Clone(core.WithAddPeer(downPeer), core.WithDownPeers([]*pdpb.PeerStats{{Peer: downPeer, DownSeconds: 3600}}), core.WithPendingPeers([]*metapb.Peer{downPeer})) + mustRegionHeartbeat(c, s.svr, r) + url := fmt.Sprintf("%s/region/id/%d", s.urlPrefix, r.GetID()) + r1 := ®ionInfo{} + err := readJSONWithURL(url, r1) + c.Assert(err, IsNil) + c.Assert(r1, DeepEquals, newRegionInfo(r)) + + url = fmt.Sprintf("%s/regions/check/%s", s.urlPrefix, "down-peer") + r2 := ®ionsInfo{} + err = readJSONWithURL(url, r2) + c.Assert(err, IsNil) + c.Assert(r2, DeepEquals, ®ionsInfo{Count: 1, Regions: []*regionInfo{newRegionInfo(r)}}) + + url = fmt.Sprintf("%s/regions/check/%s", s.urlPrefix, "pending-peer") + r3 := ®ionsInfo{} + err = readJSONWithURL(url, r3) + c.Assert(err, IsNil) + c.Assert(r3, DeepEquals, ®ionsInfo{Count: 1, Regions: []*regionInfo{newRegionInfo(r)}}) +} + func (s *testRegionSuite) TestRegions(c *C) { rs := []*core.RegionInfo{ newTestRegionInfo(2, 1, []byte("a"), []byte("b")),