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

commit 196d7dd8e181a5315462277b5b1d0417254eedee
Author: wangqijun <[email protected]>
AuthorDate: Tue Jul 2 09:14:14 2019 +0800

    Refactoring the delete function
---
 client/client.go                  | 54 ++++++++++++++++++++++++
 client/client_test.go             | 34 +++++++++++++--
 server/dao/kie_api.go             | 88 +++++++++++++++++++--------------------
 server/dao/kv.go                  | 34 +++++++++++----
 server/dao/kv_test.go             | 35 ++++++++++------
 server/dao/label_history.go       | 32 ++++++++------
 server/dao/mongodb_operator.go    |  4 +-
 server/resource/v1/common.go      |  4 +-
 server/resource/v1/doc_struct.go  |  5 +++
 server/resource/v1/kv_resource.go | 32 +++++++-------
 10 files changed, 219 insertions(+), 103 deletions(-)

diff --git a/client/client.go b/client/client.go
index 58a3c49..34fc9b7 100644
--- a/client/client.go
+++ b/client/client.go
@@ -79,6 +79,39 @@ func New(config Config) (*Client, error) {
        }, nil
 }
 
+//Put create value of a key
+func (c *Client) Put(ctx context.Context, kv model.KVDoc) (*model.KVDoc, 
error) {
+       url := fmt.Sprintf("%s/%s/%s", c.opts.Endpoint, APIPathKV, kv.Key)
+       h := http.Header{}
+       h.Set("Content-Type", "application/json")
+       h.Set("domain", "test")
+       body, _ := json.Marshal(kv)
+       resp, err := c.c.HTTPDoWithContext(ctx, "PUT", url, h, body)
+       if err != nil {
+               return nil, err
+       }
+       b := httputil.ReadBody(resp)
+       if resp.StatusCode != http.StatusOK {
+               if resp.StatusCode == http.StatusNotFound {
+                       return nil, ErrKeyNotExist
+               }
+               openlogging.Error("get failed", 
openlogging.WithTags(openlogging.Tags{
+                       "k":      kv.Key,
+                       "status": resp.Status,
+                       "body":   b,
+               }))
+               return nil, fmt.Errorf("get %s failed,http status [%s], body 
[%s]", kv.Key, resp.Status, b)
+       }
+
+       kvs := &model.KVDoc{}
+       err = json.Unmarshal(b, kvs)
+       if err != nil {
+               openlogging.Error("unmarshal kv failed:" + err.Error())
+               return nil, err
+       }
+       return kvs, nil
+}
+
 //Get get value of a key
 func (c *Client) Get(ctx context.Context, key string, opts ...GetOption) 
([]*model.KVDoc, error) {
        options := GetOptions{}
@@ -112,3 +145,24 @@ func (c *Client) Get(ctx context.Context, key string, opts 
...GetOption) ([]*mod
        }
        return kvs, nil
 }
+
+//Delete remove kv
+func (c *Client) Delete(ctx context.Context, kvID, labelID string) error {
+       url := fmt.Sprintf("%s/%s/%s", c.opts.Endpoint, APIPathKV, kvID)
+       if labelID != "" {
+               url = fmt.Sprintf("%s?labelID=%s", url, labelID)
+       }
+       h := http.Header{}
+       h.Set("Content-Type", "application/json")
+       h.Set("domain", "test")
+
+       resp, err := c.c.HTTPDoWithContext(ctx, "DELETE", url, h, nil)
+       if err != nil {
+               return err
+       }
+       b := httputil.ReadBody(resp)
+       if resp.StatusCode != http.StatusNoContent {
+               return fmt.Errorf("delete %s failed,http status [%s], body 
[%s]", kvID, resp.Status, b)
+       }
+       return nil
+}
diff --git a/client/client_test.go b/client/client_test.go
index 937b6c1..bf125fd 100644
--- a/client/client_test.go
+++ b/client/client_test.go
@@ -18,11 +18,11 @@
 package client_test
 
 import (
-       . "github.com/onsi/ginkgo"
-       . "github.com/onsi/gomega"
-
        "context"
        . "github.com/apache/servicecomb-kie/client"
+       "github.com/apache/servicecomb-kie/pkg/model"
+       . "github.com/onsi/ginkgo"
+       . "github.com/onsi/gomega"
        "os"
 )
 
@@ -62,4 +62,32 @@ var _ = Describe("Client", func() {
 
                })
        })
