You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ti...@apache.org on 2019/12/31 10:13:35 UTC
[servicecomb-kie] branch master updated: SCB-1699 support match
pattern (#60)
This is an automated email from the ASF dual-hosted git repository.
tianxiaoliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-kie.git
The following commit(s) were added to refs/heads/master by this push:
new f35cbba SCB-1699 support match pattern (#60)
f35cbba is described below
commit f35cbba3fe4c94072a4067bea6194bdae299033d
Author: Shawn <xi...@gmail.com>
AuthorDate: Tue Dec 31 18:13:29 2019 +0800
SCB-1699 support match pattern (#60)
---
pkg/common/common.go | 1 +
server/resource/v1/common.go | 19 +++-
server/resource/v1/doc_struct.go | 10 ++
server/resource/v1/history_resource_test.go | 2 +-
server/resource/v1/kv_resource.go | 5 +-
server/resource/v1/kv_resource_test.go | 159 +++++++++++++++-------------
server/resource/v1/v1_suite_test.go | 34 ------
server/service/mongo/kv/kv_dao.go | 3 -
server/service/mongo/kv/kv_service.go | 5 +
9 files changed, 124 insertions(+), 114 deletions(-)
diff --git a/pkg/common/common.go b/pkg/common/common.go
index 05b7ae3..22ab5a3 100644
--- a/pkg/common/common.go
+++ b/pkg/common/common.go
@@ -22,6 +22,7 @@ const (
QueryParamQ = "q"
QueryByLabelsCon = "&"
QueryParamWait = "wait"
+ QueryParamMatch = "match"
)
//http headers
diff --git a/server/resource/v1/common.go b/server/resource/v1/common.go
index 4cd6d1a..2db72c9 100644
--- a/server/resource/v1/common.go
+++ b/server/resource/v1/common.go
@@ -40,6 +40,7 @@ import (
//const of server
const (
+ PatternExact = "exact"
MsgDomainMustNotBeEmpty = "domain must not be empty"
MsgIllegalLabels = "label value can not be empty, " +
"label can not be duplicated, please check query parameters"
@@ -155,6 +156,14 @@ func getWaitDuration(rctx *restful.Context) string {
}
return wait
}
+func getMatchPattern(rctx *restful.Context) string {
+ m := rctx.ReadQueryParameter(common.QueryParamMatch)
+
+ if m != "" && m != PatternExact {
+ return ""
+ }
+ return m
+}
func wait(d time.Duration, rctx *restful.Context, topic *pubsub.Topic) bool {
changed := true
if d != 0 {
@@ -197,9 +206,15 @@ func checkPagination(limitStr, offsetStr string) (int64, int64, error) {
}
return limit, offset, err
}
-func queryAndResponse(rctx *restful.Context, domain interface{}, project string, key string, labels map[string]string, limit, offset int) {
+func queryAndResponse(rctx *restful.Context,
+ domain interface{}, project string, key string, labels map[string]string, limit, offset int) {
+ m := getMatchPattern(rctx)
+ opts := []service.FindOption{service.WithKey(key), service.WithLabels(labels)}
+ if m == PatternExact {
+ opts = append(opts, service.WithExactLabels())
+ }
kv, err := service.KVService.List(rctx.Ctx, domain.(string), project,
- limit, offset, service.WithKey(key), service.WithLabels(labels))
+ limit, offset, opts...)
if err != nil {
if err == service.ErrKeyNotExists {
WriteErrResponse(rctx, http.StatusNotFound, err.Error(), common.ContentTypeText)
diff --git a/server/resource/v1/doc_struct.go b/server/resource/v1/doc_struct.go
index 9b6ecf4..6a00529 100644
--- a/server/resource/v1/doc_struct.go
+++ b/server/resource/v1/doc_struct.go
@@ -48,10 +48,20 @@ var (
DataType: "string",
Name: common.QueryParamWait,
ParamType: goRestful.QueryParameterKind,
+ Required: false,
Desc: "wait until any kv changed. " +
"for example wait=5s, server will not response until 5 seconds during that time window, " +
"if any kv changed, server will return 200 and kv list, otherwise return 304 and empty body",
}
+ DocQueryMatch = &restful.Parameters{
+ DataType: "string",
+ Name: common.QueryParamMatch,
+ ParamType: goRestful.QueryParameterKind,
+ Required: false,
+ Desc: "match works with label query param, it specifies label match pattern. " +
+ "if it is empty, server will return kv which's labels partial match the label query param. " +
+ "uf it is exact, server will return kv which's labels exact match the label query param",
+ }
DocQueryKVIDParameters = &restful.Parameters{
DataType: "string",
Name: "kvID",
diff --git a/server/resource/v1/history_resource_test.go b/server/resource/v1/history_resource_test.go
index c431614..c088f09 100644
--- a/server/resource/v1/history_resource_test.go
+++ b/server/resource/v1/history_resource_test.go
@@ -77,7 +77,7 @@ var _ = Describe("v1 history resource", func() {
It("should not return err", func() {
Expect(err).Should(BeNil())
})
- data := []*model.LabelRevisionDoc{}
+ data := make([]*model.LabelRevisionDoc, 0)
err = json.Unmarshal(body, &data)
It("should not return err", func() {
Expect(err).Should(BeNil())
diff --git a/server/resource/v1/kv_resource.go b/server/resource/v1/kv_resource.go
index 0ac5751..c56b356 100644
--- a/server/resource/v1/kv_resource.go
+++ b/server/resource/v1/kv_resource.go
@@ -279,8 +279,7 @@ func (r *KVResource) URLPatterns() []restful.Route {
ResourceFunc: r.GetByKey,
FuncDesc: "get key values by key and labels",
Parameters: []*restful.Parameters{
- DocPathProject, DocPathKey,
- DocQueryLabelParameters,
+ DocPathProject, DocPathKey, DocQueryLabelParameters, DocQueryMatch,
},
Returns: []*restful.Returns{
{
@@ -316,7 +315,7 @@ func (r *KVResource) URLPatterns() []restful.Route {
ResourceFunc: r.List,
FuncDesc: "list key values by labels and key",
Parameters: []*restful.Parameters{
- DocPathProject, DocQueryLabelParameters, DocQueryWait,
+ DocPathProject, DocQueryLabelParameters, DocQueryWait, DocQueryMatch,
},
Returns: []*restful.Returns{
{
diff --git a/server/resource/v1/kv_resource_test.go b/server/resource/v1/kv_resource_test.go
index dc1de85..4787753 100644
--- a/server/resource/v1/kv_resource_test.go
+++ b/server/resource/v1/kv_resource_test.go
@@ -20,34 +20,32 @@ package v1_test
import (
"bytes"
"encoding/json"
+ "github.com/apache/servicecomb-kie/pkg/model"
+ "github.com/apache/servicecomb-kie/server/config"
+ handler2 "github.com/apache/servicecomb-kie/server/handler"
"github.com/apache/servicecomb-kie/server/pubsub"
+ v1 "github.com/apache/servicecomb-kie/server/resource/v1"
"github.com/apache/servicecomb-kie/server/service"
+ "github.com/go-chassis/go-chassis/core/common"
+ "github.com/go-chassis/go-chassis/core/handler"
+ "github.com/go-chassis/go-chassis/server/restful/restfultest"
log "github.com/go-chassis/paas-lager"
"github.com/go-mesh/openlogging"
+ "github.com/stretchr/testify/assert"
"io/ioutil"
"net/http"
"net/http/httptest"
+ "testing"
- "github.com/go-chassis/go-chassis/core/common"
- "github.com/go-chassis/go-chassis/core/handler"
- "github.com/go-chassis/go-chassis/server/restful/restfultest"
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-
- "github.com/apache/servicecomb-kie/pkg/model"
- "github.com/apache/servicecomb-kie/server/config"
- noop "github.com/apache/servicecomb-kie/server/handler"
- v1 "github.com/apache/servicecomb-kie/server/resource/v1"
_ "github.com/apache/servicecomb-kie/server/service/mongo"
)
-var _ = Describe("v1 kv resource", func() {
+func TestKVResource_List(t *testing.T) {
log.Init(log.Config{
Writers: []string{"stdout"},
LoggerLevel: "DEBUG",
LogFormatText: false,
})
-
logger := log.NewLogger("ut")
openlogging.SetLogger(logger)
//for UT
@@ -63,66 +61,85 @@ var _ = Describe("v1 kv resource", func() {
}
pubsub.Init()
pubsub.Start()
- Describe("put kv", func() {
- Context("valid param", func() {
- kv := &model.KVDoc{
- Value: "1s",
- Labels: map[string]string{"service": "tester"},
- }
- j, _ := json.Marshal(kv)
- r, _ := http.NewRequest("PUT", "/v1/test/kie/kv/timeout", bytes.NewBuffer(j))
- noopH := &noop.NoopAuthHandler{}
- chain, _ := handler.CreateChain(common.Provider, "testchain1", noopH.Name())
- r.Header.Set("Content-Type", "application/json")
- kvr := &v1.KVResource{}
- c, _ := restfultest.New(kvr, chain)
- resp := httptest.NewRecorder()
- c.ServeHTTP(resp, r)
-
- body, err := ioutil.ReadAll(resp.Body)
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
+ t.Run("put kv, label is service", func(t *testing.T) {
+ kv := &model.KVDoc{
+ Value: "1s",
+ Labels: map[string]string{"service": "utService"},
+ }
+ j, _ := json.Marshal(kv)
+ r, _ := http.NewRequest("PUT", "/v1/test/kie/kv/timeout", bytes.NewBuffer(j))
+ noopH := &handler2.NoopAuthHandler{}
+ chain, _ := handler.CreateChain(common.Provider, "testchain1", noopH.Name())
+ r.Header.Set("Content-Type", "application/json")
+ kvr := &v1.KVResource{}
+ c, _ := restfultest.New(kvr, chain)
+ resp := httptest.NewRecorder()
+ c.ServeHTTP(resp, r)
- data := &model.KVDoc{}
- err = json.Unmarshal(body, data)
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
-
- It("should return created or updated kv", func() {
- Expect(data.Value).Should(Equal(kv.Value))
- Expect(data.Labels).Should(Equal(kv.Labels))
- })
- })
+ body, err := ioutil.ReadAll(resp.Body)
+ assert.NoError(t, err)
+ data := &model.KVDoc{}
+ err = json.Unmarshal(body, data)
+ assert.NoError(t, err)
+ assert.NotEmpty(t, data.ID)
+ assert.Equal(t, kv.Value, data.Value)
+ assert.Equal(t, kv.Labels, data.Labels)
})
- Describe("list kv", func() {
- Context("with no label", func() {
- r, _ := http.NewRequest("GET", "/v1/test/kie/kv?label=service:tester", nil)
- noopH := &noop.NoopAuthHandler{}
- chain, _ := handler.CreateChain(common.Provider, "testchain1", noopH.Name())
- r.Header.Set("Content-Type", "application/json")
- kvr := &v1.KVResource{}
- c, err := restfultest.New(kvr, chain)
- It("should not return error", func() {
- Expect(err).Should(BeNil())
- })
- resp := httptest.NewRecorder()
- c.ServeHTTP(resp, r)
-
- body, err := ioutil.ReadAll(resp.Body)
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
- result := &model.KVResponse{}
- err = json.Unmarshal(body, result)
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
+ t.Run("put kv,label is service and version", func(t *testing.T) {
+ kv := &model.KVDoc{
+ Value: "1s",
+ Labels: map[string]string{"service": "utService",
+ "version": "1.0.0"},
+ }
+ j, _ := json.Marshal(kv)
+ r, _ := http.NewRequest("PUT", "/v1/test/kie/kv/timeout", bytes.NewBuffer(j))
+ noopH := &handler2.NoopAuthHandler{}
+ chain, _ := handler.CreateChain(common.Provider, "testchain1", noopH.Name())
+ r.Header.Set("Content-Type", "application/json")
+ kvr := &v1.KVResource{}
+ c, _ := restfultest.New(kvr, chain)
+ resp := httptest.NewRecorder()
+ c.ServeHTTP(resp, r)
- It("should longer than 1", func() {
- Expect(len(result.Data)).NotTo(Equal(0))
- })
- })
+ body, err := ioutil.ReadAll(resp.Body)
+ assert.NoError(t, err)
+ data := &model.KVDoc{}
+ err = json.Unmarshal(body, data)
+ assert.NoError(t, err)
+ assert.NotEmpty(t, data.ID)
+ })
+ t.Run("list kv by service label, should return 2 kvs", func(t *testing.T) {
+ r, _ := http.NewRequest("GET", "/v1/test/kie/kv?label=service:utService", nil)
+ noopH := &handler2.NoopAuthHandler{}
+ chain, _ := handler.CreateChain(common.Provider, "testchain1", noopH.Name())
+ r.Header.Set("Content-Type", "application/json")
+ kvr := &v1.KVResource{}
+ c, err := restfultest.New(kvr, chain)
+ assert.NoError(t, err)
+ resp := httptest.NewRecorder()
+ c.ServeHTTP(resp, r)
+ body, err := ioutil.ReadAll(resp.Body)
+ assert.NoError(t, err)
+ result := &model.KVResponse{}
+ err = json.Unmarshal(body, result)
+ assert.NoError(t, err)
+ assert.Equal(t, 2, len(result.Data))
+ })
+ t.Run("list kv by service label, exact match,should return 1 kv", func(t *testing.T) {
+ r, _ := http.NewRequest("GET", "/v1/test/kie/kv?label=service:utService&match=exact", nil)
+ noopH := &handler2.NoopAuthHandler{}
+ chain, _ := handler.CreateChain(common.Provider, "testchain1", noopH.Name())
+ r.Header.Set("Content-Type", "application/json")
+ kvr := &v1.KVResource{}
+ c, err := restfultest.New(kvr, chain)
+ assert.NoError(t, err)
+ resp := httptest.NewRecorder()
+ c.ServeHTTP(resp, r)
+ body, err := ioutil.ReadAll(resp.Body)
+ assert.NoError(t, err)
+ result := &model.KVResponse{}
+ err = json.Unmarshal(body, result)
+ assert.NoError(t, err)
+ assert.Equal(t, 1, len(result.Data))
})
-})
+}
diff --git a/server/resource/v1/v1_suite_test.go b/server/resource/v1/v1_suite_test.go
deleted file mode 100644
index 31569b8..0000000
--- a/server/resource/v1/v1_suite_test.go
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package v1_test
-
-import (
- "testing"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-
- _ "github.com/apache/servicecomb-kie/server/service/mongo"
-)
-
-func TestV1(t *testing.T) {
-
- RegisterFailHandler(Fail)
- RunSpecs(t, "V1 Suite")
-
-}
diff --git a/server/service/mongo/kv/kv_dao.go b/server/service/mongo/kv/kv_dao.go
index 207ac8a..b61b88b 100644
--- a/server/service/mongo/kv/kv_dao.go
+++ b/server/service/mongo/kv/kv_dao.go
@@ -121,10 +121,7 @@ func findKV(ctx context.Context, domain string, project string, opts service.Fin
for k, v := range opts.Labels {
filter["labels."+k] = v
}
- } else {
- filter["labels"] = ""
}
-
cur, err := collection.Find(ctx, filter)
if err != nil {
if err.Error() == context.DeadlineExceeded.Error() {
diff --git a/server/service/mongo/kv/kv_service.go b/server/service/mongo/kv/kv_service.go
index 8cc6b8c..1be9160 100644
--- a/server/service/mongo/kv/kv_service.go
+++ b/server/service/mongo/kv/kv_service.go
@@ -205,6 +205,11 @@ func (s *Service) List(ctx context.Context, domain, project string, limit, offse
openlogging.Error("decode to KVs error: " + err.Error())
return nil, err
}
+ if opts.ExactLabels {
+ if !reflect.DeepEqual(opts.Labels, curKV.Labels) {
+ continue
+ }
+ }
clearPart(curKV)
result.Data = append(result.Data, curKV)
}