Skip to content

Commit

Permalink
Merge b0967f4 into feeacdf
Browse files Browse the repository at this point in the history
  • Loading branch information
tianxiaoliang committed Mar 26, 2020
2 parents feeacdf + b0967f4 commit 807374b
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 135 deletions.
19 changes: 16 additions & 3 deletions server/resource/v1/kv_resource.go
Expand Up @@ -122,11 +122,25 @@ func (r *KVResource) List(rctx *restful.Context) {
var err error
project := rctx.ReadPathParameter(PathParameterProject)
domain := ReadDomain(rctx)
kvID := rctx.ReadQueryParameter(common.QueryParamKeyID)
if kvID != "" {
kv, err := service.KVService.Get(rctx.Ctx, domain.(string), project, kvID)
if err != nil {
WriteErrResponse(rctx, http.StatusBadRequest, err.Error(), common.ContentTypeText)
return
}
err = writeResponse(rctx, kv)
if err != nil {
openlogging.Error(err.Error())
}
return
}
labels, err := getLabels(rctx)
if err != nil {
WriteErrResponse(rctx, http.StatusBadRequest, err.Error(), common.ContentTypeText)
return
}

offsetStr := rctx.ReadQueryParameter(common.QueryParamOffset)
limitStr := rctx.ReadQueryParameter(common.QueryParamLimit)
offset, limit, err := checkPagination(offsetStr, limitStr)
Expand Down Expand Up @@ -217,16 +231,15 @@ func (r *KVResource) Delete(context *restful.Context) {
WriteErrResponse(context, http.StatusBadRequest, common.ErrKvIDMustNotEmpty, common.ContentTypeText)
return
}
result, err := service.KVService.FindKV(context.Ctx, domain.(string), project,
service.WithID(kvID))
result, err := service.KVService.Get(context.Ctx, domain.(string), project, kvID)
if err != nil && err != service.ErrKeyNotExists {
WriteErrResponse(context, http.StatusInternalServerError, err.Error(), common.ContentTypeText)
return
} else if err == service.ErrKeyNotExists {
context.WriteHeader(http.StatusNoContent)
return
}
kv := result[0].Data[0]
kv := result.Data[0]
err = service.KVService.Delete(context.Ctx, kvID, domain.(string), project)
if err != nil {
openlogging.Error("delete failed ,", openlogging.WithTags(openlogging.Tags{
Expand Down
23 changes: 22 additions & 1 deletion server/resource/v1/kv_resource_test.go
Expand Up @@ -117,7 +117,8 @@ func TestKVResource_Put(t *testing.T) {
t.Run("put kv,label is service and version", func(t *testing.T) {
kv := &model.KVDoc{
Value: "1s",
Labels: map[string]string{"service": "utService",
Labels: map[string]string{
"service": "utService",
"version": "1.0.0"},
}
j, _ := json.Marshal(kv)
Expand Down Expand Up @@ -155,6 +156,26 @@ func TestKVResource_List(t *testing.T) {
err = json.Unmarshal(body, result)
assert.NoError(t, err)
assert.Equal(t, 3, len(result.Data))

t.Run("list kv by id, should return only one", func(t *testing.T) {
r, _ := http.NewRequest("GET", "/v1/test/kie/kv?kv_id="+result.Data[0].ID, 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{}
t.Log(string(body))
err = json.Unmarshal(body, result)
assert.NoError(t, err)
assert.Equal(t, 1, len(result.Data))
})

})
var rev string
t.Run("list kv by service label, exact match,should return 2 kv", func(t *testing.T) {
Expand Down
48 changes: 9 additions & 39 deletions server/service/mongo/kv/kv_service.go
Expand Up @@ -123,19 +123,19 @@ func (s *Service) Exist(ctx context.Context, domain, key string, project string,
}
return kvs[0], nil
}
kvs, err := s.FindKV(ctx, domain, project,
kvs, err := s.List(ctx, domain, project,
service.WithExactLabels(),
service.WithLabels(opts.Labels),
service.WithKey(key))
if err != nil {
openlogging.Error(err.Error())
openlogging.Error("check kv exist: " + err.Error())
return nil, err
}
if len(kvs) != 1 {
if len(kvs.Data) != 1 {
return nil, session.ErrTooMany
}

return kvs[0].Data[0], nil
return kvs.Data[0], nil

}

Expand Down Expand Up @@ -193,10 +193,8 @@ func (s *Service) List(ctx context.Context, domain, project string, options ...s
return result, nil
}

//FindKV get kvs by key, labels
//because labels has a a lot of combination,
//you can use WithDepth(0) to return only one kv which's labels exactly match the criteria
func (s *Service) FindKV(ctx context.Context, domain string, project string, options ...service.FindOption) ([]*model.KVResponse, error) {
//Get get kvs by id
func (s *Service) Get(ctx context.Context, domain, project, id string, options ...service.FindOption) (*model.KVResponse, error) {
opts := service.FindOptions{}
for _, o := range options {
o(&opts)
Expand All @@ -210,36 +208,8 @@ func (s *Service) FindKV(ctx context.Context, domain string, project string, opt
if project == "" {
return nil, session.ErrMissingProject
}

if opts.ID != "" {
openlogging.Debug(MsgFindOneKeyByID, openlogging.WithTags(openlogging.Tags{
"id": opts.ID,
"key": opts.Key,
"labels": opts.Labels,
}))
return findKVByID(ctx, domain, project, opts.ID)
if id == "" {
return nil, session.ErrIDIsNil
}

cur, _, err := findKV(ctx, domain, project, opts)
if err != nil {
return nil, err
}
defer cur.Close(ctx)

if opts.Depth == 0 && opts.Key != "" {
openlogging.Debug(MsgFindOneKey, openlogging.WithTags(
map[string]interface{}{
"key": opts.Key,
"label": opts.Labels,
"domain": domain,
},
))
return cursorToOneKV(ctx, cur, opts.Labels)
}
openlogging.Debug(MsgFindMoreKey, openlogging.WithTags(openlogging.Tags{
"depth": opts.Depth,
"key": opts.Key,
"labels": opts.Labels,
}))
return findMoreKV(ctx, cur, &opts)
return findKVByID(ctx, domain, project, id)
}
38 changes: 1 addition & 37 deletions server/service/mongo/kv/kv_test.go
Expand Up @@ -72,7 +72,7 @@ func TestService_CreateOrUpdate(t *testing.T) {
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{
_, err := kvsvc.CreateOrUpdate(context.Background(), &model.KVDoc{
Key: "timeout",
Value: "1s",
Labels: map[string]string{
Expand All @@ -82,13 +82,6 @@ func TestService_CreateOrUpdate(t *testing.T) {
Project: "kv-test",
})
assert.NoError(t, err)
kvs1, err := kvsvc.FindKV(context.Background(), "default", "kv-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",
Expand All @@ -104,39 +97,10 @@ func TestService_CreateOrUpdate(t *testing.T) {
}))
assert.NoError(t, err)
assert.Equal(t, afterKV.Value, savedKV.Value)
kvs, err := kvsvc.FindKV(context.Background(), "default", "kv-test",
service.WithKey("timeout"),
service.WithLabels(map[string]string{
"app": "mall",
}),
service.WithExactLabels())
assert.Equal(t, afterKV.Value, kvs[0].Data[0].Value)
})

}

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", "kv-test",
service.WithKey("timeout"),
service.WithLabels(map[string]string{
"app": "mall",
}),
service.WithExactLabels())
assert.NoError(t, err)
assert.Equal(t, 1, len(kvs))
})
t.Run("greedy find by labels,with labels app ans service ", func(t *testing.T) {
kvs, err := kvsvc.FindKV(context.Background(), "default", "kv-test",
service.WithLabels(map[string]string{
"app": "mall",
"service": "cart",
}))
assert.NoError(t, err)
assert.Equal(t, 1, len(kvs))
})
}
func TestService_Delete(t *testing.T) {
kvsvc := &kv.Service{}
t.Run("delete key by kvID", func(t *testing.T) {
Expand Down
56 changes: 3 additions & 53 deletions server/service/mongo/kv/tool.go
Expand Up @@ -19,7 +19,6 @@ package kv

import (
"context"
"fmt"
"reflect"

"github.com/apache/servicecomb-kie/pkg/model"
Expand Down Expand Up @@ -70,62 +69,13 @@ func cursorToOneKV(ctx context.Context, cur *mongo.Cursor, labels map[string]str
return nil, service.ErrKeyNotExists
}

func findKVByID(ctx context.Context, domain, project, kvID string) ([]*model.KVResponse, error) {
kvResp := make([]*model.KVResponse, 0)
func findKVByID(ctx context.Context, domain, project, kvID string) (*model.KVResponse, error) {
kv, err := findKVDocByID(ctx, domain, project, kvID)
if err != nil {
return nil, err
}
kvResp = append(kvResp, &model.KVResponse{
return &model.KVResponse{
Total: 1,
Data: []*model.KVDoc{kv},
})
return kvResp, nil
}

func findMoreKV(ctx context.Context, cur *mongo.Cursor, opts *service.FindOptions) ([]*model.KVResponse, error) {
kvResp := make([]*model.KVResponse, 0)
for cur.Next(ctx) {
curKV := &model.KVDoc{}

if err := cur.Decode(curKV); err != nil {
openlogging.Error("decode to KVs error: " + err.Error())
return nil, err
}
if (len(curKV.Labels) - len(opts.Labels)) > opts.Depth {
//because it is query by labels, so result can not be minus
//so many labels,then continue
openlogging.Debug("so deep, skip this key")
continue
}
openlogging.Debug(fmt.Sprintf("%v", curKV))
var groupExist bool
var labelGroup *model.KVResponse
for _, labelGroup = range kvResp {
if reflect.DeepEqual(labelGroup.LabelDoc.Labels, curKV.Labels) {
groupExist = true
clearAll(curKV)
labelGroup.Data = append(labelGroup.Data, curKV)
break
}

}
if !groupExist {
labelGroup = &model.KVResponse{
LabelDoc: &model.LabelDocResponse{
Labels: curKV.Labels,
LabelID: curKV.LabelID,
},
Data: []*model.KVDoc{curKV},
}
clearAll(curKV)
openlogging.Debug("add new label group")
kvResp = append(kvResp, labelGroup)
}

}
if len(kvResp) == 0 {
return nil, service.ErrKeyNotExists
}
return kvResp, nil
}, nil
}
4 changes: 2 additions & 2 deletions server/service/service.go
Expand Up @@ -46,8 +46,8 @@ type KV interface {
CreateOrUpdate(ctx context.Context, kv *model.KVDoc) (*model.KVDoc, error)
List(ctx context.Context, domain, project string, options ...FindOption) (*model.KVResponse, 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)
//Get return kv by id
Get(ctx context.Context, domain, project, id string, options ...FindOption) (*model.KVResponse, error)
}

//History provide api of History entity
Expand Down

0 comments on commit 807374b

Please sign in to comment.