diff --git a/server/api/etcd_api_test.go b/server/api/etcd_api_test.go new file mode 100644 index 00000000000..593ea904e2a --- /dev/null +++ b/server/api/etcd_api_test.go @@ -0,0 +1,51 @@ +// Copyright 2019 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package api + +import ( + "encoding/json" + "net/http" + "strings" + + . "github.com/pingcap/check" +) + +var _ = Suite(&testEtcdAPISuite{}) + +type testEtcdAPISuite struct { + hc *http.Client +} + +func (s *testEtcdAPISuite) SetUpSuite(c *C) { + s.hc = newHTTPClient() +} + +func (s *testEtcdAPISuite) TestGRPCGateway(c *C) { + svr, clean := mustNewServer(c) + defer clean() + + addr := svr.GetConfig().ClientUrls + "/v3/kv/put" + putKey := map[string]string{"key": "Zm9v", "value": "YmFy"} + v, _ := json.Marshal(putKey) + err := postJSON(addr, v) + c.Assert(err, IsNil) + addr = svr.GetConfig().ClientUrls + "/v3/kv/range" + getKey := map[string]string{"key": "Zm9v"} + v, _ = json.Marshal(getKey) + err = postJSON(addr, v, func(res []byte) bool { + c.Assert(strings.Contains(string(res), "Zm9v"), IsTrue) + return true + }) + c.Assert(err, IsNil) +} diff --git a/server/api/util.go b/server/api/util.go index bed7abf8ad1..4dcae2ab382 100644 --- a/server/api/util.go +++ b/server/api/util.go @@ -86,19 +86,26 @@ func readJSON(r io.ReadCloser, data interface{}) error { return nil } -func postJSON(url string, data []byte) error { +func postJSON(url string, data []byte, checkOpts ...func(res []byte) bool) error { resp, err := dialClient.Post(url, "application/json", bytes.NewBuffer(data)) if err != nil { return errors.WithStack(err) } res, err := ioutil.ReadAll(resp.Body) - resp.Body.Close() + defer resp.Body.Close() + if err != nil { return err } + if resp.StatusCode != http.StatusOK { return errors.New(string(res)) } + for _, opt := range checkOpts { + if !opt(res) { + return errors.New("check failed") + } + } return nil } diff --git a/server/config.go b/server/config.go index e69c69ce452..4853f6fa9a6 100644 --- a/server/config.go +++ b/server/config.go @@ -49,9 +49,10 @@ type Config struct { AdvertiseClientUrls string `toml:"advertise-client-urls" json:"advertise-client-urls"` AdvertisePeerUrls string `toml:"advertise-peer-urls" json:"advertise-peer-urls"` - Name string `toml:"name" json:"name"` - DataDir string `toml:"data-dir" json:"data-dir"` - ForceNewCluster bool `json:"force-new-cluster"` + Name string `toml:"name" json:"name"` + DataDir string `toml:"data-dir" json:"data-dir"` + ForceNewCluster bool `json:"force-new-cluster"` + EnableGRPCGateway bool `json:"enable-grpc-gateway"` InitialCluster string `toml:"initial-cluster" json:"initial-cluster"` InitialClusterState string `toml:"initial-cluster-state" json:"initial-cluster-state"` @@ -199,6 +200,7 @@ const ( defaultUseRegionStorage = true defaultStrictlyMatchLabel = false + defaultEnableGRPCGateway = true ) func adjustString(v *string, defValue string) { @@ -427,6 +429,9 @@ func (c *Config) Adjust(meta *toml.MetaData) error { if !configMetaData.IsDefined("enable-prevote") { c.PreVote = true } + if !configMetaData.IsDefined("enable-grpc-gateway") { + c.EnableGRPCGateway = defaultEnableGRPCGateway + } return nil } @@ -876,6 +881,7 @@ func (c *Config) genEmbedEtcdConfig() (*embed.Config, error) { cfg.PeerTLSInfo.KeyFile = c.Security.KeyPath cfg.ForceNewCluster = c.ForceNewCluster cfg.ZapLoggerBuilder = embed.NewZapCoreLoggerBuilder(c.logger, c.logger.Core(), c.logProps.Syncer) + cfg.EnableGRPCGateway = c.EnableGRPCGateway cfg.Logger = "zap" var err error