This is an automated email from the ASF dual-hosted git repository. asifdxtreme pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/servicecomb-kie.git
commit 49d238a4c3977fbf897fccdcdbfafa62bc9b1282 Author: wangqijun <wangqj2...@sohu.com> AuthorDate: Fri May 24 22:18:57 2019 +0800 add delete by id string --- server/dao/kv.go | 7 +++-- server/dao/kv_test.go | 53 ++++++++++++++++++++++++++++++++++++ server/dao/mongodb.go | 38 +++++++++++++++++++++++++- server/resource/v1/common.go | 5 +++- server/resource/v1/kv_resource.go | 57 ++++++++++++++++++++++++++++++++++++++- 5 files changed, 153 insertions(+), 7 deletions(-) diff --git a/server/dao/kv.go b/server/dao/kv.go index de32cc3..9cf40fe 100644 --- a/server/dao/kv.go +++ b/server/dao/kv.go @@ -21,9 +21,9 @@ package dao import ( "crypto/tls" "errors" - "time" - "github.com/apache/servicecomb-kie/server/config" "github.com/apache/servicecomb-kie/pkg/model" + "github.com/apache/servicecomb-kie/server/config" + "time" ) var ErrMissingDomain = errors.New("domain info missing, illegal access") @@ -35,8 +35,7 @@ type KV interface { CreateOrUpdate(kv *model.KV) (*model.KV, error) //do not use primitive.ObjectID as return to decouple with mongodb, we can afford perf lost Exist(key, domain string, labels model.Labels) (string, error) - DeleteByID(id string) error - Delete(key, domain string, labels model.Labels) error + Delete(ids []string, domain string) error Find(domain string, options ...FindOption) ([]*model.KV, error) AddHistory(kv *model.KV) error //RollBack(kv *KV, version string) error diff --git a/server/dao/kv_test.go b/server/dao/kv_test.go index 9cb23ad..81bd106 100644 --- a/server/dao/kv_test.go +++ b/server/dao/kv_test.go @@ -189,4 +189,57 @@ var _ = Describe("Kv mongodb service", func() { }) }) + + Describe("delete key", func() { + Context("delete key by id,seperated by ',' ", func() { + kv1, err := s.CreateOrUpdate(&model.KV{ + Key: "timeout", + Value: "20s", + Domain: "default", + Labels: map[string]string{ + "env": "test", + }, + }) + It("should not return err", func() { + Expect(err).Should(BeNil()) + }) + + kv2, err := s.CreateOrUpdate(&model.KV{ + Key: "times", + Value: "3", + Domain: "default", + Labels: map[string]string{ + "env": "test", + }, + }) + It("should not return err", func() { + Expect(err).Should(BeNil()) + }) + + ids := []string{kv1.ID.Hex(), kv2.ID.Hex()} + err = s.Delete(ids, "default") + It("should not return err", func() { + Expect(err).Should(BeNil()) + }) + + }) + Context("test miss ids, no panic", func() { + err := s.Delete(nil, "default") + It("should not return err", func() { + Expect(err).Should(BeNil()) + }) + }) + Context("Test encode error ", func() { + err := s.Delete([]string{"12312312321"}, "default") + It("should return err", func() { + Expect(err).To(HaveOccurred()) + }) + }) + Context("Test miss domain error ", func() { + err := s.Delete([]string{"5ce3602381fc6e33708b9621"}, "") + It("should return err", func() { + Expect(err).Should(Equal(dao.ErrMissingDomain)) + }) + }) + }) }) diff --git a/server/dao/mongodb.go b/server/dao/mongodb.go index cbaabad..9fc6ad0 100644 --- a/server/dao/mongodb.go +++ b/server/dao/mongodb.go @@ -224,7 +224,43 @@ func (s *MongodbService) DeleteByID(id string) error { return nil } -func (s *MongodbService) Delete(key, domain string, labels model.Labels) error { +func (s *MongodbService) Delete(ids []string, domain string) error { + if len(ids) == 0 { + openlogging.Warn("delete error,ids is blank") + return nil + } + 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) + if err != nil { + openlogging.Error(fmt.Sprintf("convert %s ,err:%s", v, err)) + return err + } + oid = append(oid, hex) + } + //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 + if err != nil { + openlogging.Error(fmt.Sprintf("delete [%s] 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))) + } else { + openlogging.Info(fmt.Sprintf("delete success,count=%d", dr.DeletedCount)) + } return nil } func (s *MongodbService) AddHistory(kv *model.KV) error { diff --git a/server/resource/v1/common.go b/server/resource/v1/common.go index bee9f36..e246602 100644 --- a/server/resource/v1/common.go +++ b/server/resource/v1/common.go @@ -27,10 +27,13 @@ import ( ) const ( + FindExact = "exact" + FindMany = "greedy" MsgDomainMustNotBeEmpty = "domain must not be empty" - MsgIllegalFindPolicy = "value of header "+common.HeaderMatch+" can be greedy or exact" + MsgIllegalFindPolicy = "value of header " + common.HeaderMatch + " can be greedy or exact" MsgIllegalLabels = "label's value can not be empty, " + "label can not be duplicated, please check your query parameters" + ErrIDMustNotEmpty = "must supply id if you want to remove key" ) func ReadDomain(context *restful.Context) interface{} { diff --git a/server/resource/v1/kv_resource.go b/server/resource/v1/kv_resource.go index 0030e7b..4839279 100644 --- a/server/resource/v1/kv_resource.go +++ b/server/resource/v1/kv_resource.go @@ -20,6 +20,7 @@ package v1 import ( "encoding/json" + "fmt" "github.com/apache/servicecomb-kie/pkg/common" "github.com/apache/servicecomb-kie/pkg/model" "github.com/apache/servicecomb-kie/server/dao" @@ -27,6 +28,7 @@ import ( "github.com/go-chassis/go-chassis/server/restful" "github.com/go-mesh/openlogging" "net/http" + "strings" ) type KVResource struct { @@ -159,7 +161,28 @@ func (r *KVResource) FindByLabels(context *restful.Context) { } func (r *KVResource) Delete(context *restful.Context) { - + domain := ReadDomain(context) + if domain == nil { + WriteErrResponse(context, http.StatusInternalServerError, MsgDomainMustNotBeEmpty) + } + ids := context.ReadPathParameter("ids") + if ids == "" { + WriteErrResponse(context, http.StatusBadRequest, ErrIDMustNotEmpty) + return + } + idArray := strings.Split(ids, ",") + s, err := dao.NewKVService() + if err != nil { + WriteErrResponse(context, http.StatusInternalServerError, err.Error()) + return + } + err = s.Delete(idArray, domain.(string)) + if err != nil { + openlogging.Error(fmt.Sprintf("delete ids=%s,err=%s", ids, err.Error())) + WriteErrResponse(context, http.StatusInternalServerError, err.Error()) + return + } + context.WriteHeader(http.StatusNoContent) } //URLPatterns defined config operations @@ -253,6 +276,38 @@ func (r *KVResource) URLPatterns() []restful.Route { }, Consumes: []string{"application/json"}, Produces: []string{"application/json"}, + }, { + Method: http.MethodDelete, + Path: "/v1/kv/{ids}", + ResourceFuncName: "Delete", + FuncDesc: "delete key by id,seperated by ','", + Parameters: []*restful.Parameters{ + { + DataType: "string", + Name: "X-Domain-Name", + ParamType: goRestful.HeaderParameterKind, + }, { + 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.", + }, + }, + Returns: []*restful.Returns{ + { + Code: http.StatusNoContent, + Message: "Delete success", + }, + { + Code: http.StatusBadRequest, + Message: "Failed,check url", + }, + { + Code: http.StatusInternalServerError, + Message: "Server error", + }, + }, }, } }