Use foundation/validator instead (#184)
diff --git a/go.mod b/go.mod
index b10cd0d..539d13b 100644
--- a/go.mod
+++ b/go.mod
@@ -2,16 +2,13 @@
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/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/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/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 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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
"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 @@
)
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 @@
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 @@
archaius.Init(archaius.WithMemorySource())
archaius.Set("servicecomb.cipher.plugin", "default")
cipher.Init()
+ validator.Init()
}