+
+       Describe("DELETE /v1/kv/", func() {
+               Context("by kvID", func() {
+                       client2, err := New(Config{
+                               Endpoint: "http://127.0.0.1:30110";,
+                       })
+
+                       kvBody := model.KVDoc{}
+                       kvBody.Key = "time"
+                       kvBody.Value = "100s"
+                       kvBody.ValueType = "string"
+                       kvBody.Labels = make(map[string]string)
+                       kvBody.Labels["evn"] = "test"
+                       kv, err := client2.Put(context.TODO(), kvBody)
+                       It("should be not error", func() {
+                               Ω(err).ShouldNot(HaveOccurred())
+                               Expect(kv.Key).To(Equal(kvBody.Key))
+                       })
+                       client3, err := New(Config{
+                               Endpoint: "http://127.0.0.1:30110";,
+                       })
+                       It("should be 204", func() {
+                               err := client3.Delete(context.TODO(), 
kv.ID.Hex(), "")
+                               Ω(err).ShouldNot(HaveOccurred())
+                       })
+               })
+       })
+
 })
diff --git a/server/dao/kie_api.go b/server/dao/kie_api.go
index 5e641aa..de65dcd 100644
--- a/server/dao/kie_api.go
+++ b/server/dao/kie_api.go
@@ -193,7 +193,8 @@ func (s *MongodbService) FindKVByLabelID(ctx 
context.Context, domain, labelID, k
        ctx, _ = context.WithTimeout(context.Background(), DefaultTimeout)
        filter := bson.M{"label_id": labelID, "domain": domain}
        if key != "" {
-               return s.findOneKey(ctx, filter, key)
+               filter["key"] = key
+               return s.findOneKey(ctx, filter)
        }
        return s.findKeys(ctx, filter, true)
 
@@ -279,63 +280,58 @@ func (s *MongodbService) FindKV(ctx context.Context, 
domain string, options ...F
 
 }
 
-//DeleteByID delete a key value by collection ID
-func (s *MongodbService) DeleteByID(id string) error {
-       collection := s.c.Database(DB).Collection(CollectionKV)
-       hex, err := primitive.ObjectIDFromHex(id)
-       if err != nil {
-               openlogging.Error(fmt.Sprintf("convert %s ,err:%s", id, err))
-               return err
-       }
-       ctx, _ := context.WithTimeout(context.Background(), DefaultTimeout)
-       dr, err := collection.DeleteOne(ctx, bson.M{"_id": hex})
-       if err != nil {
-               openlogging.Error(fmt.Sprintf("delete [%s] failed: %s", hex, 
err))
-       }
-       if dr.DeletedCount != 1 {
-               openlogging.Warn(fmt.Sprintf("delete [%s], but it is not 
exist", hex))
-       }
-       return nil
-}
-
-//Delete remove a list of key values for a tenant
+//Delete delete kv,If the labelID is "", query the collection kv to get it
 //domain=tenant
-func (s *MongodbService) Delete(ids []string, domain string) error {
-       if len(ids) == 0 {
-               openlogging.Warn("delete error,ids is blank")
-               return nil
-       }
+//1.delete kv;2.add history
+func (s *MongodbService) Delete(kvID string, labelID string, domain string) 
error {
+       ctx, _ := context.WithTimeout(context.Background(), DefaultTimeout)
        if domain == "" {
                return ErrMissingDomain
        }
-       collection := s.c.Database(DB).Collection(CollectionKV)
-       //transfer id
-       var oid []primitive.ObjectID
-       for _, v := range ids {
-               if v == "" {
-                       openlogging.Warn("ids contains continuous ','")
-                       continue
-               }
-               hex, err := primitive.ObjectIDFromHex(v)
+       hex, err := primitive.ObjectIDFromHex(kvID)
+       if err != nil {
+               return err
+       }
+       //if labelID == "",get labelID by kvID
+       var kv *model.KVDoc
+       if labelID == "" {
+               kvArray, err := s.findOneKey(ctx, bson.M{"_id": hex})
                if err != nil {
-                       openlogging.Error(fmt.Sprintf("convert %s ,err:%s", v, 
err))
                        return err
                }
-               oid = append(oid, hex)
+               if len(kvArray) > 0 {
+                       kv = kvArray[0]
+                       labelID = kv.LabelID
+               }
        }
-       //use in filter
-       filter := &bson.M{"_id": &bson.M{"$in": oid}, "domain": domain}
-       ctx, _ := context.WithTimeout(context.Background(), DefaultTimeout)
-       dr, err := collection.DeleteMany(ctx, filter)
-       //check error and delete number
+       //get Label and check labelID
+       r, err := s.getLatestLabel(ctx, labelID)
+       if err != nil {
+               if err == ErrRevisionNotExist {
+                       openlogging.Warn(fmt.Sprintf("failed,kvID and labelID 
do not match"))
+                       return ErrKvIDAndLabelIDNotMatch
+               }
+               return err
+       }
+       //delete kv
+       err = s.DeleteKV(ctx, hex)
        if err != nil {
-               openlogging.Error(fmt.Sprintf("delete [%v] failed : [%s]", 
filter, err))
                return err
        }
-       if dr.DeletedCount != int64(len(oid)) {
-               openlogging.Warn(fmt.Sprintf(" The actual number of 
deletions[%d] is not equal to the parameters[%d].", dr.DeletedCount, len(oid)))
+       //Labels will not be empty when deleted
+       revision, err := s.addHistory(ctx, r, labelID)
+       if err != nil {
+               openlogging.Warn("add history failed ,", 
openlogging.WithTags(openlogging.Tags{
+                       "kvID":    kvID,
+                       "labelID": labelID,
+                       "error":   err.Error(),
+               }))
        } else {
-               openlogging.Info(fmt.Sprintf("delete success,count=%d", 
dr.DeletedCount))
+               openlogging.Info("add history success,", 
openlogging.WithTags(openlogging.Tags{
+                       "kvID":     kvID,
+                       "labelID":  labelID,
+                       "revision": revision,
+               }))
        }
        return nil
 }
diff --git a/server/dao/kv.go b/server/dao/kv.go
index 41aba48..e3dcad1 100644
--- a/server/dao/kv.go
+++ b/server/dao/kv.go
@@ -34,12 +34,14 @@ import (
 
 //db errors
 var (
-       ErrMissingDomain    = errors.New("domain info missing, illegal access")
-       ErrKeyNotExists     = errors.New("key with labels does not exits")
-       ErrLabelNotExists   = errors.New("labels does not exits")
-       ErrTooMany          = errors.New("key with labels should be only one")
-       ErrKeyMustNotEmpty  = errors.New("must supply key if you want to get 
exact one result")
-       ErrRevisionNotExist = errors.New("label revision not exist")
+       ErrMissingDomain          = errors.New("domain info missing, illegal 
access")
+       ErrKeyNotExists           = errors.New("key with labels does not exits")
+       ErrLabelNotExists         = errors.New("labels does not exits")
+       ErrTooMany                = errors.New("key with labels should be only 
one")
+       ErrKeyMustNotEmpty        = errors.New("must supply key if you want to 
get exact one result")
+       ErrRevisionNotExist       = errors.New("label revision not exist")
+       ErrKVIDIsNil              = errors.New("kvID id is nil")
+       ErrKvIDAndLabelIDNotMatch = errors.New("kvID and labelID do not match")
 )
 
 //Options mongodb options
@@ -64,9 +66,8 @@ func NewKVService() (*MongodbService, error) {
        }
        return NewMongoService(opts)
 }
-func (s *MongodbService) findOneKey(ctx context.Context, filter bson.M, key 
string) ([]*model.KVDoc, error) {
+func (s *MongodbService) findOneKey(ctx context.Context, filter bson.M) 
([]*model.KVDoc, error) {
        collection := s.c.Database(DB).Collection(CollectionKV)
-       filter["key"] = key
        sr := collection.FindOne(ctx, filter)
        if sr.Err() != nil {
                return nil, sr.Err()
@@ -128,3 +129,20 @@ func (s *MongodbService) findKV(ctx context.Context, 
domain string, opts FindOpt
        }
        return cur, err
 }
+
+//DeleteKV by kvID
+func (s *MongodbService) DeleteKV(ctx context.Context, hexID 
primitive.ObjectID) error {
+       collection := s.c.Database(DB).Collection(CollectionKV)
+       dr, err := collection.DeleteOne(ctx, bson.M{"_id": hexID})
+       //check error and delete number
+       if err != nil {
+               openlogging.Error(fmt.Sprintf("delete [%s] failed : [%s]", 
hexID, err))
+               return err
+       }
+       if dr.DeletedCount != 1 {
+               openlogging.Warn(fmt.Sprintf("Failed,May have been 
deleted,kvID=%s", hexID))
+       } else {
+               openlogging.Info(fmt.Sprintf("delete success,kvID=%s", hexID))
+       }
+       return err
+}
diff --git a/server/dao/kv_test.go b/server/dao/kv_test.go
index db92857..0de63a3 100644
--- a/server/dao/kv_test.go
+++ b/server/dao/kv_test.go
@@ -197,7 +197,7 @@ var _ = Describe("Kv mongodb service", func() {
        })
 
        Describe("delete key", func() {
-               Context("delete key by id,seperated by ',' ", func() {
+               Context("delete key by kvID", func() {
                        kv1, err := s.CreateOrUpdate(context.Background(), 
"default", &model.KVDoc{
                                Key:   "timeout",
                                Value: "20s",
@@ -208,11 +208,20 @@ var _ = Describe("Kv mongodb service", func() {
                        It("should not return err", func() {
                                Expect(err).Should(BeNil())
                        })
+                       It("should not return err", func() {
+                               Expect(err).Should(BeNil())
+                       })
 
-                       kv2, err := s.CreateOrUpdate(context.Background(), 
"default", &model.KVDoc{
-                               Key:    "times",
-                               Value:  "3",
-                               Domain: "default",
+                       err = s.Delete(kv1.ID.Hex(), "", "default")
+                       It("should not return err", func() {
+                               Expect(err).Should(BeNil())
+                       })
+
+               })
+               Context("delete key by kvID and labelID", func() {
+                       kv1, err := s.CreateOrUpdate(context.Background(), 
"default", &model.KVDoc{
+                               Key:   "timeout",
+                               Value: "20s",
                                Labels: map[string]string{
                                        "env": "test",
                                },
@@ -220,28 +229,30 @@ var _ = Describe("Kv mongodb service", func() {
                        It("should not return err", func() {
                                Expect(err).Should(BeNil())
                        })
+                       It("should not return err", func() {
+                               Expect(err).Should(BeNil())
+                       })
 
-                       ids := []string{kv1.ID.Hex(), kv2.ID.Hex()}
-                       err = s.Delete(ids, "default")
+                       err = s.Delete(kv1.ID.Hex(), kv1.LabelID, "default")
                        It("should not return err", func() {
                                Expect(err).Should(BeNil())
                        })
 
                })
-               Context("test miss ids, no panic", func() {
-                       err := s.Delete(nil, "default")
+               Context("test miss kvID, no panic", func() {
+                       err := s.Delete("", "", "default")
                        It("should not return err", func() {
-                               Expect(err).Should(BeNil())
+                               Expect(err).Should(HaveOccurred())
                        })
                })
                Context("Test encode error ", func() {
-                       err := s.Delete([]string{"12312312321"}, "default")
+                       err := s.Delete("12312312321", "", "default")
                        It("should return err", func() {
                                Expect(err).To(HaveOccurred())
                        })
                })
                Context("Test miss domain error ", func() {
-                       err := s.Delete([]string{"5ce3602381fc6e33708b9621"}, 
"")
+                       err := s.Delete("12312312321", "", "")
                        It("should return err", func() {
                                Expect(err).Should(Equal(dao.ErrMissingDomain))
                        })
diff --git a/server/dao/label_history.go b/server/dao/label_history.go
index a3809d6..c796e7b 100644
--- a/server/dao/label_history.go
+++ b/server/dao/label_history.go
@@ -19,7 +19,6 @@ package dao
 
 import (
        "context"
-
        "fmt"
        "github.com/apache/servicecomb-kie/pkg/model"
        "github.com/go-mesh/openlogging"
@@ -57,8 +56,8 @@ func (s *MongodbService) getLatestLabel(ctx context.Context, 
labelID string) (*m
        return h, nil
 }
 
-//AddHistory get latest labels revision and plus 1  and save current label 
stats to history, then update current revision to db
-func (s *MongodbService) AddHistory(ctx context.Context, labelID string, 
labels map[string]string, domain string) (int, error) {
+//getAndAddHistory get latest labels revision and call addHistory
+func (s *MongodbService) getAndAddHistory(ctx context.Context, labelID string, 
labels map[string]string, domain string) (int, error) {
        r, err := s.getLatestLabel(ctx, labelID)
        if err != nil {
                if err == ErrRevisionNotExist {
@@ -76,23 +75,31 @@ func (s *MongodbService) AddHistory(ctx context.Context, 
labelID string, labels
                }
 
        }
-       r.Revision = r.Revision + 1
+       r.Revision, err = s.addHistory(ctx, r, labelID)
+       if err != nil {
+               return 0, err
+       }
+       return r.Revision, nil
+}
 
+//addHistory labels revision plus 1 and save current label stats to history, 
then update current revision to db
+func (s *MongodbService) addHistory(ctx context.Context, labelRevision 
*model.LabelRevisionDoc, labelID string) (int, error) {
+       labelRevision.Revision = labelRevision.Revision + 1
        kvs, err := s.findKeys(ctx, bson.M{"label_id": labelID}, true)
-       if err != nil {
+       //Key may be empty When delete
+       if err != nil && err != ErrKeyNotExists {
                return 0, err
        }
        //save current kv states
-       r.KVs = kvs
+       labelRevision.KVs = kvs
        //clear prev id
-       r.ID = primitive.NilObjectID
+       labelRevision.ID = primitive.NilObjectID
        collection := s.c.Database(DB).Collection(CollectionLabelRevision)
-       _, err = collection.InsertOne(ctx, r)
+       _, 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))
@@ -101,13 +108,12 @@ func (s *MongodbService) AddHistory(ctx context.Context, 
labelID string, labels
        labelCollection := s.c.Database(DB).Collection(CollectionLabel)
        _, err = labelCollection.UpdateOne(ctx, bson.M{"_id": hex}, bson.D{
                {"$set", bson.D{
-                       {"revision", r.Revision},
+                       {"revision", labelRevision.Revision},
                }},
        })
        if err != nil {
                return 0, err
        }
-       openlogging.Debug(fmt.Sprintf("update revision to %d", r.Revision))
-
-       return r.Revision, nil
+       openlogging.Debug(fmt.Sprintf("update revision to %d", 
labelRevision.Revision))
+       return labelRevision.Revision, nil
 }
diff --git a/server/dao/mongodb_operator.go b/server/dao/mongodb_operator.go
index ce672d1..e588f5a 100644
--- a/server/dao/mongodb_operator.go
+++ b/server/dao/mongodb_operator.go
@@ -52,7 +52,7 @@ func (s *MongodbService) createKey(ctx context.Context, kv 
*model.KVDoc) (*model
        }
        objectID, _ := res.InsertedID.(primitive.ObjectID)
        kv.ID = objectID
-       revision, err := s.AddHistory(ctx, kv.LabelID, kv.Labels, kv.Domain)
+       revision, err := s.getAndAddHistory(ctx, kv.LabelID, kv.Labels, 
kv.Domain)
        if err != nil {
                openlogging.Warn(
                        fmt.Sprintf("can not updateKey version for [%s] [%s] in 
[%s]",
@@ -81,7 +81,7 @@ func (s *MongodbService) updateKey(ctx context.Context, kv 
*model.KVDoc) (int, e
        openlogging.Debug(
                fmt.Sprintf("updateKey %s with labels %s value [%s] %d ",
                        kv.Key, kv.Labels, kv.Value, ur.ModifiedCount))
-       revision, err := s.AddHistory(ctx, kv.LabelID, kv.Labels, kv.Domain)
+       revision, err := s.getAndAddHistory(ctx, kv.LabelID, kv.Labels, 
kv.Domain)
        if err != nil {
                openlogging.Warn(
                        fmt.Sprintf("can not label revision for [%s] [%s] in 
[%s],err: %s",
diff --git a/server/resource/v1/common.go b/server/resource/v1/common.go
index 9b01260..f96c11c 100644
--- a/server/resource/v1/common.go
+++ b/server/resource/v1/common.go
@@ -35,8 +35,8 @@ const (
        MsgDomainMustNotBeEmpty = "domain must not be empty"
        MsgIllegalLabels        = "label's value can not be empty, " +
                "label can not be duplicated, please check your query 
parameters"
-       MsgIllegalDepth   = "X-Depth must be number"
-       ErrIDMustNotEmpty = "must supply id if you want to remove key"
+       MsgIllegalDepth     = "X-Depth must be number"
+       ErrKvIDMustNotEmpty = "must supply kv id if you want to remove key"
 )
 
 //ReadDomain get domain info from attribute
diff --git a/server/resource/v1/doc_struct.go b/server/resource/v1/doc_struct.go
index 33f0eb7..d39fc7e 100644
--- a/server/resource/v1/doc_struct.go
+++ b/server/resource/v1/doc_struct.go
@@ -44,6 +44,11 @@ var (
                Name:      "key",
                ParamType: goRestful.PathParameterKind,
        }
+       labelIDParameters = &restful.Parameters{
+               DataType:  "string",
+               Name:      "key",
+               ParamType: goRestful.PathParameterKind,
+       }
 )
 
 //KVBody is open api doc
diff --git a/server/resource/v1/kv_resource.go 
b/server/resource/v1/kv_resource.go
index 832dae7..d8b2d50 100644
--- a/server/resource/v1/kv_resource.go
+++ b/server/resource/v1/kv_resource.go
@@ -20,14 +20,12 @@ package v1
 
 import (
        "encoding/json"
-       "fmt"
        "github.com/apache/servicecomb-kie/pkg/model"
        "github.com/apache/servicecomb-kie/server/dao"
        goRestful "github.com/emicklei/go-restful"
        "github.com/go-chassis/go-chassis/server/restful"
        "github.com/go-mesh/openlogging"
        "net/http"
-       "strings"
 )
 
 //KVResource has API about kv operations
@@ -163,20 +161,24 @@ func (r *KVResource) Delete(context *restful.Context) {
        if domain == nil {
                WriteErrResponse(context, http.StatusInternalServerError, 
MsgDomainMustNotBeEmpty)
        }
-       ids := context.ReadPathParameter("ids")
-       if ids == "" {
-               WriteErrResponse(context, http.StatusBadRequest, 
ErrIDMustNotEmpty)
+       kvID := context.ReadPathParameter("kvID")
+       if kvID == "" {
+               WriteErrResponse(context, http.StatusBadRequest, 
ErrKvIDMustNotEmpty)
                return
        }
-       idArray := strings.Split(ids, ",")
+       labelID := context.ReadQueryParameter("labelID")
        s, err := dao.NewKVService()
        if err != nil {
                WriteErrResponse(context, http.StatusInternalServerError, 
err.Error())
                return
        }
-       err = s.Delete(idArray, domain.(string))
+       err = s.Delete(kvID, labelID, domain.(string))
        if err != nil {
-               openlogging.Error(fmt.Sprintf("delete ids=%s,err=%s", ids, 
err.Error()))
+               openlogging.Error("delete failed ,", 
openlogging.WithTags(openlogging.Tags{
+                       "kvID":    kvID,
+                       "labelID": labelID,
+                       "error":   err.Error(),
+               }))
                WriteErrResponse(context, http.StatusInternalServerError, 
err.Error())
                return
        }
@@ -245,16 +247,12 @@ func (r *KVResource) URLPatterns() []restful.Route {
                        Produces: []string{goRestful.MIME_JSON},
                }, {
                        Method:           http.MethodDelete,
-                       Path:             "/v1/kv/{ids}",
+                       Path:             "/v1/kv/{kvID}",
                        ResourceFuncName: "Delete",
-                       FuncDesc:         "delete key by id,separated by ','",
-                       Parameters: []*restful.Parameters{{
-                               DataType:  "string",
-                               Name:      "ids",
-                               ParamType: goRestful.PathParameterKind,
-                               Desc: "The id strings to be removed are 
separated by ',',If the actual number of deletions " +
-                                       "and the number of parameters are not 
equal, no error will be returned and only warn log will be printed.",
-                       },
+                       FuncDesc: "Delete key by kvID and labelID,If the 
labelID is nil, query the collection kv to get it." +
+                               "It means if only get kvID, it can also delete 
normally.But if you want better performance, you need to pass the labelID",
+                       Parameters: []*restful.Parameters{
+                               labelIDParameters,
                        },
                        Returns: []*restful.Returns{
                                {

Reply via email to