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 50c787f  Use foundation/validator instead (#184)
50c787f is described below

commit 50c787fe1dbb6917c3c95497c5a0b15f25a19d0f
Author: little-cui <sure_0...@qq.com>
AuthorDate: Thu Jun 3 20:06:35 2021 +0800

    Use foundation/validator instead (#184)
---
 go.mod                                 |   7 +-
 go.sum                                 |  10 ++
 pkg/model/db_schema.go                 |  26 ++---
 pkg/validate/instance.go               |  49 ----------
 pkg/validate/instance_test.go          | 125 ------------------------
 pkg/validate/rule.go                   |  90 -----------------
 pkg/validate/rule_test.go              |  39 --------
 pkg/validate/validator.go              |  87 -----------------
 pkg/validate/validator_test.go         |  36 -------
 pkg/validator/rule.go                  |  46 +++++++++
 pkg/validator/rule_test.go             | 173 +++++++++++++++++++++++++++++++++
 server/resource/v1/kv_resource.go      |  10 +-
 server/resource/v1/kv_resource_test.go |   4 -
 server/server.go                       |   4 +-
 test/init.go                           |   2 +
 15 files changed, 253 insertions(+), 455 deletions(-)

diff --git a/go.mod b/go.mod
index b10cd0d..539d13b 100644
--- a/go.mod
+++ b/go.mod
@@ -2,16 +2,13 @@ module github.com/apache/servicecomb-kie
 
 require (
        github.com/emicklei/go-restful v2.12.0+incompatible
-       github.com/go-chassis/cari v0.2.0
+       github.com/go-chassis/cari v0.4.1-0.20210528013912-6da8395f7ff9
+       github.com/go-chassis/foundation v0.3.1-0.20210602072914-a580bed505d0
        github.com/go-chassis/go-archaius v1.5.2-0.20210301074935-e4694f6b077b
        github.com/go-chassis/go-chassis/v2 v2.1.2-0.20210308033545-985e98e20637
        github.com/go-chassis/openlog v1.1.2
        github.com/go-chassis/seclog v1.3.0
-       github.com/go-playground/universal-translator v0.17.0
-       github.com/go-playground/validator v9.31.0+incompatible
        github.com/hashicorp/serf v0.9.5
-       github.com/leodido/go-urn v1.2.1 // indirect
-       github.com/mitchellh/mapstructure v1.3.3 // indirect
        github.com/satori/go.uuid v1.2.0
        github.com/stretchr/testify v1.6.1
        github.com/urfave/cli v1.22.4
diff --git a/go.sum b/go.sum
index e61b066..f0e08bd 100644
--- a/go.sum
+++ b/go.sum
@@ -120,10 +120,16 @@ github.com/go-chassis/cari 
v0.0.2-0.20210208095358-3bccdf2ce456 h1:n81PUcR0Qrapi
 github.com/go-chassis/cari v0.0.2-0.20210208095358-3bccdf2ce456/go.mod 
h1:MgtsEI0AM4Ush6Lyw27z9Gk4nQ/8GWTSXrFzupawWDM=
 github.com/go-chassis/cari v0.2.0 
h1:29Rsisbq/bKc79OCZdD2TU0aGr8UBH/i0fjUniMh0+Q=
 github.com/go-chassis/cari v0.2.0/go.mod 
h1:Ie2lW11Y5ZFClY9z7bhAwK6BoNxqGSf3fYGs4mPFs74=
+github.com/go-chassis/cari v0.4.0 
h1:2rJ7pB4dfZIu5/HQwwJhmybC1n/0MXWkKieoHCu4tQc=
+github.com/go-chassis/cari v0.4.0/go.mod 
h1:av/19fqwEP4eOC8unL/z67AAbFDwXUCko6SKa4Avrd8=
+github.com/go-chassis/cari v0.4.1-0.20210528013912-6da8395f7ff9 
h1:UxNOY1mnK7i9qRYeu0d2jsVItfoV0ga75RF6isOhn00=
+github.com/go-chassis/cari v0.4.1-0.20210528013912-6da8395f7ff9/go.mod 
h1:av/19fqwEP4eOC8unL/z67AAbFDwXUCko6SKa4Avrd8=
 github.com/go-chassis/foundation v0.2.2-0.20201210043510-9f6d3de40234/go.mod 
h1:2PjwqpVwYEVaAldl5A58a08viH8p27pNeYaiE3ZxOBA=
 github.com/go-chassis/foundation v0.2.2/go.mod 
h1:2PjwqpVwYEVaAldl5A58a08viH8p27pNeYaiE3ZxOBA=
 github.com/go-chassis/foundation v0.3.0 
h1:jG4BIrK8fXD9jbTtJ5rOLGQZ1pQI/mLnDuVJzToCtos=
 github.com/go-chassis/foundation v0.3.0/go.mod 
h1:2PjwqpVwYEVaAldl5A58a08viH8p27pNeYaiE3ZxOBA=
+github.com/go-chassis/foundation v0.3.1-0.20210602072914-a580bed505d0 
h1:bWvRZc0/sxPjzOBB4DTjxcFjpoy3MdSt5fbIimx2FtE=
+github.com/go-chassis/foundation v0.3.1-0.20210602072914-a580bed505d0/go.mod 
h1:6NsIUaHghTFRGfCBcZN011zl196F6OR5QvD9N+P4oWU=
 github.com/go-chassis/go-archaius v1.3.6-0.20201210061741-7450779aaeb8/go.mod 
h1:j8vJX5c455N0cN5rzeC1dm9T5kyOI8ZvIjaSJ+rZjwc=
 github.com/go-chassis/go-archaius v1.4.0/go.mod 
h1:j8vJX5c455N0cN5rzeC1dm9T5kyOI8ZvIjaSJ+rZjwc=
 github.com/go-chassis/go-archaius v1.5.0/go.mod 
h1:QPwvvtBxvwiC48rmydoAqxopqOr93RCQ6syWsIkXPXQ=
@@ -341,6 +347,9 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod 
h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
 github.com/julienschmidt/httprouter v1.2.0 
h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g=
 github.com/julienschmidt/httprouter v1.2.0/go.mod 
h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
 github.com/karlseguin/ccache 
v2.0.3-0.20170217060820-3ba9789cfd2c+incompatible/go.mod 
h1:CM9tNPzT6EdRh14+jiW8mEF9mkNZuuE51qmgGYUB93w=
+github.com/karlseguin/ccache/v2 v2.0.8 
h1:lT38cE//uyf6KcFok0rlgXtGFBWxkI6h/qg4tbFyDnA=
+github.com/karlseguin/ccache/v2 v2.0.8/go.mod 
h1:2BDThcfQMf/c0jnZowt16eW405XIqZPavt+HoYEtcxQ=
+github.com/karlseguin/expect v1.0.2-0.20190806010014-778a5f0c6003/go.mod 
h1:zNBxMY8P21owkeogJELCLeHIt+voOSduHYTFUbwRAV8=
 github.com/karlseguin/expect v1.0.7/go.mod 
h1:lXdI8iGiQhmzpnnmU/EGA60vqKs8NbRNFnhhrJGoD5g=
 github.com/karrick/godirwalk v1.8.0/go.mod 
h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
 github.com/karrick/godirwalk v1.10.3 
h1:lOpSw2vJP0y5eLBW906QwKsUK/fe/QDyoqM5rnnuPDY=
@@ -402,6 +411,7 @@ github.com/miekg/dns v1.1.26/go.mod 
h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKju
 github.com/mitchellh/cli v1.0.0/go.mod 
h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
 github.com/mitchellh/cli v1.1.0 h1:tEElEatulEHDeedTxwckzyYMA5c86fbmNIUL1hBIiTg=
 github.com/mitchellh/cli v1.1.0/go.mod 
h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
+github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee 
h1:kK7VuFVykgt0LfMSloWYjDOt4TnOcL0AxF0/rDq2VkM=
 github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod 
h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/mapstructure v1.3.3 
h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
 github.com/mitchellh/mapstructure v1.3.3/go.mod 
h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
diff --git a/pkg/model/db_schema.go b/pkg/model/db_schema.go
index 8875c24..5583df7 100644
--- a/pkg/model/db_schema.go
+++ b/pkg/model/db_schema.go
@@ -33,19 +33,19 @@ type LabelDoc struct {
 type KVDoc struct {
        ID             string `json:"id,omitempty" bson:"id,omitempty" 
yaml:"id,omitempty" swag:"string"`
        LabelFormat    string `json:"label_format,omitempty" 
bson:"label_format,omitempty" yaml:"label_format,omitempty"`
-       Key            string `json:"key" yaml:"key" validate:"key"`
-       Value          string `json:"value" yaml:"value" validate:"value"`
+       Key            string `json:"key" yaml:"key" 
validate:"min=1,max=128,key"`
+       Value          string `json:"value" yaml:"value" 
validate:"max=2097152,value"`
        ValueType      string `json:"value_type,omitempty" 
bson:"value_type,omitempty" yaml:"value_type,omitempty" validate:"valueType"` 
//ini,json,text,yaml,properties
-       Checker        string `json:"check,omitempty" yaml:"check,omitempty" 
validate:"check"`                                           //python script
+       Checker        string `json:"check,omitempty" yaml:"check,omitempty" 
validate:"max=1048576,check"`                               //python script
        CreateRevision int64  `json:"create_revision,omitempty" 
bson:"create_revision," yaml:"create_revision,omitempty"`
        UpdateRevision int64  `json:"update_revision,omitempty" 
bson:"update_revision," yaml:"update_revision,omitempty"`
-       Project        string `json:"project,omitempty" 
yaml:"project,omitempty" validate:"commonName"`
+       Project        string `json:"project,omitempty" 
yaml:"project,omitempty" validate:"min=1,max=256,commonName"`
        Status         string `json:"status,omitempty" yaml:"status,omitempty" 
validate:"kvStatus"`
        CreateTime     int64  `json:"create_time,omitempty" bson:"create_time," 
yaml:"create_time,omitempty"`
        UpdateTime     int64  `json:"update_time,omitempty" bson:"update_time," 
yaml:"update_time,omitempty"`
 
        Labels map[string]string `json:"labels,omitempty" 
yaml:"labels,omitempty" validate:"max=6,dive,keys,labelKV,endkeys,labelKV"` 
//redundant
-       Domain string            `json:"domain,omitempty" 
yaml:"domain,omitempty" validate:"commonName"`                              
//redundant
+       Domain string            `json:"domain,omitempty" 
yaml:"domain,omitempty" validate:"min=1,max=256,commonName"`                
//redundant
 }
 
 //ViewDoc is db struct, it saves user's custom view name and criteria
@@ -76,24 +76,24 @@ type PollingDetail struct {
 // UpdateKVRequest is db struct, it contains kv update request params
 type UpdateKVRequest struct {
        ID      string `json:"id,omitempty" bson:"id,omitempty" 
yaml:"id,omitempty" swag:"string" validate:"uuid"`
-       Value   string `json:"value,omitempty" yaml:"value,omitempty" 
validate:"value"`
-       Project string `json:"project,omitempty" yaml:"project,omitempty" 
validate:"commonName"`
-       Domain  string `json:"domain,omitempty" yaml:"domain,omitempty" 
validate:"commonName"` //redundant
+       Value   string `json:"value,omitempty" yaml:"value,omitempty" 
validate:"max=2097152,value"`
+       Project string `json:"project,omitempty" yaml:"project,omitempty" 
validate:"min=1,max=256,commonName"`
+       Domain  string `json:"domain,omitempty" yaml:"domain,omitempty" 
validate:"min=1,max=256,commonName"` //redundant
        Status  string `json:"status,omitempty" yaml:"status,omitempty" 
validate:"kvStatus"`
 }
 
 // GetKVRequest contains kv get request params
 type GetKVRequest struct {
-       Project string `json:"project,omitempty" yaml:"project,omitempty" 
validate:"commonName"`
-       Domain  string `json:"domain,omitempty" yaml:"domain,omitempty" 
validate:"commonName"` //redundant
+       Project string `json:"project,omitempty" yaml:"project,omitempty" 
validate:"min=1,max=256,commonName"`
+       Domain  string `json:"domain,omitempty" yaml:"domain,omitempty" 
validate:"min=1,max=256,commonName"` //redundant
        ID      string `json:"id,omitempty" bson:"id,omitempty" 
yaml:"id,omitempty" swag:"string" validate:"uuid"`
 }
 
 // ListKVRequest contains kv list request params
 type ListKVRequest struct {
-       Project string            `json:"project,omitempty" 
yaml:"project,omitempty" validate:"commonName"`
-       Domain  string            `json:"domain,omitempty" 
yaml:"domain,omitempty" validate:"commonName"` //redundant
-       Key     string            `json:"key" yaml:"key" validate:"getKey"`
+       Project string            `json:"project,omitempty" 
yaml:"project,omitempty" validate:"min=1,max=256,commonName"`
+       Domain  string            `json:"domain,omitempty" 
yaml:"domain,omitempty" validate:"min=1,max=256,commonName"` //redundant
+       Key     string            `json:"key" yaml:"key" 
validate:"max=128,getKey"`
        Labels  map[string]string `json:"labels,omitempty" 
yaml:"labels,omitempty" validate:"max=8,dive,keys,labelKV,endkeys,labelKV"` 
//redundant
        Offset  int64             `validate:"min=0"`
        Limit   int64             `validate:"min=0,max=100"`
diff --git a/pkg/validate/instance.go b/pkg/validate/instance.go
deleted file mode 100644
index fe1c2ab..0000000
--- a/pkg/validate/instance.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package validate
-
-var defaultValidator = NewValidator()
-
-const (
-       key                   = "key"
-       commonNameRegexString = 
`^[a-zA-Z0-9]*$|^[a-zA-Z0-9][a-zA-Z0-9_\-.]*[a-zA-Z0-9]$`
-       getKeyRegexString     = 
`^[a-zA-Z0-9]*$|^[a-zA-Z0-9][a-zA-Z0-9_\-.]*[a-zA-Z0-9]$|^beginWith\([a-zA-Z0-9][a-zA-Z0-9_\-.]*\)$|^wildcard\([a-zA-Z0-9][a-zA-Z0-9_\-.*]*\)$`
-       asciiRegexString      = `^[\x00-\x7F]*$`
-       allCharString         = `.*`
-)
-
-// custom validate rules
-// please use different tag names from third party tags
-var customRules = []*RegexValidateRule{
-       NewRule(key, commonNameRegexString, &Option{Min: 1, Max: 128}),
-       NewRule("getKey", getKeyRegexString, &Option{Max: 128}),
-       NewRule("commonName", commonNameRegexString, &Option{Min: 1, Max: 256}),
-       NewRule("valueType", `^$|^(ini|json|text|yaml|properties)$`, nil),
-       NewRule("kvStatus", `^$|^(enabled|disabled)$`, nil),
-       NewRule("value", allCharString, &Option{Max: 2097152}), //ASCII, 2M
-       NewRule("labelKV", commonNameRegexString, &Option{Max: 32}),
-       NewRule("check", asciiRegexString, &Option{Max: 1048576}), //ASCII, 1M
-}
-
-// tags of third party validate rules we used, for error translation
-var thirdPartyTags = []string{
-       "min", "max", "length", "uuid",
-}
-
-// Init initializes validate
-func Init() error {
-       for _, r := range customRules {
-               if err := defaultValidator.RegisterRule(r); err != nil {
-                       return err
-               }
-       }
-       for _, t := range thirdPartyTags {
-               if err := defaultValidator.AddErrorTranslation4Tag(t); err != 
nil {
-                       return err
-               }
-       }
-       return nil
-}
-
-// Validate validates data
-func Validate(v interface{}) error {
-       return defaultValidator.Validate(v)
-}
diff --git a/pkg/validate/instance_test.go b/pkg/validate/instance_test.go
deleted file mode 100644
index 0519656..0000000
--- a/pkg/validate/instance_test.go
+++ /dev/null
@@ -1,125 +0,0 @@
-package validate_test
-
-import (
-       "testing"
-
-       "github.com/apache/servicecomb-kie/pkg/model"
-       "github.com/apache/servicecomb-kie/pkg/validate"
-
-       "github.com/stretchr/testify/assert"
-)
-
-func TestValidate(t *testing.T) {
-       string32 := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" //32
-       string128 := string32 + string32 + string32 + string32
-       err := validate.Init()
-       assert.NoError(t, err)
-
-       kvDoc := &model.KVDoc{Project: "a", Domain: "a",
-               Key:   "a",
-               Value: "a",
-       }
-       assert.NoError(t, validate.Validate(kvDoc))
-
-       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
-               Key:   "",
-               Value: "a",
-       }
-       assert.Error(t, validate.Validate(kvDoc))
-
-       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
-               Key:   "a#",
-               Value: "a",
-       }
-       assert.Error(t, validate.Validate(kvDoc))
-
-       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
-               Key:   string128 + "a",
-               Value: "a",
-       }
-       assert.Error(t, validate.Validate(kvDoc))
-
-       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
-               Key:   "a",
-               Value: "",
-       }
-       assert.NoError(t, validate.Validate(kvDoc))
-
-       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
-               Key:       "a",
-               Value:     "a",
-               ValueType: "",
-       }
-       assert.NoError(t, validate.Validate(kvDoc))
-
-       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
-               Key:       "a",
-               Value:     "a",
-               ValueType: "text",
-       }
-       assert.NoError(t, validate.Validate(kvDoc))
-
-       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
-               Key:       "a",
-               Value:     "a",
-               ValueType: "a",
-       }
-       assert.Error(t, validate.Validate(kvDoc))
-
-       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
-               Key:    "a",
-               Value:  "a",
-               Status: "",
-       }
-       assert.NoError(t, validate.Validate(kvDoc))
-
-       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
-               Key:    "a",
-               Value:  "a",
-               Status: "enabled",
-       }
-       assert.NoError(t, validate.Validate(kvDoc))
-
-       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
-               Key:    "a",
-               Value:  "a",
-               Status: "a",
-       }
-       assert.Error(t, validate.Validate(kvDoc))
-
-       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
-               Key:    "a",
-               Value:  "a",
-               Labels: nil,
-       }
-       assert.NoError(t, validate.Validate(kvDoc))
-
-       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
-               Key:    "a",
-               Value:  "a",
-               Labels: map[string]string{"a": "a"},
-       }
-       assert.NoError(t, validate.Validate(kvDoc))
-
-       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
-               Key:    "a",
-               Value:  "a",
-               Labels: map[string]string{string32 + "a": "a"},
-       }
-       assert.Error(t, validate.Validate(kvDoc))
-
-       ListKVRe := &model.ListKVRequest{Project: "a", Domain: "a",
-               Key: "beginWith(a)",
-       }
-       assert.NoError(t, validate.Validate(ListKVRe))
-
-       ListKVRe = &model.ListKVRequest{Project: "a", Domain: "a",
-               Key: "beginW(a)",
-       }
-       assert.Error(t, validate.Validate(ListKVRe))
-
-       ListKVRe = &model.ListKVRequest{Project: "a", Domain: "a",
-               Key: "beginW()",
-       }
-       assert.Error(t, validate.Validate(ListKVRe))
-}
diff --git a/pkg/validate/rule.go b/pkg/validate/rule.go
deleted file mode 100644
index 3fb9560..0000000
--- a/pkg/validate/rule.go
+++ /dev/null
@@ -1,90 +0,0 @@
-package validate
-
-import (
-       "fmt"
-       "regexp"
-       "unicode/utf8"
-
-       "github.com/go-playground/validator"
-)
-
-// RegexValidateRule contains an validate tag's info
-type RegexValidateRule struct {
-       tag           string
-       min           int64
-       max           int64
-       regex         *regexp.Regexp
-       validateFuncs []func(string) bool
-}
-
-// Option is RegexValidateRule option
-type Option struct {
-       Min int64
-       Max int64
-}
-
-// Validate validates string
-func (r *RegexValidateRule) Validate(s string) bool {
-       for _, f := range r.validateFuncs {
-               if ok := f(s); !ok {
-                       return false
-               }
-       }
-       return true
-}
-
-func (r *RegexValidateRule) validateFL(fl validator.FieldLevel) bool {
-       return r.Validate(fl.Field().String())
-}
-
-// Tag returns the validate rule's tag
-func (r *RegexValidateRule) Tag() string {
-       return r.tag
-}
-
-// Explain explains the rule
-func (r *RegexValidateRule) Explain() string {
-       explain := r.regex.String()
-       if r.max > 0 {
-               explain = fmt.Sprintf("%s , max = %d", explain, r.max)
-       }
-       if r.min > 0 {
-               explain = fmt.Sprintf("%s , min = %d", explain, r.min)
-       }
-       return explain
-}
-
-func (r *RegexValidateRule) matchRegex(s string) bool {
-       return r.regex.MatchString(s)
-}
-func (r *RegexValidateRule) matchMin(s string) bool {
-       return int64(utf8.RuneCountInString(s)) >= r.min
-}
-func (r *RegexValidateRule) matchMax(s string) bool {
-       return int64(utf8.RuneCountInString(s)) <= r.max
-}
-
-// NewRule news a rule
-func NewRule(tag, regexStr string, opt *Option) *RegexValidateRule {
-       r := &RegexValidateRule{
-               tag:           tag,
-               regex:         regexp.MustCompile(regexStr),
-               validateFuncs: make([]func(string) bool, 0),
-       }
-
-       if opt == nil {
-               r.validateFuncs = append(r.validateFuncs, r.matchRegex)
-               return r
-       }
-
-       if opt.Max > 0 {
-               r.max = opt.Max
-               r.validateFuncs = append(r.validateFuncs, r.matchMax)
-       }
-       if opt.Min > 0 {
-               r.min = opt.Min
-               r.validateFuncs = append(r.validateFuncs, r.matchMin)
-       }
-       r.validateFuncs = append(r.validateFuncs, r.matchRegex)
-       return r
-}
diff --git a/pkg/validate/rule_test.go b/pkg/validate/rule_test.go
deleted file mode 100644
index d2336a9..0000000
--- a/pkg/validate/rule_test.go
+++ /dev/null
@@ -1,39 +0,0 @@
-package validate_test
-
-import (
-       "testing"
-
-       "github.com/apache/servicecomb-kie/pkg/validate"
-       "github.com/stretchr/testify/assert"
-)
-
-func TestNewRule(t *testing.T) {
-       rule := validate.NewRule("t", `^[a-zA-Z0-9]*$`, &validate.Option{Min: 
2, Max: 4})
-       assert.Equal(t, "t", rule.Tag())
-       rule.Explain()
-       assert.True(t, rule.Validate("ab"))
-       assert.False(t, rule.Validate("a"))
-       assert.False(t, rule.Validate("abcde"))
-       assert.False(t, rule.Validate("ab-"))
-
-       rule = validate.NewRule("t", `^[a-zA-Z0-9]*$`, &validate.Option{Min: 2})
-       rule.Explain()
-       assert.True(t, rule.Validate("ab"))
-       assert.False(t, rule.Validate("a"))
-       assert.True(t, rule.Validate("abcde"))
-       assert.False(t, rule.Validate("ab-"))
-
-       rule = validate.NewRule("t", `^[a-zA-Z0-9]*$`, &validate.Option{Max: 4})
-       rule.Explain()
-       assert.True(t, rule.Validate("ab"))
-       assert.True(t, rule.Validate("a"))
-       assert.False(t, rule.Validate("abcde"))
-       assert.False(t, rule.Validate("ab-"))
-
-       rule = validate.NewRule("t", `^[a-zA-Z0-9]*$`, nil)
-       rule.Explain()
-       assert.True(t, rule.Validate("ab"))
-       assert.True(t, rule.Validate("a"))
-       assert.True(t, rule.Validate("abcdefg12345678"))
-       assert.False(t, rule.Validate("ab-"))
-}
diff --git a/pkg/validate/validator.go b/pkg/validate/validator.go
deleted file mode 100644
index 59fdf26..0000000
--- a/pkg/validate/validator.go
+++ /dev/null
@@ -1,87 +0,0 @@
-package validate
-
-import (
-       "errors"
-       "fmt"
-       "strings"
-
-       ut "github.com/go-playground/universal-translator"
-       valid "github.com/go-playground/validator"
-)
-
-var errorTranslator ut.Translator // no use but as an index
-
-func registerErrorTranslator(_ ut.Translator) error { return nil }
-
-// Validator validates data
-// not safe, use it after initialized
-type Validator struct {
-       rules map[string]*RegexValidateRule
-       valid *valid.Validate
-}
-
-// Validate validates the input data
-func (v *Validator) Validate(i interface{}) error {
-       err := v.valid.Struct(i)
-       if err != nil {
-               return v.wrapError(err)
-       }
-       return nil
-}
-
-// converts the raw error into an easy-to-understand error
-func (v *Validator) wrapError(err error) error {
-       validErr, ok := err.(valid.ValidationErrors)
-       if !ok {
-               return err
-       }
-       msgs := make([]string, len(validErr))
-       for i, ve := range validErr {
-               fe := ve.(valid.FieldError)
-               msgs[i] = fe.Translate(errorTranslator)
-       }
-       return errors.New("validate failed, " + strings.Join(msgs, " | "))
-}
-
-// RegisterRule registers a custom validate rule
-func (v *Validator) RegisterRule(r *RegexValidateRule) error {
-       if r == nil {
-               return errors.New("empty regex validate rule")
-       }
-       v.rules[r.tag] = r
-       if err := v.valid.RegisterValidation(r.tag, r.validateFL); err != nil {
-               return err
-       }
-       return v.AddErrorTranslation4Tag(r.tag)
-}
-
-// translates raw errors to easy-to-understand messages
-func (v *Validator) translateError(_ ut.Translator, fe valid.FieldError) 
string {
-       var rule string
-       if r, ok := v.rules[fe.Tag()]; ok {
-               rule = r.Explain()
-       } else {
-               rule = fe.Tag()
-               if len(fe.Param()) > 0 {
-                       rule = rule + " = " + fe.Param()
-               }
-       }
-       return fmt.Sprintf("field: %s, rule: %s", fe.Namespace(), rule)
-}
-
-// AddErrorTranslation4Tag adds translation for the errors of some tag,
-// to make the error easier to understand
-func (v *Validator) AddErrorTranslation4Tag(tag string) error {
-       return v.valid.RegisterTranslation(tag,
-               errorTranslator,
-               registerErrorTranslator,
-               v.translateError)
-}
-
-// NewValidator news a validator
-func NewValidator() *Validator {
-       return &Validator{
-               valid: valid.New(),
-               rules: make(map[string]*RegexValidateRule),
-       }
-}
diff --git a/pkg/validate/validator_test.go b/pkg/validate/validator_test.go
deleted file mode 100644
index 3bcde81..0000000
--- a/pkg/validate/validator_test.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package validate_test
-
-import (
-       "testing"
-
-       "github.com/apache/servicecomb-kie/pkg/validate"
-       "github.com/stretchr/testify/assert"
-)
-
-type student struct {
-       Name    string `validate:"kieTest"`
-       Address string `validate:"alpha,min=2,max=4"`
-}
-
-func TestNewValidator(t *testing.T) {
-       r := validate.NewRule("kieTest", `^[a-zA-Z0-9]*$`, nil)
-       valid := validate.NewValidator()
-       err := valid.RegisterRule(r)
-       assert.Nil(t, err)
-       assert.Nil(t, valid.AddErrorTranslation4Tag("min"))
-       assert.Nil(t, valid.AddErrorTranslation4Tag("max"))
-
-       s := &student{Name: "a1", Address: "abc"}
-       err = valid.Validate(s)
-       assert.Nil(t, err)
-
-       s = &student{Name: "a1-", Address: "abc"}
-       err = valid.Validate(s)
-       assert.NotNil(t, err)
-       t.Log(err)
-
-       s = &student{Name: "a1", Address: "abcde"}
-       err = valid.Validate(s)
-       assert.NotNil(t, err)
-       t.Log(err)
-}
diff --git a/pkg/validator/rule.go b/pkg/validator/rule.go
new file mode 100644
index 0000000..b6e9e71
--- /dev/null
+++ b/pkg/validator/rule.go
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package validator
+
+import "github.com/go-chassis/foundation/validator"
+
+const (
+       key                   = "key"
+       commonNameRegexString = 
`^[a-zA-Z0-9]*$|^[a-zA-Z0-9][a-zA-Z0-9_\-.]*[a-zA-Z0-9]$`
+       labelKvRegexString    = 
`^[a-zA-Z0-9]{0,32}$|^[a-zA-Z0-9][a-zA-Z0-9_\-.]{0,30}[a-zA-Z0-9]$`
+       getKeyRegexString     = 
`^[a-zA-Z0-9]*$|^[a-zA-Z0-9][a-zA-Z0-9_\-.]*[a-zA-Z0-9]$|^beginWith\([a-zA-Z0-9][a-zA-Z0-9_\-.]*\)$|^wildcard\([a-zA-Z0-9][a-zA-Z0-9_\-.*]*\)$`
+       asciiRegexString      = `^[\x00-\x7F]*$`
+       allCharString         = `.*`
+)
+
+// custom validate rules
+// please use different tag names from third party tags
+var customRules = []*validator.RegexValidateRule{
+       validator.NewRegexRule(key, commonNameRegexString),
+       validator.NewRegexRule("getKey", getKeyRegexString),
+       validator.NewRegexRule("commonName", commonNameRegexString),
+       validator.NewRegexRule("valueType", 
`^$|^(ini|json|text|yaml|properties)$`),
+       validator.NewRegexRule("kvStatus", `^$|^(enabled|disabled)$`),
+       validator.NewRegexRule("value", allCharString), //ASCII, 2M
+       validator.NewRegexRule("labelKV", labelKvRegexString),
+       validator.NewRegexRule("check", asciiRegexString), //ASCII, 1M
+}
+
+func Init() error {
+       return validator.RegisterRegexRules(customRules)
+}
diff --git a/pkg/validator/rule_test.go b/pkg/validator/rule_test.go
new file mode 100644
index 0000000..5cf5705
--- /dev/null
+++ b/pkg/validator/rule_test.go
@@ -0,0 +1,173 @@
+package validator_test
+
+import (
+       "github.com/go-chassis/foundation/validator"
+       "strings"
+       "testing"
+
+       "github.com/apache/servicecomb-kie/pkg/model"
+       validsvc "github.com/apache/servicecomb-kie/pkg/validator"
+       "github.com/stretchr/testify/assert"
+)
+
+func init() {
+       if err := validsvc.Init(); err != nil {
+               panic(err)
+       }
+}
+
+func TestValidate(t *testing.T) {
+       string32 := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" //32
+       string128 := string32 + string32 + string32 + string32
+
+       kvDoc := &model.KVDoc{Project: "a", Domain: "a",
+               Key:   "a",
+               Value: "a",
+       }
+       assert.NoError(t, validator.Validate(kvDoc))
+
+       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
+               Key:   "",
+               Value: "a",
+       }
+       assert.Error(t, validator.Validate(kvDoc))
+
+       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
+               Key:   "a#",
+               Value: "a",
+       }
+       assert.Error(t, validator.Validate(kvDoc))
+
+       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
+               Key:   string128 + "a",
+               Value: "a",
+       }
+       assert.Error(t, validator.Validate(kvDoc))
+
+       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
+               Key:   "a",
+               Value: "",
+       }
+       assert.NoError(t, validator.Validate(kvDoc))
+
+       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
+               Key:       "a",
+               Value:     "a",
+               ValueType: "",
+       }
+       assert.NoError(t, validator.Validate(kvDoc))
+
+       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
+               Key:       "a",
+               Value:     "a",
+               ValueType: "text",
+       }
+       assert.NoError(t, validator.Validate(kvDoc))
+
+       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
+               Key:       "a",
+               Value:     "a",
+               ValueType: "a",
+       }
+       assert.Error(t, validator.Validate(kvDoc))
+
+       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
+               Key:    "a",
+               Value:  "a",
+               Status: "",
+       }
+       assert.NoError(t, validator.Validate(kvDoc))
+
+       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
+               Key:    "a",
+               Value:  "a",
+               Status: "enabled",
+       }
+       assert.NoError(t, validator.Validate(kvDoc))
+
+       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
+               Key:    "a",
+               Value:  "a",
+               Status: "a",
+       }
+       assert.Error(t, validator.Validate(kvDoc))
+
+       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
+               Key:    "a",
+               Value:  "a",
+               Labels: nil,
+       }
+       assert.NoError(t, validator.Validate(kvDoc))
+
+       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
+               Key:    "a",
+               Value:  "a",
+               Labels: map[string]string{"a": "a"},
+       }
+       assert.NoError(t, validator.Validate(kvDoc))
+
+       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
+               Key:   "a",
+               Value: "a",
+               Labels: map[string]string{
+                       "1": "a",
+                       "2": "a",
+                       "3": "a",
+                       "4": "a",
+                       "5": "a",
+                       "6": "a",
+                       "7": "a", // error
+               },
+       }
+       assert.Error(t, validator.Validate(kvDoc))
+
+       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
+               Key:   "a",
+               Value: "a",
+               Labels: map[string]string{
+                       "1":                            "a",
+                       "2":                            "a",
+                       "3":                            "a",
+                       "4":                            "a",
+                       "5":                            "a",
+                       "6-" + strings.Repeat("x", 31): "a", // error
+               },
+       }
+       assert.Error(t, validator.Validate(kvDoc))
+
+       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
+               Key:   "a",
+               Value: "a",
+               Labels: map[string]string{
+                       "1": "a",
+                       "2": "a",
+                       "3": "a",
+                       "4": "a",
+                       "5": "a",
+                       "6": "a-" + strings.Repeat("x", 31), // error
+               },
+       }
+       assert.Error(t, validator.Validate(kvDoc))
+
+       kvDoc = &model.KVDoc{Project: "a", Domain: "a",
+               Key:    "a",
+               Value:  "a",
+               Labels: map[string]string{string32 + "a": "a"},
+       }
+       assert.Error(t, validator.Validate(kvDoc))
+
+       ListKVRe := &model.ListKVRequest{Project: "a", Domain: "a",
+               Key: "beginWith(a)",
+       }
+       assert.NoError(t, validator.Validate(ListKVRe))
+
+       ListKVRe = &model.ListKVRequest{Project: "a", Domain: "a",
+               Key: "beginW(a)",
+       }
+       assert.Error(t, validator.Validate(ListKVRe))
+
+       ListKVRe = &model.ListKVRequest{Project: "a", Domain: "a",
+               Key: "beginW()",
+       }
+       assert.Error(t, validator.Validate(ListKVRe))
+}
diff --git a/server/resource/v1/kv_resource.go 
b/server/resource/v1/kv_resource.go
index b228e3a..51f74be 100644
--- a/server/resource/v1/kv_resource.go
+++ b/server/resource/v1/kv_resource.go
@@ -21,11 +21,11 @@ package v1
 import (
        "encoding/json"
        "fmt"
+       "github.com/go-chassis/foundation/validator"
        "net/http"
 
        "github.com/apache/servicecomb-kie/pkg/common"
        "github.com/apache/servicecomb-kie/pkg/model"
-       "github.com/apache/servicecomb-kie/pkg/validate"
        "github.com/apache/servicecomb-kie/server/pubsub"
        "github.com/apache/servicecomb-kie/server/service"
        "github.com/apache/servicecomb-kie/server/service/mongo/session"
@@ -55,7 +55,7 @@ func (r *KVResource) Post(rctx *restful.Context) {
        if kv.Status == "" {
                kv.Status = common.StatusDisabled
        }
-       err = validate.Validate(kv)
+       err = validator.Validate(kv)
        if err != nil {
                WriteErrResponse(rctx, http.StatusBadRequest, err.Error())
                return
@@ -114,7 +114,7 @@ func (r *KVResource) Put(rctx *restful.Context) {
        kvReq.ID = kvID
        kvReq.Domain = domain
        kvReq.Project = project
-       err = validate.Validate(kvReq)
+       err = validator.Validate(kvReq)
        if err != nil {
                WriteErrResponse(rctx, http.StatusBadRequest, err.Error())
                return
@@ -151,7 +151,7 @@ func (r *KVResource) Get(rctx *restful.Context) {
                Domain:  ReadDomain(rctx.Ctx),
                ID:      rctx.ReadPathParameter(common.PathParamKVID),
        }
-       err := validate.Validate(request)
+       err := validator.Validate(request)
        if err != nil {
                WriteErrResponse(rctx, http.StatusBadRequest, err.Error())
                return
@@ -198,7 +198,7 @@ func (r *KVResource) List(rctx *restful.Context) {
        }
        request.Offset = offset
        request.Limit = limit
-       err = validate.Validate(request)
+       err = validator.Validate(request)
        if err != nil {
                WriteErrResponse(rctx, http.StatusBadRequest, err.Error())
                return
diff --git a/server/resource/v1/kv_resource_test.go 
b/server/resource/v1/kv_resource_test.go
index 7402427..b7d6f5e 100644
--- a/server/resource/v1/kv_resource_test.go
+++ b/server/resource/v1/kv_resource_test.go
@@ -22,7 +22,6 @@ import (
        "encoding/json"
        common2 "github.com/apache/servicecomb-kie/pkg/common"
        "github.com/apache/servicecomb-kie/pkg/model"
-       "github.com/apache/servicecomb-kie/pkg/validate"
        "github.com/apache/servicecomb-kie/server/config"
        "github.com/apache/servicecomb-kie/server/plugin/qms"
        "github.com/apache/servicecomb-kie/server/pubsub"
@@ -47,9 +46,6 @@ import (
 )
 
 func init() {
-       if err := validate.Init(); err != nil {
-               panic(err)
-       }
        log.Init(log.Config{
                Writers:       []string{"stdout"},
                LoggerLevel:   "DEBUG",
diff --git a/server/server.go b/server/server.go
index 3f57559..93215ab 100644
--- a/server/server.go
+++ b/server/server.go
@@ -18,7 +18,7 @@
 package server
 
 import (
-       "github.com/apache/servicecomb-kie/pkg/validate"
+       "github.com/apache/servicecomb-kie/pkg/validator"
        "github.com/apache/servicecomb-kie/server/config"
        "github.com/apache/servicecomb-kie/server/pubsub"
        "github.com/apache/servicecomb-kie/server/rbac"
@@ -42,7 +42,7 @@ func Run() {
        if err := service.DBInit(); err != nil {
                openlog.Fatal(err.Error())
        }
-       if err := validate.Init(); err != nil {
+       if err := validator.Init(); err != nil {
                openlog.Fatal("validate init failed: " + err.Error())
        }
        rbac.Init()
diff --git a/test/init.go b/test/init.go
index 9841401..397c104 100644
--- a/test/init.go
+++ b/test/init.go
@@ -18,6 +18,7 @@
 package test
 
 import (
+       "github.com/apache/servicecomb-kie/pkg/validator"
        "github.com/go-chassis/go-archaius"
        "github.com/go-chassis/go-chassis/v2/security/cipher"
        _ "github.com/go-chassis/go-chassis/v2/security/cipher/plugins/plain"
@@ -27,4 +28,5 @@ func init() {
        archaius.Init(archaius.WithMemorySource())
        archaius.Set("servicecomb.cipher.plugin", "default")
        cipher.Init()
+       validator.Init()
 }

Reply via email to