You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ni...@apache.org on 2019/05/27 01:51:00 UTC
[servicecomb-kie] 01/02: add delete by id string
This is an automated email from the ASF dual-hosted git repository.
ningjiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-kie.git
commit 49d238a4c3977fbf897fccdcdbfafa62bc9b1282
Author: wangqijun <wa...@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",
+ },
+ },
},
}
}