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 c943c7c  SCB-1723 support pagination in kie apis (#71)
c943c7c is described below

commit c943c7c0eed5fba98928cb46a690d3140a8fa647
Author: Ang Li <[email protected]>
AuthorDate: Sun Jan 19 14:39:48 2020 +0800

    SCB-1723 support pagination in kie apis (#71)
    
    * SCB-1723 support pagination in kie apis
    
    * add slow query log, add db info to uri
    
    * SCB-1723 move offset and limit settings to functional options
    
    * SCB-1723 get paging params from query, no paging by default, add UTs
---
 .gitignore                                    |  1 +
 docs/configurations/storage.md                |  2 +-
 examples/dev/db.js                            |  3 +-
 examples/dev/kie-conf.yaml                    |  2 +-
 pkg/common/common.go                          |  2 ++
 server/resource/v1/common.go                  | 14 ++++++----
 server/resource/v1/doc_struct.go              | 12 ++++++++
 server/resource/v1/history_resource.go        | 16 +++++++++--
 server/resource/v1/kv_resource.go             | 40 +++++++++++++++++++--------
 server/resource/v1/kv_resource_test.go        | 36 +++++++++++++++++++++++-
 server/service/mongo/counter/revision_test.go |  2 +-
 server/service/mongo/history/dao.go           | 13 +++++++--
 server/service/mongo/history/service.go       |  2 +-
 server/service/mongo/history/service_test.go  |  2 +-
 server/service/mongo/kv/kv_dao.go             | 10 ++++++-
 server/service/mongo/kv/kv_service.go         | 14 ++++++++--
 server/service/mongo/kv/kv_test.go            | 29 +++++++++++--------
 server/service/options.go                     | 16 +++++++++++
 server/service/service.go                     |  2 +-
 19 files changed, 174 insertions(+), 44 deletions(-)

diff --git a/.gitignore b/.gitignore
index 172347d..43590f7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,4 +21,5 @@ release
 etc/data/
 etc/ssl/
 tmp/
+conf/
 glide.lock
diff --git a/docs/configurations/storage.md b/docs/configurations/storage.md
index 1828410..dd5abc3 100644
--- a/docs/configurations/storage.md
+++ b/docs/configurations/storage.md
@@ -20,7 +20,7 @@ you can use mongo db as kie server storage to save 
configuration
 ### Example
 ```yaml
 db:
-  uri: mongodb://kie:[email protected]:27017
+  uri: mongodb://kie:[email protected]:27017/kie
   poolSize: 10
   timeout:  5m
   sslEnabled: true
diff --git a/examples/dev/db.js b/examples/dev/db.js
index 17f6cef..918ee58 100644
--- a/examples/dev/db.js
+++ b/examples/dev/db.js
@@ -47,4 +47,5 @@ db.createCollection( "kv", {
         } }
 } );
 db.kv.createIndex({"id": 1}, { unique: true } );
-db.kv.createIndex({key: 1, label_id: 1,domain:1,project:1},{ unique: true });
\ No newline at end of file
+db.kv.createIndex({key: 1, label_id: 1,domain:1,project:1},{ unique: true });
+db.setProfilingLevel(1, {slowms: 80, sampleRate: 1} );
\ No newline at end of file
diff --git a/examples/dev/kie-conf.yaml b/examples/dev/kie-conf.yaml
index c9633fa..4fef6b2 100644
--- a/examples/dev/kie-conf.yaml
+++ b/examples/dev/kie-conf.yaml
@@ -1,6 +1,6 @@
 db:
   #uri: mongodb://rwuser:[email protected]:8635/test?authSource=admin
-  uri: mongodb://kie:[email protected]:27017
+  uri: mongodb://kie:[email protected]:27017/kie
   type: mongodb
   poolSize: 10
   timeout:  5m
diff --git a/pkg/common/common.go b/pkg/common/common.go
index 45739ad..41bd161 100644
--- a/pkg/common/common.go
+++ b/pkg/common/common.go
@@ -25,6 +25,8 @@ const (
        QueryParamRev    = "revision"
        QueryParamMatch  = "match"
        QueryParamKeyID  = "kv_id"
+       QueryLimit       = "limit"
+       QueryOffset      = "offset"
 )
 
 //http headers
diff --git a/server/resource/v1/common.go b/server/resource/v1/common.go
index 85e3e41..8a329f0 100644
--- a/server/resource/v1/common.go
+++ b/server/resource/v1/common.go
@@ -205,21 +205,25 @@ func checkPagination(limitStr, offsetStr string) (int64, 
int64, error) {
                if err != nil {
                        return 0, 0, errors.New("invalid offset number")
                }
-               if offset < 1 {
+               if offset < 0 {
                        return 0, 0, errors.New("invalid offset number")
                }
        }
        return limit, offset, err
 }
 func queryAndResponse(rctx *restful.Context,
-       domain interface{}, project string, key string, labels 
map[string]string, limit, offset int) {
+       domain interface{}, project string, key string, labels 
map[string]string, limit, offset int64) {
        m := getMatchPattern(rctx)
-       opts := []service.FindOption{service.WithKey(key), 
service.WithLabels(labels)}
+       opts := []service.FindOption{
+               service.WithKey(key),
+               service.WithLabels(labels),
+               service.WithLimit(limit),
+               service.WithOffset(offset),
+       }
        if m == PatternExact {
                opts = append(opts, service.WithExactLabels())
        }
-       kv, err := service.KVService.List(rctx.Ctx, domain.(string), project,
-               limit, offset, opts...)
+       kv, err := service.KVService.List(rctx.Ctx, domain.(string), project, 
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 47635ce..b8de013 100644
--- a/server/resource/v1/doc_struct.go
+++ b/server/resource/v1/doc_struct.go
@@ -89,6 +89,18 @@ var (
                ParamType: goRestful.QueryParameterKind,
                Desc:      "label pairs,for example 
&label=service:order&label=version:1.0.0",
        }
+       DocQueryLimitParameters = &restful.Parameters{
+               DataType:  "string",
+               Name:      common.QueryLimit,
+               ParamType: goRestful.QueryParameterKind,
+               Desc:      "limit,for example &limit=10",
+       }
+       DocQueryOffsetParameters = &restful.Parameters{
+               DataType:  "string",
+               Name:      common.QueryOffset,
+               ParamType: goRestful.QueryParameterKind,
+               Desc:      "offset,for example &offset=10",
+       }
 )
 
 //swagger doc path params
diff --git a/server/resource/v1/history_resource.go 
b/server/resource/v1/history_resource.go
index 44c21fc..09d60e6 100644
--- a/server/resource/v1/history_resource.go
+++ b/server/resource/v1/history_resource.go
@@ -36,14 +36,24 @@ type HistoryResource struct {
 //GetRevisions search key only by label
 func (r *HistoryResource) GetRevisions(context *restful.Context) {
        var err error
-       labelID := context.ReadPathParameter("key_id")
-       if labelID == "" {
+       keyID := context.ReadPathParameter("key_id")
+       limitStr := context.ReadQueryParameter("limit")
+       offsetStr := context.ReadQueryParameter("offset")
+       limit, offset, err := checkPagination(limitStr, offsetStr)
+       if err != nil {
+               WriteErrResponse(context, http.StatusBadRequest, err.Error(), 
common.ContentTypeText)
+               return
+       }
+       if keyID == "" {
                openlogging.Error("key id is nil")
                WriteErrResponse(context, http.StatusForbidden, "key_id must 
not be empty", common.ContentTypeText)
                return
        }
        key := context.ReadQueryParameter("key")
-       revisions, err := service.HistoryService.GetHistory(context.Ctx, 
labelID, service.WithKey(key))
+       revisions, err := service.HistoryService.GetHistory(context.Ctx, keyID,
+               service.WithKey(key),
+               service.WithLimit(limit),
+               service.WithOffset(offset))
        if err != nil {
                if err == service.ErrRevisionNotExist {
                        WriteErrResponse(context, http.StatusNotFound, 
err.Error(), common.ContentTypeText)
diff --git a/server/resource/v1/kv_resource.go 
b/server/resource/v1/kv_resource.go
index 02db656..784c408 100644
--- a/server/resource/v1/kv_resource.go
+++ b/server/resource/v1/kv_resource.go
@@ -96,10 +96,16 @@ func (r *KVResource) GetByKey(rctx *restful.Context) {
                WriteErrResponse(rctx, http.StatusInternalServerError, 
MsgDomainMustNotBeEmpty, common.ContentTypeText)
                return
        }
-       returnData(rctx, domain, project, labels, 0, 0)
+       limitStr := rctx.ReadQueryParameter("limit")
+       offsetStr := rctx.ReadQueryParameter("offset")
+       limit, offset, err := checkPagination(limitStr, offsetStr)
+       if err != nil {
+               WriteErrResponse(rctx, http.StatusBadRequest, err.Error(), 
common.ContentTypeText)
+               return
+       }
+       returnData(rctx, domain, project, labels, limit, offset)
 }
 
-//List TODO pagination
 func (r *KVResource) List(rctx *restful.Context) {
        var err error
        project := rctx.ReadPathParameter("project")
@@ -113,8 +119,8 @@ func (r *KVResource) List(rctx *restful.Context) {
                WriteErrResponse(rctx, http.StatusBadRequest, err.Error(), 
common.ContentTypeText)
                return
        }
-       limitStr := rctx.ReadPathParameter("limit")
-       offsetStr := rctx.ReadPathParameter("offset")
+       limitStr := rctx.ReadQueryParameter("limit")
+       offsetStr := rctx.ReadQueryParameter("offset")
        limit, offset, err := checkPagination(limitStr, offsetStr)
        if err != nil {
                WriteErrResponse(rctx, http.StatusBadRequest, err.Error(), 
common.ContentTypeText)
@@ -123,12 +129,12 @@ func (r *KVResource) List(rctx *restful.Context) {
        returnData(rctx, domain, project, labels, limit, offset)
 }
 
-func returnData(rctx *restful.Context, domain interface{}, project string, 
labels map[string]string, limit int64, offset int64) {
+func returnData(rctx *restful.Context, domain interface{}, project string, 
labels map[string]string, limit, offset int64) {
        revStr := rctx.ReadQueryParameter(common.QueryParamRev)
        wait := rctx.ReadQueryParameter(common.QueryParamWait)
        if revStr == "" {
                if wait == "" {
-                       queryAndResponse(rctx, domain, project, "", labels, 
int(limit), int(offset))
+                       queryAndResponse(rctx, domain, project, "", labels, 
limit, offset)
                        return
                }
                changed, err := eventHappened(rctx, wait, &pubsub.Topic{
@@ -141,7 +147,7 @@ func returnData(rctx *restful.Context, domain interface{}, 
project string, label
                        return
                }
                if changed {
-                       queryAndResponse(rctx, domain, project, "", labels, 
int(limit), int(offset))
+                       queryAndResponse(rctx, domain, project, "", labels, 
limit, offset)
                        return
                }
                rctx.WriteHeader(http.StatusNotModified)
@@ -156,7 +162,7 @@ func returnData(rctx *restful.Context, domain interface{}, 
project string, label
                        return
                }
                if revised {
-                       queryAndResponse(rctx, domain, project, "", labels, 
int(limit), int(offset))
+                       queryAndResponse(rctx, domain, project, "", labels, 
limit, offset)
                        return
                } else if wait != "" {
                        changed, err := eventHappened(rctx, wait, &pubsub.Topic{
@@ -169,7 +175,7 @@ func returnData(rctx *restful.Context, domain interface{}, 
project string, label
                                return
                        }
                        if changed {
-                               queryAndResponse(rctx, domain, project, "", 
labels, int(limit), int(offset))
+                               queryAndResponse(rctx, domain, project, "", 
labels, limit, offset)
                                return
                        }
                        rctx.WriteHeader(http.StatusNotModified)
@@ -195,8 +201,17 @@ func (r *KVResource) Search(context *restful.Context) {
                return
        }
        var kvs []*model.KVResponse
+       limitStr := context.ReadQueryParameter("limit")
+       offsetStr := context.ReadQueryParameter("offset")
+       limit, offset, err := checkPagination(limitStr, offsetStr)
+       if err != nil {
+               WriteErrResponse(context, http.StatusBadRequest, err.Error(), 
common.ContentTypeText)
+               return
+       }
        if labelCombinations == nil {
-               result, err := service.KVService.FindKV(context.Ctx, 
domain.(string), project)
+               result, err := service.KVService.FindKV(context.Ctx, 
domain.(string), project,
+                       service.WithLimit(limit),
+                       service.WithOffset(offset))
                if err != nil {
                        openlogging.Error("can not find by labels", 
openlogging.WithTags(openlogging.Tags{
                                "err": err.Error(),
@@ -210,7 +225,10 @@ func (r *KVResource) Search(context *restful.Context) {
                openlogging.Debug("find by combination", 
openlogging.WithTags(openlogging.Tags{
                        "q": labels,
                }))
-               result, err := service.KVService.FindKV(context.Ctx, 
domain.(string), project, service.WithLabels(labels))
+               result, err := service.KVService.FindKV(context.Ctx, 
domain.(string), project,
+                       service.WithLabels(labels),
+                       service.WithLimit(limit),
+                       service.WithOffset(offset))
                if err != nil {
                        if err == service.ErrKeyNotExists {
                                continue
diff --git a/server/resource/v1/kv_resource_test.go 
b/server/resource/v1/kv_resource_test.go
index 4354a3a..a60bb30 100644
--- a/server/resource/v1/kv_resource_test.go
+++ b/server/resource/v1/kv_resource_test.go
@@ -56,7 +56,7 @@ func init() {
                ListenPeerAddr: "127.0.0.1:4000",
                AdvertiseAddr:  "127.0.0.1:4000",
        }
-       config.Configurations.DB.URI = "mongodb://kie:[email protected]:27017"
+       config.Configurations.DB.URI = "mongodb://kie:[email protected]:27017/kie"
        err := service.DBInit()
        if err != nil {
                panic(err)
@@ -220,6 +220,40 @@ func TestKVResource_List(t *testing.T) {
                duration := time.Since(start)
                t.Log(duration)
        })
+       t.Run("list kv by service label offset, should return 1kv", func(t 
*testing.T) {
+               r, _ := http.NewRequest("GET", 
"/v1/test/kie/kv?label=service:utService&offset=1", 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("list kv by service label limit, should return 1kv", func(t 
*testing.T) {
+               r, _ := http.NewRequest("GET", 
"/v1/test/kie/kv?label=service:utService&limit=1", 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))
+       })
 }
 func TestKVResource_GetByKey(t *testing.T) {
        t.Run("get one key by label, exact match,should return 1 kv", func(t 
*testing.T) {
diff --git a/server/service/mongo/counter/revision_test.go 
b/server/service/mongo/counter/revision_test.go
index 744fd9f..d298942 100644
--- a/server/service/mongo/counter/revision_test.go
+++ b/server/service/mongo/counter/revision_test.go
@@ -28,7 +28,7 @@ import (
 
 func TestIncreaseAndGetRevision(t *testing.T) {
        var err error
-       config.Configurations = &config.Config{DB: config.DB{URI: 
"mongodb://kie:[email protected]:27017"}}
+       config.Configurations = &config.Config{DB: config.DB{URI: 
"mongodb://kie:[email protected]:27017/kie"}}
        err = session.Init()
        assert.NoError(t, err)
        s := &counter.Service{}
diff --git a/server/service/mongo/history/dao.go 
b/server/service/mongo/history/dao.go
index d9021c4..0057bbc 100644
--- a/server/service/mongo/history/dao.go
+++ b/server/service/mongo/history/dao.go
@@ -27,11 +27,18 @@ import (
        "go.mongodb.org/mongo-driver/mongo/options"
 )
 
-func getHistoryByKeyID(ctx context.Context, filter bson.M) ([]*model.KVDoc, 
error) {
+func getHistoryByKeyID(ctx context.Context, filter bson.M, limit, offset 
int64) ([]*model.KVDoc, error) {
        collection := session.GetDB().Collection(session.CollectionKVRevision)
-       cur, err := collection.Find(ctx, filter, 
options.Find().SetSort(map[string]interface{}{
+       opt := options.Find().SetSort(map[string]interface{}{
                "revision": -1,
-       }))
+       })
+       if limit != 0 {
+               opt = opt.SetLimit(limit)
+       }
+       if offset != 0 {
+               opt = opt.SetSkip(offset)
+       }
+       cur, err := collection.Find(ctx, filter, opt)
        if err != nil {
                return nil, err
        }
diff --git a/server/service/mongo/history/service.go 
b/server/service/mongo/history/service.go
index 19f5969..9502e75 100644
--- a/server/service/mongo/history/service.go
+++ b/server/service/mongo/history/service.go
@@ -40,5 +40,5 @@ func (s *Service) GetHistory(ctx context.Context, kvID 
string, options ...servic
                "id": kvID,
        }
 
-       return getHistoryByKeyID(ctx, filter)
+       return getHistoryByKeyID(ctx, filter, opts.Limit, opts.Offset)
 }
diff --git a/server/service/mongo/history/service_test.go 
b/server/service/mongo/history/service_test.go
index 7cb0cb3..ea0aa77 100644
--- a/server/service/mongo/history/service_test.go
+++ b/server/service/mongo/history/service_test.go
@@ -27,7 +27,7 @@ import (
 )
 
 func init() {
-       config.Configurations = &config.Config{DB: config.DB{URI: 
"mongodb://kie:[email protected]:27017"}}
+       config.Configurations = &config.Config{DB: config.DB{URI: 
"mongodb://kie:[email protected]:27017/kie"}}
        _ = session.Init()
 }
 
diff --git a/server/service/mongo/kv/kv_dao.go 
b/server/service/mongo/kv/kv_dao.go
index 74ed8d1..15e8eaa 100644
--- a/server/service/mongo/kv/kv_dao.go
+++ b/server/service/mongo/kv/kv_dao.go
@@ -29,6 +29,7 @@ import (
        uuid "github.com/satori/go.uuid"
        "go.mongodb.org/mongo-driver/bson"
        "go.mongodb.org/mongo-driver/mongo"
+       "go.mongodb.org/mongo-driver/mongo/options"
 )
 
 //createKey get latest revision from history
@@ -111,7 +112,14 @@ func findKV(ctx context.Context, domain string, project 
string, opts service.Fin
                        filter["labels."+k] = v
                }
        }
-       cur, err := collection.Find(ctx, filter)
+       opt := options.Find()
+       if opts.Limit != 0 {
+               opt = opt.SetLimit(opts.Limit)
+       }
+       if opts.Offset != 0 {
+               opt = opt.SetSkip(opts.Offset)
+       }
+       cur, err := collection.Find(ctx, filter, opt)
        if err != nil {
                if err.Error() == context.DeadlineExceeded.Error() {
                        openlogging.Error("find kv failed, deadline exceeded", 
openlogging.WithTags(openlogging.Tags{
diff --git a/server/service/mongo/kv/kv_service.go 
b/server/service/mongo/kv/kv_service.go
index 96d35de..49bd7ef 100644
--- a/server/service/mongo/kv/kv_service.go
+++ b/server/service/mongo/kv/kv_service.go
@@ -31,6 +31,12 @@ import (
        "github.com/go-mesh/openlogging"
 )
 
+//const
+const (
+       existKvLimit  = 2
+       existKvOffset = 0
+)
+
 //Service operate data in mongodb
 type Service struct {
        timeout time.Duration
@@ -111,7 +117,11 @@ func (s *Service) Exist(ctx context.Context, domain, key 
string, project string,
                return kvs[0], nil
        }
        kvs, err := s.FindKV(ctx, domain, project,
-               service.WithExactLabels(), service.WithLabels(opts.Labels), 
service.WithKey(key))
+               service.WithExactLabels(),
+               service.WithLabels(opts.Labels),
+               service.WithKey(key),
+               service.WithLimit(existKvLimit),
+               service.WithOffset(existKvOffset))
        if err != nil {
                openlogging.Error(err.Error())
                return nil, err
@@ -147,7 +157,7 @@ func (s *Service) Delete(ctx context.Context, kvID string, 
domain string, projec
 }
 
 //List get kv list by key and criteria
-func (s *Service) List(ctx context.Context, domain, project string, limit, 
offset int, options ...service.FindOption) (*model.KVResponse, error) {
+func (s *Service) List(ctx context.Context, domain, project string, options 
...service.FindOption) (*model.KVResponse, error) {
        opts := service.NewDefaultFindOpts()
        for _, o := range options {
                o(&opts)
diff --git a/server/service/mongo/kv/kv_test.go 
b/server/service/mongo/kv/kv_test.go
index 710ad58..cd52ea7 100644
--- a/server/service/mongo/kv/kv_test.go
+++ b/server/service/mongo/kv/kv_test.go
@@ -30,7 +30,7 @@ import (
 
 func TestService_CreateOrUpdate(t *testing.T) {
        var err error
-       config.Configurations = &config.Config{DB: config.DB{URI: 
"mongodb://kie:[email protected]:27017"}}
+       config.Configurations = &config.Config{DB: config.DB{URI: 
"mongodb://kie:[email protected]:27017/kie"}}
        err = session.Init()
        assert.NoError(t, err)
        kvsvc := &kv.Service{}
@@ -81,9 +81,12 @@ func TestService_CreateOrUpdate(t *testing.T) {
                        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())
+               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",
@@ -99,9 +102,12 @@ func TestService_CreateOrUpdate(t *testing.T) {
                        "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())
+               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)
        })
 
@@ -120,10 +126,11 @@ func TestService_FindKV(t *testing.T) {
                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", 
"test", service.WithLabels(map[string]string{
-                       "app":     "mall",
-                       "service": "cart",
-               }))
+               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))
        })
diff --git a/server/service/options.go b/server/service/options.go
index 9fe41c6..bae00a7 100644
--- a/server/service/options.go
+++ b/server/service/options.go
@@ -38,6 +38,8 @@ type FindOptions struct {
        LabelID     string
        ClearLabel  bool
        Timeout     time.Duration
+       Limit       int64
+       Offset      int64
 }
 
 //FindOption is functional option to find key value
@@ -91,3 +93,17 @@ func WithOutLabelField() FindOption {
                o.ClearLabel = true
        }
 }
+
+//WithLimit tells service paging limit
+func WithLimit(l int64) FindOption {
+       return func(o *FindOptions) {
+               o.Limit = l
+       }
+}
+
+//WithOffset tells service paging offset
+func WithOffset(os int64) FindOption {
+       return func(o *FindOptions) {
+               o.Offset = os
+       }
+}
diff --git a/server/service/service.go b/server/service/service.go
index e6e5310..b3a82c7 100644
--- a/server/service/service.go
+++ b/server/service/service.go
@@ -41,7 +41,7 @@ var (
 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)
+       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)

Reply via email to