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 2020/01/05 03:41:36 UTC
[servicecomb-kie] branch master updated: SCB-1700 support kv
revision management (#61)
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 ada262a SCB-1700 support kv revision management (#61)
ada262a is described below
commit ada262a5377fac2da2cb50acc5b32e6f433c2d9b
Author: Shawn <xi...@gmail.com>
AuthorDate: Sun Jan 5 11:41:29 2020 +0800
SCB-1700 support kv revision management (#61)
* SCB-1700 support kv revision management
* SCB-1700 fix wrong query param parsing
---
client/client_test.go | 2 +-
pkg/common/common.go | 1 +
pkg/model/mongodb_doc.go | 27 +--
server/resource/v1/common.go | 5 +-
server/resource/v1/common_test.go | 65 +++---
server/resource/v1/doc_struct.go | 8 +-
server/resource/v1/history_resource.go | 14 +-
server/resource/v1/history_resource_test.go | 111 +++++----
server/resource/v1/kv_resource.go | 25 +--
server/resource/v1/kv_resource_test.go | 39 +++-
server/service/mongo/history/dao.go | 82 ++-----
server/service/mongo/history/service.go | 15 +-
server/service/mongo/history/tool.go | 31 ---
server/service/mongo/kv/kv_dao.go | 70 ++----
server/service/mongo/kv/kv_service.go | 89 ++------
server/service/mongo/kv/kv_suite_test.go | 14 +-
server/service/mongo/kv/kv_test.go | 335 +++++++++-------------------
server/service/mongo/label/label_dao.go | 41 +---
server/service/mongo/session/session.go | 9 +-
server/service/service.go | 6 +-
20 files changed, 335 insertions(+), 654 deletions(-)
diff --git a/client/client_test.go b/client/client_test.go
index 7c58b8c..bdf5e22 100644
--- a/client/client_test.go
+++ b/client/client_test.go
@@ -132,7 +132,7 @@ var _ = Describe("Client", func() {
Endpoint: "http://127.0.0.1:30110",
})
It("should be 204", func() {
- err := client3.Delete(context.TODO(), kv.ID.String(), "", WithProject("test"))
+ err := client3.Delete(context.TODO(), kv.ID, "", WithProject("test"))
Ω(err).ShouldNot(HaveOccurred())
})
})
diff --git a/pkg/common/common.go b/pkg/common/common.go
index 22ab5a3..fad017d 100644
--- a/pkg/common/common.go
+++ b/pkg/common/common.go
@@ -23,6 +23,7 @@ const (
QueryByLabelsCon = "&"
QueryParamWait = "wait"
QueryParamMatch = "match"
+ QueryParamKeyID = "kvID"
)
//http headers
diff --git a/pkg/model/mongodb_doc.go b/pkg/model/mongodb_doc.go
index 7307cc2..5d6d9b6 100644
--- a/pkg/model/mongodb_doc.go
+++ b/pkg/model/mongodb_doc.go
@@ -17,22 +17,17 @@
package model
-import (
- "github.com/apache/servicecomb-kie/server/id"
-)
-
//LabelDoc is database struct to store labels
type LabelDoc struct {
- ID id.ID `json:"_id,omitempty" bson:"_id,omitempty" yaml:"_id,omitempty" swag:"string"`
- Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
- Revision int `json:"revision,omitempty" yaml:"revision,omitempty"`
- Domain string `json:"domain,omitempty" yaml:"domain,omitempty"` //tenant info
- Project string `json:"project,omitempty" yaml:"project,omitempty"`
+ ID string `json:"id,omitempty" bson:"id,omitempty" yaml:"id,omitempty" swag:"string"`
+ Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
+ Domain string `json:"domain,omitempty" yaml:"domain,omitempty"` //tenant info
+ Project string `json:"project,omitempty" yaml:"project,omitempty"`
}
//KVDoc is database struct to store kv
type KVDoc struct {
- ID id.ID `json:"_id,omitempty" bson:"_id,omitempty" yaml:"_id,omitempty" swag:"string"`
+ ID string `json:"id,omitempty" bson:"id,omitempty" yaml:"id,omitempty" swag:"string"`
LabelID string `json:"label_id,omitempty" bson:"label_id,omitempty" yaml:"label_id,omitempty"`
Key string `json:"key" yaml:"key"`
Value string `json:"value,omitempty" yaml:"value,omitempty"`
@@ -41,16 +36,6 @@ type KVDoc struct {
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` //redundant
Domain string `json:"domain,omitempty" yaml:"domain,omitempty"` //redundant
- Revision int `json:"revision,omitempty" bson:"-" yaml:"revision,omitempty"`
+ Revision int `json:"revision,omitempty" bson:"revision," yaml:"revision,omitempty"`
Project string `json:"project,omitempty" yaml:"project,omitempty"`
}
-
-//LabelRevisionDoc is database struct to store label history stats
-type LabelRevisionDoc struct {
- ID id.ID `json:"_id,omitempty" bson:"_id,omitempty" yaml:"_id,omitempty" swag:"string"`
- LabelID string `json:"label_id,omitempty" bson:"label_id,omitempty" yaml:"label_id,omitempty"`
- Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
- Domain string `json:"-" yaml:"-"`
- KVs []*KVDoc `json:"data,omitempty" bson:"data,omitempty" yaml:"data,omitempty"`
- Revision int `json:"revision" yaml:"revision"`
-}
diff --git a/server/resource/v1/common.go b/server/resource/v1/common.go
index 2db72c9..538a2bd 100644
--- a/server/resource/v1/common.go
+++ b/server/resource/v1/common.go
@@ -137,8 +137,9 @@ func writeResponse(ctx *restful.Context, v interface{}) error {
}
return ctx.WriteJSON(v, goRestful.MIME_JSON) // json is default
}
-func getLabels(labelStr string) (map[string]string, error) {
- labelsSlice := strings.Split(labelStr, ",")
+
+//GetLabels parse labels
+func GetLabels(labelsSlice []string) (map[string]string, error) {
labels := make(map[string]string, len(labelsSlice))
for _, v := range labelsSlice {
v := strings.Split(v, ":")
diff --git a/server/resource/v1/common_test.go b/server/resource/v1/common_test.go
index 792383c..d1ba7a7 100644
--- a/server/resource/v1/common_test.go
+++ b/server/resource/v1/common_test.go
@@ -18,47 +18,36 @@
package v1_test
import (
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-
- . "github.com/apache/servicecomb-kie/server/resource/v1"
+ v1 "github.com/apache/servicecomb-kie/server/resource/v1"
"github.com/emicklei/go-restful"
+ "github.com/stretchr/testify/assert"
"net/http"
+ "testing"
)
-var _ = Describe("Common", func() {
- Describe("set query combination", func() {
- Context("valid param", func() {
- r, err := http.NewRequest("GET",
- "/kv?q=app:mall+service:payment&q=app:mall+service:payment+version:1.0.0",
- nil)
- It("should not return err ", func() {
- Expect(err).Should(BeNil())
- })
- c, err := ReadLabelCombinations(restful.NewRequest(r))
- It("should not return err ", func() {
- Expect(err).Should(BeNil())
- })
- It("should has 2 combinations", func() {
- Expect(len(c)).Should(Equal(2))
- })
+func TestGetLabels(t *testing.T) {
+ r, err := http.NewRequest("GET",
+ "/kv?q=app:mall+service:payment&q=app:mall+service:payment+version:1.0.0",
+ nil)
+ assert.NoError(t, err)
+ c, err := v1.ReadLabelCombinations(restful.NewRequest(r))
+ assert.NoError(t, err)
+ assert.Equal(t, 2, len(c))
- })
- Context("find default", func() {
- r, err := http.NewRequest("GET",
- "/kv",
- nil)
- It("should not return err ", func() {
- Expect(err).Should(BeNil())
- })
- c, err := ReadLabelCombinations(restful.NewRequest(r))
- It("should not return err ", func() {
- Expect(err).Should(BeNil())
- })
- It("should has 1 combinations", func() {
- Expect(len(c)).Should(Equal(1))
- })
+ r, err = http.NewRequest("GET",
+ "/kv",
+ nil)
+ assert.NoError(t, err)
+ c, err = v1.ReadLabelCombinations(restful.NewRequest(r))
+ assert.NoError(t, err)
+ assert.Equal(t, 1, len(c))
- })
- })
-})
+ r, err = http.NewRequest("GET",
+ "/kv?label=app:mall&label=service:payment",
+ nil)
+ assert.NoError(t, err)
+ req := restful.NewRequest(r)
+ m, err := v1.GetLabels(req.QueryParameters("label"))
+ assert.NoError(t, err)
+ assert.Equal(t, 2, len(m))
+}
diff --git a/server/resource/v1/doc_struct.go b/server/resource/v1/doc_struct.go
index 6a00529..00e2135 100644
--- a/server/resource/v1/doc_struct.go
+++ b/server/resource/v1/doc_struct.go
@@ -62,9 +62,9 @@ var (
"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{
+ DocQueryKeyIDParameters = &restful.Parameters{
DataType: "string",
- Name: "kvID",
+ Name: common.QueryParamKeyID,
ParamType: goRestful.QueryParameterKind,
Required: true,
}
@@ -101,9 +101,9 @@ var (
ParamType: goRestful.PathParameterKind,
Required: true,
}
- DocPathLabelID = &restful.Parameters{
+ DocPathKeyID = &restful.Parameters{
DataType: "string",
- Name: "label_id",
+ Name: "key_id",
ParamType: goRestful.PathParameterKind,
Required: true,
}
diff --git a/server/resource/v1/history_resource.go b/server/resource/v1/history_resource.go
index 5f408a2..44c21fc 100644
--- a/server/resource/v1/history_resource.go
+++ b/server/resource/v1/history_resource.go
@@ -36,10 +36,10 @@ type HistoryResource struct {
//GetRevisions search key only by label
func (r *HistoryResource) GetRevisions(context *restful.Context) {
var err error
- labelID := context.ReadPathParameter("label_id")
+ labelID := context.ReadPathParameter("key_id")
if labelID == "" {
- openlogging.Debug("label id is null")
- WriteErrResponse(context, http.StatusForbidden, "label_id must not be empty", common.ContentTypeText)
+ openlogging.Error("key id is nil")
+ WriteErrResponse(context, http.StatusForbidden, "key_id must not be empty", common.ContentTypeText)
return
}
key := context.ReadQueryParameter("key")
@@ -67,17 +67,17 @@ func (r *HistoryResource) URLPatterns() []restful.Route {
return []restful.Route{
{
Method: http.MethodGet,
- Path: "/v1/{project}/kie/revision/{label_id}",
+ Path: "/v1/{project}/kie/revision/{key_id}",
ResourceFunc: r.GetRevisions,
- FuncDesc: "get all revisions by label id",
+ FuncDesc: "get all revisions by key id",
Parameters: []*restful.Parameters{
- DocPathProject, DocPathLabelID, DocQueryKeyParameters,
+ DocPathProject, DocPathKeyID,
},
Returns: []*restful.Returns{
{
Code: http.StatusOK,
Message: "true",
- Model: []model.LabelHistoryResponse{},
+ Model: []model.KVDoc{},
},
},
Consumes: []string{goRestful.MIME_JSON, common.ContentTypeYaml},
diff --git a/server/resource/v1/history_resource_test.go b/server/resource/v1/history_resource_test.go
index c088f09..07004c6 100644
--- a/server/resource/v1/history_resource_test.go
+++ b/server/resource/v1/history_resource_test.go
@@ -19,74 +19,67 @@ package v1_test
import (
"context"
"encoding/json"
+ "fmt"
+ "github.com/apache/servicecomb-kie/pkg/model"
+ v1 "github.com/apache/servicecomb-kie/server/resource/v1"
"github.com/apache/servicecomb-kie/server/service"
- "io/ioutil"
-
"github.com/go-chassis/go-chassis/core/common"
"github.com/go-chassis/go-chassis/core/handler"
-
- "fmt"
+ "github.com/go-chassis/go-chassis/server/restful/restfultest"
+ "github.com/stretchr/testify/assert"
+ "io/ioutil"
"net/http"
"net/http/httptest"
+ "testing"
- "github.com/apache/servicecomb-kie/pkg/model"
- "github.com/apache/servicecomb-kie/server/config"
- v1 "github.com/apache/servicecomb-kie/server/resource/v1"
_ "github.com/apache/servicecomb-kie/server/service/mongo"
- "github.com/go-chassis/go-chassis/server/restful/restfultest"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
)
-var _ = Describe("v1 history resource", func() {
-
- config.Configurations = &config.Config{
- DB: config.DB{},
+func TestHistoryResource_GetRevisions(t *testing.T) {
+ kv := &model.KVDoc{
+ Key: "test",
+ Value: "revisions",
+ Labels: map[string]string{
+ "test": "revisions",
+ },
+ Domain: "default",
+ Project: "test",
}
+ kv, _ = service.KVService.CreateOrUpdate(context.Background(), kv)
+ path := fmt.Sprintf("/v1/test/kie/revision/%s", kv.ID)
+ r, _ := http.NewRequest("GET", path, nil)
+ revision := &v1.HistoryResource{}
+ chain, _ := handler.GetChain(common.Provider, "")
+ c, err := restfultest.New(revision, chain)
+ assert.NoError(t, err)
+ resp := httptest.NewRecorder()
+ c.ServeHTTP(resp, r)
+ body, err := ioutil.ReadAll(resp.Body)
+ assert.NoError(t, err)
+ data := make([]*model.KVDoc, 0)
+ err = json.Unmarshal(body, &data)
+ assert.NoError(t, err)
+ before := len(data)
+ assert.GreaterOrEqual(t, before, 1)
- Describe("get history revisions", func() {
- config.Configurations.DB.URI = "mongodb://kie:123@127.0.0.1:27017"
- err := service.DBInit()
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
- Context("valid param", func() {
- kv := &model.KVDoc{
- Key: "test",
- Value: "revisions",
- Labels: map[string]string{
- "test": "revisions",
- },
- Domain: "default",
- Project: "test",
- }
- kv, _ = service.KVService.CreateOrUpdate(context.Background(), kv)
- path := fmt.Sprintf("/v1/%s/kie/revision/%s", "test", kv.LabelID)
- r, _ := http.NewRequest("GET", path, nil)
- revision := &v1.HistoryResource{}
- chain, _ := handler.GetChain(common.Provider, "")
- c, err := restfultest.New(revision, chain)
- It("should not return err or nil", 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())
- })
- data := make([]*model.LabelRevisionDoc, 0)
- err = json.Unmarshal(body, &data)
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
-
- It("should return all revisions with the same label ID", func() {
- Expect(len(data) > 0).Should(Equal(true))
- Expect((data[0]).LabelID).Should(Equal(kv.LabelID))
- })
- })
+ t.Run("put again, should has 2 revision", func(t *testing.T) {
+ kv.Domain = "default"
+ kv.Project = "test"
+ kv, err = service.KVService.CreateOrUpdate(context.Background(), kv)
+ assert.NoError(t, err)
+ path := fmt.Sprintf("/v1/test/kie/revision/%s", kv.ID)
+ r, _ := http.NewRequest("GET", path, nil)
+ revision := &v1.HistoryResource{}
+ chain, _ := handler.GetChain(common.Provider, "")
+ c, err := restfultest.New(revision, chain)
+ assert.NoError(t, err)
+ resp := httptest.NewRecorder()
+ c.ServeHTTP(resp, r)
+ body, err := ioutil.ReadAll(resp.Body)
+ assert.NoError(t, err)
+ data := make([]*model.KVDoc, 0)
+ err = json.Unmarshal(body, &data)
+ assert.Equal(t, before+1, len(data))
})
-})
+
+}
diff --git a/server/resource/v1/kv_resource.go b/server/resource/v1/kv_resource.go
index c56b356..f38c9eb 100644
--- a/server/resource/v1/kv_resource.go
+++ b/server/resource/v1/kv_resource.go
@@ -85,10 +85,10 @@ func (r *KVResource) GetByKey(rctx *restful.Context) {
return
}
project := rctx.ReadPathParameter("project")
- labelStr := rctx.ReadQueryParameter("label")
+ labelSlice := rctx.Req.QueryParameters("label")
var labels map[string]string
- if labelStr != "" {
- labels, err = getLabels(labelStr)
+ if len(labelSlice) != 0 {
+ labels, err = GetLabels(labelSlice)
if err != nil {
WriteErrResponse(rctx, http.StatusBadRequest, MsgIllegalLabels, common.ContentTypeText)
return
@@ -131,10 +131,10 @@ func (r *KVResource) List(rctx *restful.Context) {
WriteErrResponse(rctx, http.StatusInternalServerError, MsgDomainMustNotBeEmpty, common.ContentTypeText)
return
}
- labelStr := rctx.ReadQueryParameter("label")
+ labelSlice := rctx.Req.QueryParameters("label")
var labels map[string]string
- if labelStr != "" {
- labels, err = getLabels(labelStr)
+ if len(labelSlice) != 0 {
+ labels, err = GetLabels(labelSlice)
if err != nil {
WriteErrResponse(rctx, http.StatusBadRequest, MsgIllegalLabels, common.ContentTypeText)
return
@@ -234,18 +234,16 @@ func (r *KVResource) Delete(context *restful.Context) {
if domain == nil {
WriteErrResponse(context, http.StatusInternalServerError, MsgDomainMustNotBeEmpty, common.ContentTypeText)
}
- kvID := context.ReadQueryParameter("kvID")
+ kvID := context.ReadQueryParameter(common.QueryParamKeyID)
if kvID == "" {
WriteErrResponse(context, http.StatusBadRequest, ErrKvIDMustNotEmpty, common.ContentTypeText)
return
}
- labelID := context.ReadQueryParameter("labelID")
- err := service.KVService.Delete(kvID, labelID, domain.(string), project)
+ err := service.KVService.Delete(context.Ctx, kvID, domain.(string), project)
if err != nil {
openlogging.Error("delete failed ,", openlogging.WithTags(openlogging.Tags{
- "kvID": kvID,
- "labelID": labelID,
- "error": err.Error(),
+ "kvID": kvID,
+ "error": err.Error(),
}))
WriteErrResponse(context, http.StatusInternalServerError, err.Error(), common.ContentTypeText)
return
@@ -334,8 +332,7 @@ func (r *KVResource) URLPatterns() []restful.Route {
FuncDesc: "delete key by kvID and labelID. Want better performance, give labelID",
Parameters: []*restful.Parameters{
DocPathProject,
- DocQueryKVIDParameters,
- DocQueryLabelIDParameters,
+ DocQueryKeyIDParameters,
},
Returns: []*restful.Returns{
{
diff --git a/server/resource/v1/kv_resource_test.go b/server/resource/v1/kv_resource_test.go
index 4787753..382e2de 100644
--- a/server/resource/v1/kv_resource_test.go
+++ b/server/resource/v1/kv_resource_test.go
@@ -40,7 +40,7 @@ import (
_ "github.com/apache/servicecomb-kie/server/service/mongo"
)
-func TestKVResource_List(t *testing.T) {
+func init() {
log.Init(log.Config{
Writers: []string{"stdout"},
LoggerLevel: "DEBUG",
@@ -59,6 +59,9 @@ func TestKVResource_List(t *testing.T) {
if err != nil {
panic(err)
}
+}
+func TestKVResource_List(t *testing.T) {
+
pubsub.Init()
pubsub.Start()
t.Run("put kv, label is service", func(t *testing.T) {
@@ -142,4 +145,38 @@ func TestKVResource_List(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, 1, len(result.Data))
})
+ t.Run("get one key by label, exact match,should return 1 kv", func(t *testing.T) {
+ r, _ := http.NewRequest("GET", "/v1/test/kie/kv/timeout?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))
+ })
+ t.Run("get one key by service label should return 2 kv", func(t *testing.T) {
+ r, _ := http.NewRequest("GET", "/v1/test/kie/kv/timeout?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))
+ })
}
diff --git a/server/service/mongo/history/dao.go b/server/service/mongo/history/dao.go
index 8533ec0..d9021c4 100644
--- a/server/service/mongo/history/dao.go
+++ b/server/service/mongo/history/dao.go
@@ -19,101 +19,49 @@ package history
import (
"context"
- "fmt"
"github.com/apache/servicecomb-kie/pkg/model"
"github.com/apache/servicecomb-kie/server/service"
- "github.com/apache/servicecomb-kie/server/service/mongo/label"
"github.com/apache/servicecomb-kie/server/service/mongo/session"
"github.com/go-mesh/openlogging"
"go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
)
-//AddHistory increment labels revision and save current label stats to history, then update current revision to db
-func AddHistory(ctx context.Context,
- labelRevision *model.LabelRevisionDoc, labelID string, kvs []*model.KVDoc) (int, error) {
- labelRevision.Revision = labelRevision.Revision + 1
-
- //save current kv states
- labelRevision.KVs = kvs
- //clear prev id
- labelRevision.ID = ""
- collection := session.GetDB().Collection(session.CollectionLabelRevision)
- _, err := collection.InsertOne(ctx, labelRevision)
- if err != nil {
- openlogging.Error(err.Error())
- return 0, err
- }
- hex, err := primitive.ObjectIDFromHex(labelID)
- if err != nil {
- openlogging.Error(fmt.Sprintf("convert %s,err:%s", labelID, err))
- return 0, err
- }
- labelCollection := session.GetDB().Collection(session.CollectionLabel)
- _, err = labelCollection.UpdateOne(ctx, bson.M{"_id": hex}, bson.D{
- {"$set", bson.D{
- {"revision", labelRevision.Revision},
- }},
- })
- if err != nil {
- return 0, err
- }
- openlogging.Debug(fmt.Sprintf("update revision to %d", labelRevision.Revision))
- return labelRevision.Revision, nil
-}
-
-func getHistoryByLabelID(ctx context.Context, filter bson.M) ([]*model.LabelRevisionDoc, error) {
- collection := session.GetDB().Collection(session.CollectionLabelRevision)
+func getHistoryByKeyID(ctx context.Context, filter bson.M) ([]*model.KVDoc, error) {
+ collection := session.GetDB().Collection(session.CollectionKVRevision)
cur, err := collection.Find(ctx, filter, options.Find().SetSort(map[string]interface{}{
- "revisions": -1,
+ "revision": -1,
}))
if err != nil {
return nil, err
}
- rvs := make([]*model.LabelRevisionDoc, 0)
+ kvs := make([]*model.KVDoc, 0)
var exist bool
for cur.Next(ctx) {
- var elem model.LabelRevisionDoc
+ var elem model.KVDoc
err := cur.Decode(&elem)
if err != nil {
- openlogging.Error("decode to LabelRevisionDoc error: " + err.Error())
+ openlogging.Error("decode error: " + err.Error())
return nil, err
}
exist = true
- rvs = append(rvs, &elem)
+ kvs = append(kvs, &elem)
}
if !exist {
return nil, service.ErrRevisionNotExist
}
- return rvs, nil
+ return kvs, nil
}
-//GetAndAddHistory get latest labels revision and call AddHistory
-func GetAndAddHistory(ctx context.Context,
- labelID string, labels map[string]string, kvs []*model.KVDoc, domain string, project string) (int, error) {
+//AddHistory add kv history
+func AddHistory(ctx context.Context, kv *model.KVDoc) error {
ctx, cancel := context.WithTimeout(ctx, session.Timeout)
defer cancel()
- r, err := label.GetLatestLabel(ctx, labelID)
+ collection := session.GetDB().Collection(session.CollectionKVRevision)
+ _, err := collection.InsertOne(ctx, kv)
if err != nil {
- if err == service.ErrRevisionNotExist {
- openlogging.Warn(fmt.Sprintf("label revision not exists, create first label revision"))
- r = &model.LabelRevisionDoc{
- LabelID: labelID,
- Labels: labels,
- Domain: domain,
- Revision: 0,
- }
- } else {
- openlogging.Error(fmt.Sprintf("get latest [%s] in [%s],err: %s",
- labelID, domain, err.Error()))
- return 0, err
- }
-
- }
- r.Revision, err = AddHistory(ctx, r, labelID, kvs)
- if err != nil {
- return 0, err
+ openlogging.Error(err.Error())
+ return err
}
- return r.Revision, nil
+ return nil
}
diff --git a/server/service/mongo/history/service.go b/server/service/mongo/history/service.go
index 85f7bdb..19f5969 100644
--- a/server/service/mongo/history/service.go
+++ b/server/service/mongo/history/service.go
@@ -30,20 +30,15 @@ type Service struct {
}
//GetHistory get all history by label id
-func (s *Service) GetHistory(ctx context.Context, labelID string, options ...service.FindOption) ([]*model.LabelRevisionDoc, error) {
+func (s *Service) GetHistory(ctx context.Context, kvID string, options ...service.FindOption) ([]*model.KVDoc, error) {
var filter primitive.M
opts := service.FindOptions{}
for _, o := range options {
o(&opts)
}
- if opts.Key != "" {
- filter = bson.M{
- "label_id": labelID,
- "data.key": opts.Key,
- }
-
- } else {
- filter = bson.M{"label_id": labelID}
+ filter = bson.M{
+ "id": kvID,
}
- return getHistoryByLabelID(ctx, filter)
+
+ return getHistoryByKeyID(ctx, filter)
}
diff --git a/server/service/mongo/history/tool.go b/server/service/mongo/history/tool.go
deleted file mode 100644
index f72013d..0000000
--- a/server/service/mongo/history/tool.go
+++ /dev/null
@@ -1,31 +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 history
-
-import (
- "github.com/apache/servicecomb-kie/pkg/model"
-)
-
-//clearRevisionKV clean attr which don't need to return to client side
-func clearRevisionKV(revision *model.LabelRevisionDoc) {
- for _, v := range revision.KVs {
- v.Domain = ""
- v.Project = ""
- v.LabelID = ""
- }
-}
diff --git a/server/service/mongo/kv/kv_dao.go b/server/service/mongo/kv/kv_dao.go
index b61b88b..f8eadd1 100644
--- a/server/service/mongo/kv/kv_dao.go
+++ b/server/service/mongo/kv/kv_dao.go
@@ -20,16 +20,13 @@ package kv
import (
"context"
"fmt"
- "github.com/apache/servicecomb-kie/server/id"
- "github.com/apache/servicecomb-kie/server/service"
- "github.com/apache/servicecomb-kie/server/service/mongo/label"
- "github.com/apache/servicecomb-kie/server/service/mongo/session"
-
"github.com/apache/servicecomb-kie/pkg/model"
+ "github.com/apache/servicecomb-kie/server/service"
"github.com/apache/servicecomb-kie/server/service/mongo/history"
+ "github.com/apache/servicecomb-kie/server/service/mongo/session"
"github.com/go-mesh/openlogging"
+ uuid "github.com/satori/go.uuid"
"go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
@@ -37,76 +34,51 @@ import (
//and increase revision of label
//and insert key
func createKey(ctx context.Context, kv *model.KVDoc) (*model.KVDoc, error) {
- r, err := label.GetLatestLabel(ctx, kv.LabelID)
- if err != nil {
- if err != service.ErrRevisionNotExist {
- openlogging.Error(fmt.Sprintf("get latest [%s][%s] in [%s],err: %s",
- kv.Key, kv.Labels, kv.Domain, err.Error()))
- return nil, err
- }
- //the first time labels is created, at this time, labels has no revision yet
- //after first key created, labels got revision 1
- r = &model.LabelRevisionDoc{Revision: 0}
- }
- if r != nil {
- r.Revision = r.Revision + 1
- }
collection := session.GetDB().Collection(session.CollectionKV)
- res, err := collection.InsertOne(ctx, kv)
+ kv.ID = uuid.NewV4().String()
+ kv.Revision = 1
+ _, err := collection.InsertOne(ctx, kv)
if err != nil {
return nil, err
}
- objectID, _ := res.InsertedID.(primitive.ObjectID)
- kv.ID = id.ID(objectID.Hex())
- kvs, err := findKeys(ctx, bson.M{"label_id": kv.LabelID}, true)
- //Key may be empty When delete
- if err != nil && err != service.ErrKeyNotExists {
- return nil, err
- }
- revision, err := history.GetAndAddHistory(ctx, kv.LabelID, kv.Labels, kvs, kv.Domain, kv.Project)
+ err = history.AddHistory(ctx, kv)
if err != nil {
openlogging.Warn(
fmt.Sprintf("can not updateKeyValue version for [%s] [%s] in [%s]",
kv.Key, kv.Labels, kv.Domain))
}
openlogging.Debug(fmt.Sprintf("create %s with labels %s value [%s]", kv.Key, kv.Labels, kv.Value))
- kv.Revision = revision
+
return kv, nil
}
-//updateKeyValue get latest revision from history
-//and increase revision of label
-//and updateKeyValue and them add new revision
-func updateKeyValue(ctx context.Context, kv *model.KVDoc) (int, error) {
+//updateKeyValue update key value and add new revision
+func updateKeyValue(ctx context.Context, kv *model.KVDoc) error {
collection := session.GetDB().Collection(session.CollectionKV)
ur, err := collection.UpdateOne(ctx, bson.M{"key": kv.Key, "label_id": kv.LabelID}, bson.D{
{"$set", bson.D{
{"value", kv.Value},
{"checker", kv.Checker},
+ {"revision", kv.Revision},
}},
})
if err != nil {
- return 0, err
+ return err
}
openlogging.Debug(
fmt.Sprintf("updateKeyValue %s with labels %s value [%s] %d ",
kv.Key, kv.Labels, kv.Value, ur.ModifiedCount))
- kvs, err := findKeys(ctx, bson.M{"label_id": kv.LabelID}, true)
- //Key may be empty When delete
- if err != nil && err != service.ErrKeyNotExists {
- return 0, err
- }
- revision, err := history.GetAndAddHistory(ctx, kv.LabelID, kv.Labels, kvs, kv.Domain, kv.Project)
+ err = history.AddHistory(ctx, kv)
if err != nil {
- openlogging.Warn(
- fmt.Sprintf("can not label revision for [%s] [%s] in [%s],err: %s",
+ openlogging.Error(
+ fmt.Sprintf("can not add revision for [%s] [%s] in [%s],err: %s",
kv.Key, kv.Labels, kv.Domain, err))
}
openlogging.Debug(
fmt.Sprintf("add history %s with labels %s value [%s] %d ",
kv.Key, kv.Labels, kv.Value, ur.ModifiedCount))
- return revision, nil
+ return nil
}
@@ -153,18 +125,18 @@ func findOneKey(ctx context.Context, filter bson.M) ([]*model.KVDoc, error) {
}
//deleteKV by kvID
-func deleteKV(ctx context.Context, hexID primitive.ObjectID, project string) error {
+func deleteKV(ctx context.Context, kvID, project, domain string) error {
collection := session.GetDB().Collection(session.CollectionKV)
- dr, err := collection.DeleteOne(ctx, bson.M{"_id": hexID, "project": project})
+ dr, err := collection.DeleteOne(ctx, bson.M{"id": kvID, "project": project, "domain": domain})
//check error and delete number
if err != nil {
- openlogging.Error(fmt.Sprintf("delete [%s] failed : [%s]", hexID, err))
+ openlogging.Error(fmt.Sprintf("delete [%s] failed : [%s]", kvID, err))
return err
}
if dr.DeletedCount != 1 {
- openlogging.Warn(fmt.Sprintf("Failed,May have been deleted,kvID=%s", hexID))
+ openlogging.Warn(fmt.Sprintf("failed, may have been deleted,kvID=%s", kvID))
} else {
- openlogging.Info(fmt.Sprintf("delete success,kvID=%s", hexID))
+ openlogging.Info(fmt.Sprintf("delete success,kvID=%s", kvID))
}
return err
}
diff --git a/server/service/mongo/kv/kv_service.go b/server/service/mongo/kv/kv_service.go
index 1be9160..76d1f3a 100644
--- a/server/service/mongo/kv/kv_service.go
+++ b/server/service/mongo/kv/kv_service.go
@@ -19,19 +19,16 @@ package kv
import (
"context"
+ "errors"
"fmt"
- "github.com/apache/servicecomb-kie/server/id"
"reflect"
"time"
"github.com/apache/servicecomb-kie/pkg/model"
"github.com/apache/servicecomb-kie/server/service"
- "github.com/apache/servicecomb-kie/server/service/mongo/history"
"github.com/apache/servicecomb-kie/server/service/mongo/label"
"github.com/apache/servicecomb-kie/server/service/mongo/session"
"github.com/go-mesh/openlogging"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
)
//Service operate data in mongodb
@@ -49,7 +46,6 @@ func (s *Service) CreateOrUpdate(ctx context.Context, kv *model.KVDoc) (*model.K
if kv.Domain == "" {
return nil, session.ErrMissingDomain
}
-
//check whether the project has certain labels or not
labelID, err := label.Exist(ctx, kv.Domain, kv.Project, kv.Labels)
if err != nil {
@@ -68,11 +64,11 @@ func (s *Service) CreateOrUpdate(ctx context.Context, kv *model.KVDoc) (*model.K
return nil, err
}
}
- kv.LabelID = string(labelID)
+ kv.LabelID = labelID
if kv.ValueType == "" {
kv.ValueType = session.DefaultValueType
}
- keyID, err := s.Exist(ctx, kv.Domain, kv.Key, kv.Project, service.WithLabelID(kv.LabelID))
+ oldKV, err := s.Exist(ctx, kv.Domain, kv.Key, kv.Project, service.WithLabelID(kv.LabelID))
if err != nil {
if err == service.ErrKeyNotExists {
kv, err := createKey(ctx, kv)
@@ -85,20 +81,20 @@ func (s *Service) CreateOrUpdate(ctx context.Context, kv *model.KVDoc) (*model.K
}
return nil, err
}
- kv.ID = keyID
- revision, err := updateKeyValue(ctx, kv)
+ kv.ID = oldKV.ID
+ kv.Revision = oldKV.Revision + 1
+ err = updateKeyValue(ctx, kv)
if err != nil {
return nil, err
}
- kv.Revision = revision
kv.Domain = ""
kv.Project = ""
return kv, nil
}
-//Exist supports you query by label map or labels id
-func (s *Service) Exist(ctx context.Context, domain, key string, project string, options ...service.FindOption) (id.ID, error) {
+//Exist supports you query a key value by label map or labels id
+func (s *Service) Exist(ctx context.Context, domain, key string, project string, options ...service.FindOption) (*model.KVDoc, error) {
ctx, _ = context.WithTimeout(context.Background(), session.Timeout)
opts := service.FindOptions{}
for _, o := range options {
@@ -107,82 +103,41 @@ func (s *Service) Exist(ctx context.Context, domain, key string, project string,
if opts.LabelID != "" {
kvs, err := findKVByLabelID(ctx, domain, opts.LabelID, key, project)
if err != nil {
- return "", err
+ return nil, err
}
- return kvs[0].ID, nil
+ return kvs[0], nil
}
- kvs, err := s.FindKV(ctx, domain, project, service.WithExactLabels(), service.WithLabels(opts.Labels), service.WithKey(key))
+ kvs, err := s.FindKV(ctx, domain, project,
+ service.WithExactLabels(), service.WithLabels(opts.Labels), service.WithKey(key))
if err != nil {
- return "", err
+ return nil, err
}
if len(kvs) != 1 {
- return "", session.ErrTooMany
+ return nil, session.ErrTooMany
}
- return kvs[0].Data[0].ID, nil
+ return kvs[0].Data[0], nil
}
//Delete delete kv,If the labelID is "", query the collection kv to get it
//domain=tenant
-//1.delete kv;2.add history
-func (s *Service) Delete(kvID string, labelID string, domain string, project string) error {
- ctx, _ := context.WithTimeout(context.Background(), session.Timeout)
+func (s *Service) Delete(ctx context.Context, kvID string, domain string, project string) error {
+ ctx, _ = context.WithTimeout(context.Background(), session.Timeout)
if domain == "" {
return session.ErrMissingDomain
}
if project == "" {
return session.ErrMissingProject
}
- hex, err := primitive.ObjectIDFromHex(kvID)
- if err != nil {
- return err
- }
- //if labelID == "",get labelID by kvID
- var kv *model.KVDoc
- if labelID == "" {
- kvArray, err := findOneKey(ctx, bson.M{"_id": hex, "project": project})
- if err != nil {
- return err
- }
- if len(kvArray) > 0 {
- kv = kvArray[0]
- labelID = kv.LabelID
- }
- }
- //get Label and check labelID
- r, err := label.GetLatestLabel(ctx, labelID)
- if err != nil {
- if err == service.ErrRevisionNotExist {
- openlogging.Warn(fmt.Sprintf("failed,kvID and labelID do not match"))
- return session.ErrKvIDAndLabelIDNotMatch
- }
- return err
+ if kvID == "" {
+ return errors.New("key id is empty")
}
//delete kv
- err = deleteKV(ctx, hex, project)
- if err != nil {
- return err
- }
- kvs, err := findKeys(ctx, bson.M{"label_id": labelID, "project": project}, true)
- //Key may be empty When delete
- if err != nil && err != service.ErrKeyNotExists {
- return err
- }
- //Labels will not be empty when deleted
- revision, err := history.AddHistory(ctx, r, labelID, kvs)
+ err := deleteKV(ctx, kvID, project, domain)
if err != nil {
- openlogging.Warn("add history failed ,", openlogging.WithTags(openlogging.Tags{
- "kvID": kvID,
- "labelID": labelID,
- "error": err.Error(),
- }))
- } else {
- openlogging.Info("add history success,", openlogging.WithTags(openlogging.Tags{
- "kvID": kvID,
- "labelID": labelID,
- "revision": revision,
- }))
+ openlogging.Error("can not delete key, err:" + err.Error())
+ return errors.New("can not delete key")
}
return nil
}
diff --git a/server/service/mongo/kv/kv_suite_test.go b/server/service/mongo/kv/kv_suite_test.go
index 3eb253f..e744c46 100644
--- a/server/service/mongo/kv/kv_suite_test.go
+++ b/server/service/mongo/kv/kv_suite_test.go
@@ -18,22 +18,12 @@
package kv_test
import (
- "testing"
-
"github.com/go-chassis/paas-lager"
"github.com/go-mesh/openlogging"
- . "github.com/onsi/ginkgo"
- "github.com/onsi/ginkgo/reporters"
- . "github.com/onsi/gomega"
)
-func TestModel(t *testing.T) {
- RegisterFailHandler(Fail)
- junitReporter := reporters.NewJUnitReporter("junit.xml")
- RunSpecsWithDefaultAndCustomReporters(t, "kv Suite", []Reporter{junitReporter})
-}
+func init() {
-var _ = BeforeSuite(func() {
log.Init(log.Config{
Writers: []string{"stdout"},
LoggerLevel: "DEBUG",
@@ -41,4 +31,4 @@ var _ = BeforeSuite(func() {
logger := log.NewLogger("ut")
openlogging.SetLogger(logger)
-})
+}
diff --git a/server/service/mongo/kv/kv_test.go b/server/service/mongo/kv/kv_test.go
index b816aa4..710ad58 100644
--- a/server/service/mongo/kv/kv_test.go
+++ b/server/service/mongo/kv/kv_test.go
@@ -24,251 +24,134 @@ import (
"github.com/apache/servicecomb-kie/server/service"
"github.com/apache/servicecomb-kie/server/service/mongo/kv"
"github.com/apache/servicecomb-kie/server/service/mongo/session"
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
+ "github.com/stretchr/testify/assert"
+ "testing"
)
-var _ = Describe("Kv mongodb service", func() {
+func TestService_CreateOrUpdate(t *testing.T) {
var err error
- Describe("connecting db", func() {
- config.Configurations = &config.Config{DB: config.DB{URI: "mongodb://kie:123@127.0.0.1:27017"}}
- err = session.Init()
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
- })
+ config.Configurations = &config.Config{DB: config.DB{URI: "mongodb://kie:123@127.0.0.1:27017"}}
+ err = session.Init()
+ assert.NoError(t, err)
kvsvc := &kv.Service{}
- Describe("put kv timeout", func() {
-
- Context("with labels app and service", func() {
- kv, err := kvsvc.CreateOrUpdate(context.TODO(), &model.KVDoc{
- Key: "timeout",
- Value: "2s",
- Labels: map[string]string{
- "app": "mall",
- "service": "cart",
- },
- Domain: "default",
- Project: "test",
- })
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
- It("should has ID", func() {
- Expect(kv.ID.String()).ShouldNot(BeEmpty())
- })
-
+ t.Run("put kv timeout,with labels app and service", func(t *testing.T) {
+ kv, err := kvsvc.CreateOrUpdate(context.TODO(), &model.KVDoc{
+ Key: "timeout",
+ Value: "2s",
+ Labels: map[string]string{
+ "app": "mall",
+ "service": "cart",
+ },
+ Domain: "default",
+ Project: "test",
})
- Context("with labels app, service and version", func() {
- kv, err := kvsvc.CreateOrUpdate(context.TODO(), &model.KVDoc{
- Key: "timeout",
- Value: "2s",
- Labels: map[string]string{
- "app": "mall",
- "service": "cart",
- "version": "1.0.0",
- },
- Domain: "default",
- Project: "test",
- })
- oid, err := kvsvc.Exist(context.TODO(), "default", "timeout", "test", service.WithLabels(map[string]string{
+ assert.NoError(t, err)
+ assert.NotEmpty(t, kv.ID)
+ })
+ t.Run("put kv timeout,with labels app, service and version", func(t *testing.T) {
+ kv, err := kvsvc.CreateOrUpdate(context.TODO(), &model.KVDoc{
+ Key: "timeout",
+ Value: "2s",
+ Labels: map[string]string{
"app": "mall",
"service": "cart",
"version": "1.0.0",
- }))
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
- It("should has ID", func() {
- Expect(kv.ID.String()).ShouldNot(BeEmpty())
- })
- It("should exist", func() {
- Expect(oid).ShouldNot(BeEmpty())
- })
+ },
+ Domain: "default",
+ Project: "test",
})
- Context("with labels app,and update value", func() {
- beforeKV, err := kvsvc.CreateOrUpdate(context.Background(), &model.KVDoc{
- Key: "timeout",
- Value: "1s",
- Labels: map[string]string{
- "app": "mall",
- },
- Domain: "default",
- Project: "test",
- })
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
- kvs1, err := kvsvc.FindKV(context.Background(), "default", "test", service.WithKey("timeout"), service.WithLabels(map[string]string{
- "app": "mall",
- }), service.WithExactLabels())
- It("should be 1s", func() {
- Expect(kvs1[0].Data[0].Value).Should(Equal(beforeKV.Value))
- })
- afterKV, err := kvsvc.CreateOrUpdate(context.Background(), &model.KVDoc{
- Key: "timeout",
- Value: "3s",
- Labels: map[string]string{
- "app": "mall",
- },
- Domain: "default",
- Project: "test",
- })
- It("should has same id", func() {
- Expect(afterKV.ID.String()).Should(Equal(beforeKV.ID.String()))
- })
- oid, err := kvsvc.Exist(context.Background(), "default", "timeout", "test", service.WithLabels(map[string]string{
+ oid, err := kvsvc.Exist(context.TODO(), "default", "timeout", "test", service.WithLabels(map[string]string{
+ "app": "mall",
+ "service": "cart",
+ "version": "1.0.0",
+ }))
+ assert.NoError(t, err)
+ assert.NotEmpty(t, kv.ID)
+ assert.NoError(t, err)
+ assert.NotEmpty(t, oid)
+ })
+ t.Run("put kv timeout,with labels app,and update value", func(t *testing.T) {
+ beforeKV, err := kvsvc.CreateOrUpdate(context.Background(), &model.KVDoc{
+ Key: "timeout",
+ Value: "1s",
+ Labels: map[string]string{
"app": "mall",
- }))
- It("should exists", func() {
- Expect(oid.String()).Should(Equal(beforeKV.ID.String()))
- })
- kvs, err := kvsvc.FindKV(context.Background(), "default", "test", service.WithKey("timeout"), service.WithLabels(map[string]string{
+ },
+ Domain: "default",
+ Project: "test",
+ })
+ assert.NoError(t, err)
+ kvs1, err := kvsvc.FindKV(context.Background(), "default", "test", service.WithKey("timeout"), service.WithLabels(map[string]string{
+ "app": "mall",
+ }), service.WithExactLabels())
+ assert.Equal(t, beforeKV.Value, kvs1[0].Data[0].Value)
+ afterKV, err := kvsvc.CreateOrUpdate(context.Background(), &model.KVDoc{
+ Key: "timeout",
+ Value: "3s",
+ Labels: map[string]string{
"app": "mall",
- }), service.WithExactLabels())
- It("should be 3s", func() {
- Expect(kvs[0].Data[0].Value).Should(Equal(afterKV.Value))
- })
+ },
+ Domain: "default",
+ Project: "test",
})
+ assert.Equal(t, beforeKV.ID, afterKV.ID)
+ savedKV, err := kvsvc.Exist(context.Background(), "default", "timeout", "test", service.WithLabels(map[string]string{
+ "app": "mall",
+ }))
+ assert.Equal(t, beforeKV.ID, savedKV.ID)
+ kvs, err := kvsvc.FindKV(context.Background(), "default", "test", service.WithKey("timeout"), service.WithLabels(map[string]string{
+ "app": "mall",
+ }), service.WithExactLabels())
+ assert.Equal(t, afterKV.Value, kvs[0].Data[0].Value)
})
- Describe("greedy find by kv and labels", func() {
- Context("with labels app,depth is 1 ", func() {
- kvs, err := kvsvc.FindKV(context.Background(), "default", "test",
- service.WithKey("timeout"), service.WithLabels(map[string]string{
- "app": "mall",
- }))
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
- It("should has 1 records", func() {
- Expect(len(kvs)).Should(Equal(1))
- })
-
- })
- Context("with labels app,depth is 2 ", func() {
- kvs, err := kvsvc.FindKV(context.Background(), "default", "test", service.WithKey("timeout"),
- service.WithLabels(map[string]string{
- "app": "mall",
- }),
- service.WithDepth(2))
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
- It("should has 3 records", func() {
- Expect(len(kvs)).Should(Equal(3))
- })
+}
- })
- })
- Describe("exact find by kv and labels", func() {
- Context("with labels app ", func() {
- kvs, err := kvsvc.FindKV(context.Background(), "default", "test", service.WithKey("timeout"), service.WithLabels(map[string]string{
- "app": "mall",
- }), service.WithExactLabels())
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
- It("should has 1 records", func() {
- Expect(len(kvs)).Should(Equal(1))
- })
-
- })
- })
- Describe("exact find by labels", func() {
- Context("with labels app ", func() {
- kvs, err := kvsvc.FindKV(context.Background(), "default", "test", service.WithLabels(map[string]string{
+func TestService_FindKV(t *testing.T) {
+ kvsvc := &kv.Service{}
+ t.Run("exact find by kv and labels with label app", func(t *testing.T) {
+ kvs, err := kvsvc.FindKV(context.Background(), "default", "test",
+ service.WithKey("timeout"),
+ service.WithLabels(map[string]string{
"app": "mall",
- }), service.WithExactLabels())
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
- It("should has 1 records", func() {
- Expect(len(kvs)).Should(Equal(1))
- })
-
- })
+ }),
+ service.WithExactLabels())
+ assert.NoError(t, err)
+ assert.Equal(t, 1, len(kvs))
})
- Describe("greedy find by labels", func() {
- Context("with labels app ans service ", func() {
- kvs, err := kvsvc.FindKV(context.Background(), "default", "test", service.WithLabels(map[string]string{
- "app": "mall",
- "service": "cart",
- }))
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
- It("should has 1 records", func() {
- Expect(len(kvs)).Should(Equal(1))
- })
-
- })
+ t.Run("greedy find by labels,with labels app ans service ", func(t *testing.T) {
+ kvs, err := kvsvc.FindKV(context.Background(), "default", "test", service.WithLabels(map[string]string{
+ "app": "mall",
+ "service": "cart",
+ }))
+ assert.NoError(t, err)
+ assert.Equal(t, 1, len(kvs))
})
-
- Describe("delete key", func() {
- Context("delete key by kvID", func() {
- kv1, err := kvsvc.CreateOrUpdate(context.Background(), &model.KVDoc{
- Key: "timeout",
- Value: "20s",
- Labels: map[string]string{
- "env": "test",
- },
- Domain: "default",
- Project: "test",
- })
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
-
- err = kvsvc.Delete(kv1.ID.String(), "", "default", "test")
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
-
+}
+func TestService_Delete(t *testing.T) {
+ kvsvc := &kv.Service{}
+ t.Run("delete key by kvID", func(t *testing.T) {
+ kv1, err := kvsvc.CreateOrUpdate(context.Background(), &model.KVDoc{
+ Key: "timeout",
+ Value: "20s",
+ Labels: map[string]string{
+ "env": "test",
+ },
+ Domain: "default",
+ Project: "test",
})
- Context("delete key by kvID and labelID", func() {
- kv1, err := kvsvc.CreateOrUpdate(context.Background(), &model.KVDoc{
- Key: "timeout",
- Value: "20s",
- Labels: map[string]string{
- "env": "test",
- },
- Domain: "default",
- Project: "test",
- })
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
+ assert.NoError(t, err)
- err = kvsvc.Delete(kv1.ID.String(), kv1.LabelID, "default", "test")
- It("should not return err", func() {
- Expect(err).Should(BeNil())
- })
+ err = kvsvc.Delete(context.TODO(), kv1.ID, "default", "test")
+ assert.NoError(t, err)
- })
- Context("test miss kvID, no panic", func() {
- err := kvsvc.Delete("", "", "default", "test")
- It("should not return err", func() {
- Expect(err).Should(HaveOccurred())
- })
- })
- Context("Test encode error ", func() {
- err := kvsvc.Delete("12312312321", "", "default", "test")
- It("should return err", func() {
- Expect(err).To(HaveOccurred())
- })
- })
- Context("Test miss domain error ", func() {
- err := kvsvc.Delete("12312312321", "", "", "test")
- It("should return err", func() {
- Expect(err).Should(Equal(session.ErrMissingDomain))
- })
- })
})
-})
+ t.Run("miss id", func(t *testing.T) {
+ err := kvsvc.Delete(context.TODO(), "", "default", "test")
+ assert.Error(t, err)
+ })
+ t.Run("miss domain", func(t *testing.T) {
+ err := kvsvc.Delete(context.TODO(), "2", "", "test")
+ assert.Equal(t, session.ErrMissingDomain, err)
+ })
+}
diff --git a/server/service/mongo/label/label_dao.go b/server/service/mongo/label/label_dao.go
index 87149fc..ff1f40d 100644
--- a/server/service/mongo/label/label_dao.go
+++ b/server/service/mongo/label/label_dao.go
@@ -21,13 +21,10 @@ import (
"context"
"fmt"
"github.com/apache/servicecomb-kie/pkg/model"
- "github.com/apache/servicecomb-kie/server/id"
- "github.com/apache/servicecomb-kie/server/service"
"github.com/apache/servicecomb-kie/server/service/mongo/session"
"github.com/go-mesh/openlogging"
+ uuid "github.com/satori/go.uuid"
"go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "go.mongodb.org/mongo-driver/mongo/options"
)
const (
@@ -75,37 +72,8 @@ func FindLabels(ctx context.Context, domain, project string, labels map[string]s
return nil, session.ErrLabelNotExists
}
-//GetLatestLabel query revision table and find maximum revision number
-func GetLatestLabel(ctx context.Context, labelID string) (*model.LabelRevisionDoc, error) {
- collection := session.GetDB().Collection(session.CollectionLabelRevision)
-
- filter := bson.M{"label_id": labelID}
-
- cur, err := collection.Find(ctx, filter,
- options.Find().SetSort(map[string]interface{}{
- "revision": -1,
- }), options.Find().SetLimit(1))
- if err != nil {
- return nil, err
- }
- h := &model.LabelRevisionDoc{}
- var exist bool
- for cur.Next(ctx) {
- if err := cur.Decode(h); err != nil {
- openlogging.Error("decode to KVs error: " + err.Error())
- return nil, err
- }
- exist = true
- break
- }
- if !exist {
- return nil, service.ErrRevisionNotExist
- }
- return h, nil
-}
-
//Exist check whether the project has certain label or not and return label ID
-func Exist(ctx context.Context, domain string, project string, labels map[string]string) (id.ID, error) {
+func Exist(ctx context.Context, domain string, project string, labels map[string]string) (string, error) {
l, err := FindLabels(ctx, domain, project, labels)
if err != nil {
if err.Error() == context.DeadlineExceeded.Error() {
@@ -127,13 +95,12 @@ func CreateLabel(ctx context.Context, domain string, labels map[string]string, p
Domain: domain,
Labels: labels,
Project: project,
+ ID: uuid.NewV4().String(),
}
collection := session.GetDB().Collection(session.CollectionLabel)
- res, err := collection.InsertOne(ctx, l)
+ _, err := collection.InsertOne(ctx, l)
if err != nil {
return nil, err
}
- objectID, _ := res.InsertedID.(primitive.ObjectID)
- l.ID = id.ID(objectID.Hex())
return l, nil
}
diff --git a/server/service/mongo/session/session.go b/server/service/mongo/session/session.go
index 1eb43e2..2e4720e 100644
--- a/server/service/mongo/session/session.go
+++ b/server/service/mongo/session/session.go
@@ -40,10 +40,10 @@ import (
//const for db name and collection name
const (
- DBName = "kie"
- CollectionLabel = "label"
- CollectionKV = "kv"
- CollectionLabelRevision = "label_revision"
+ DBName = "kie"
+ CollectionLabel = "label"
+ CollectionKV = "kv"
+ CollectionKVRevision = "kv_revision"
DefaultTimeout = 5 * time.Second
DefaultValueType = "text"
@@ -86,7 +86,6 @@ func Init() error {
reg := bson.NewRegistryBuilder().
RegisterEncoder(reflect.TypeOf(model.LabelDoc{}), sc).
RegisterEncoder(reflect.TypeOf(model.KVDoc{}), sc).
- RegisterEncoder(reflect.TypeOf(model.LabelRevisionDoc{}), sc).
Build()
clientOps := []*options.ClientOptions{options.Client().ApplyURI(config.GetDB().URI)}
if config.GetDB().SSLEnabled {
diff --git a/server/service/service.go b/server/service/service.go
index 4262b2a..1585a8d 100644
--- a/server/service/service.go
+++ b/server/service/service.go
@@ -33,7 +33,7 @@ var (
//db errors
var (
ErrKeyNotExists = errors.New("key with labels does not exits")
- ErrRevisionNotExist = errors.New("label revision not exist")
+ ErrRevisionNotExist = errors.New("revision does not exist")
)
//KV provide api of KV entity
@@ -41,14 +41,14 @@ type KV interface {
//below 3 methods is usually for admin console
CreateOrUpdate(ctx context.Context, kv *model.KVDoc) (*model.KVDoc, error)
List(ctx context.Context, domain, project string, limit, offset int, options ...FindOption) (*model.KVResponse, error)
- Delete(kvID string, labelID string, domain, project string) error
+ Delete(ctx context.Context, kvID string, domain, project string) error
//FindKV is usually for service to pull configs
FindKV(ctx context.Context, domain, project string, options ...FindOption) ([]*model.KVResponse, error)
}
//History provide api of History entity
type History interface {
- GetHistory(ctx context.Context, labelID string, options ...FindOption) ([]*model.LabelRevisionDoc, error)
+ GetHistory(ctx context.Context, keyID string, options ...FindOption) ([]*model.KVDoc, error)
}
//Init init db session