Skip to content

Commit

Permalink
feat:add protomessage field validator
Browse files Browse the repository at this point in the history
  • Loading branch information
geebytes committed Jul 22, 2024
1 parent e0c804c commit eef9cc8
Show file tree
Hide file tree
Showing 9 changed files with 781 additions and 356 deletions.
3 changes: 1 addition & 2 deletions gateway/serialization.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package gateway
import (
"fmt"
"io"
"log"

_ "github.com/begonia-org/go-sdk/api/app/v1"
_ "github.com/begonia-org/go-sdk/api/endpoint/v1"
Expand Down Expand Up @@ -201,7 +200,7 @@ func (m *JSONMarshaler) Marshal(v interface{}) ([]byte, error) {

}
if response, ok := v.(*dynamicpb.Message); ok {
log.Println("实际类型,", response.Type().Descriptor().Name())
// log.Println("实际类型,", response.Type().Descriptor().Name())
byteData, err := m.JSONPb.Marshal(response)
if err != nil {
return nil, status.Errorf(codes.Internal, "marshal_response: %v", err)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ require (
require (
github.com/agiledragon/gomonkey/v2 v2.11.0
github.com/begonia-org/go-loadbalancer v0.0.0-20240519060752-71ca464f0f1a
github.com/begonia-org/go-sdk v0.0.0-20240722154330-ecc143356037
github.com/begonia-org/go-sdk v0.0.0-20240722164044-30e4fbeca04c
github.com/go-git/go-git/v5 v5.11.0
github.com/go-playground/validator/v10 v10.19.0
github.com/gorilla/websocket v1.5.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ github.com/begonia-org/go-sdk v0.0.0-20240714083941-00e95e667477 h1:8LhQbM+Y51bs
github.com/begonia-org/go-sdk v0.0.0-20240714083941-00e95e667477/go.mod h1:2mHpFudwolu6RHF18EX+lnFYyTNnwDxBD6JcfRcahz8=
github.com/begonia-org/go-sdk v0.0.0-20240722154330-ecc143356037 h1:6k1LVmKwSf/4Mm1SuB/RRRYN9VtTuHvwDadGjq9MiEE=
github.com/begonia-org/go-sdk v0.0.0-20240722154330-ecc143356037/go.mod h1:2mHpFudwolu6RHF18EX+lnFYyTNnwDxBD6JcfRcahz8=
github.com/begonia-org/go-sdk v0.0.0-20240722164044-30e4fbeca04c h1:Al780pVPkCmZ9n+NrjFZbTVzbKrd82dVMVfKn+twacQ=
github.com/begonia-org/go-sdk v0.0.0-20240722164044-30e4fbeca04c/go.mod h1:2mHpFudwolu6RHF18EX+lnFYyTNnwDxBD6JcfRcahz8=
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
Expand Down
14 changes: 7 additions & 7 deletions internal/middleware/vaildator.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ func (p *ParamsValidatorImpl) getValidatePath(message protoreflect.ProtoMessage,

// FiltersFields 从FieldMask中获取过滤字段,获取待验证字段
// required 字段优先级高于FieldMask
func (p *ParamsValidatorImpl) FiltersMessageFields(v interface{}, parent string) []string {
func (p *ParamsValidatorImpl) FiltersMessageFields(v interface{}) []string {
// fieldsMap := getFieldNamesFromJSONTags(v)
requiredFields := make([]string, 0)
maskFields := make([]string, 0)
Expand All @@ -182,7 +182,7 @@ func (p *ParamsValidatorImpl) FiltersMessageFields(v interface{}, parent string)
// require 字段必须校验
if p.isRequiredField(field) {
// log.Printf("required field:%s", field.JSONName())
requiredFields = append(requiredFields, p.getValidatePath(message, field.JSONName(), parent)...)
requiredFields = append(requiredFields, p.getValidatePath(message, field.JSONName(), "")...)
}

// 检查字段是否是FieldMask类型
Expand All @@ -198,11 +198,11 @@ func (p *ParamsValidatorImpl) FiltersMessageFields(v interface{}, parent string)
paths = append(paths, mask.Paths...)
for _, path := range paths {
maskField := strcase.ToCamel(path)
if parent != "" {
maskField = fmt.Sprintf("%s.%s", parent, strcase.ToCamel(path))
}
// if parent != "" {
// maskField = fmt.Sprintf("%s.%s", parent, strcase.ToCamel(path))
// }
maskFields = append(maskFields, maskField)
maskFields = append(maskFields, p.getValidatePath(message, path, parent)...)
maskFields = append(maskFields, p.getValidatePath(message, path, "")...)
}
}
}
Expand Down Expand Up @@ -274,7 +274,7 @@ func (p *ParamsValidatorImpl) ValidateParams(v interface{}) error {
// p.validate.Struct()
var err error
if message, ok := v.(proto.Message); ok {
filters := p.FiltersMessageFields(v, "")
filters := p.FiltersMessageFields(v)
duplicateFilters := make([]string, 0)
fieldsSet := make(map[string]struct{})
for _, f := range filters {
Expand Down
120 changes: 69 additions & 51 deletions internal/middleware/vaildator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,63 +106,64 @@ func TestValidateDynamicProtoMessage(t *testing.T) {

}
func TestValidateProtoMessage(t *testing.T) {
c.Convey("test validator unary interceptor", t, func() {
validator := middleware.NewParamsValidator()

validator.SetPriority(1)
c.So(validator.Priority(), c.ShouldEqual, 1)
c.So(validator.Name(), c.ShouldEqual, "ParamsValidator")
req := &hello.HelloRequestWithValidator{
Name: "test",
Msg: "test",
Age: 19,
Age2: 19,
FloatNum: 1.1,
BoolData: true,
BytesData: []byte("test"),
ExEnum: hello.ExampleEnum_EX_RUNNING,
ExEnums: []hello.ExampleEnum{
hello.ExampleEnum_EX_RUNNING,
},
EnumMap: map[string]hello.ExampleEnum{
"test": hello.ExampleEnum_EX_RUNNING,
},
EnumMap2: map[string]hello.ExampleEnum{
"test": hello.ExampleEnum_EX_UNKNOWN,
},
Strs: []string{"test"},
Sub: &hello.HelloSubRequest{
SubMsg: "test",
req := &hello.HelloRequestWithValidator{
Name: "test",
Msg: "test",
Age: 19,
Age2: 19,
FloatNum: 1.1,
BoolData: true,
BytesData: []byte("test"),
ExEnum: hello.ExampleEnum_EX_RUNNING,
ExEnums: []hello.ExampleEnum{
hello.ExampleEnum_EX_RUNNING,
},
EnumMap: map[string]hello.ExampleEnum{
"test": hello.ExampleEnum_EX_RUNNING,
},
EnumMap2: map[string]hello.ExampleEnum{
"test": hello.ExampleEnum_EX_UNKNOWN,
},
Strs: []string{"test"},
Sub: &hello.HelloSubRequest{
SubMsg: "test",
SubAge: 19,
SubName: "test",
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"sub_name", "sub_msg"}},
},
Subs: []*hello.HelloSubRequest{
{
SubAge: 19,
SubName: "test",
SubMsg: "test",
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"sub_name", "sub_msg"}},
},
Subs: []*hello.HelloSubRequest{
{
SubAge: 19,
SubName: "test",
SubMsg: "test",
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"sub_name", "sub_msg"}},
},
{
SubName: "test",
SubAge: 19,
SubMsg: "test",
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"sub_msg"}},
},
},
SubMap: map[string]*hello.HelloSubRequest{
"TEST1": {
SubName: "test",
SubAge: 19,
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"sub_name", "sub_age"}},
},
{
SubName: "test",
SubAge: 19,
SubMsg: "test",
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"sub_msg"}},
},
SubMap2: map[string]string{
"TEST1": "test",
},
SubMap: map[string]*hello.HelloSubRequest{
"TEST1": {
SubName: "test",
SubAge: 19,
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"sub_name", "sub_age"}},
},
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"name", "msg", "sub", "subs", "sub_map", "sub_map2"}},
}
},
SubMap2: map[string]string{
"TEST1": "test",
},
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"name", "msg", "sub", "subs", "sub_map", "sub_map2"}},
}
c.Convey("test validator unary interceptor", t, func() {
validator := middleware.NewParamsValidator()

validator.SetPriority(1)
c.So(validator.Priority(), c.ShouldEqual, 1)
c.So(validator.Name(), c.ShouldEqual, "ParamsValidator")

_, err := validator.UnaryInterceptor(context.Background(), req, &grpc.UnaryServerInfo{}, func(ctx context.Context, req interface{}) (interface{}, error) {
return nil, nil
})
Expand Down Expand Up @@ -273,6 +274,13 @@ func TestValidateProtoMessage(t *testing.T) {
})
c.So(err, c.ShouldNotBeNil)
c.So(err.Error(), c.ShouldContainSubstring, "Sub2")
req16 := tiga.DeepCopy(req).(*hello.HelloRequestWithValidator)
req16.Sub = nil
_, err = validator.UnaryInterceptor(context.Background(), req16, &grpc.UnaryServerInfo{}, func(ctx context.Context, req interface{}) (interface{}, error) {
return nil, nil
})
c.So(err, c.ShouldNotBeNil)
c.So(err.Error(), c.ShouldContainSubstring, "Sub")

st := struct {
Name string `validate:"required"`
Expand All @@ -283,6 +291,15 @@ func TestValidateProtoMessage(t *testing.T) {
c.So(err, c.ShouldNotBeNil)
c.So(err.Error(), c.ShouldContainSubstring, "params is not a proto.Message")

})
c.Convey("test NewStructFromProtobuf",t,func(){
validate:=validator.New()
vd:=middleware.NewProtobufValidate(validate)
v:=vd.NewStructFromProtobuf(tiga.DeepCopy(req).(*hello.HelloRequestWithValidator),common.E_Validate)
err:=validate.Struct(v)
c.So(err,c.ShouldBeNil)


})
}
func TestValidator(t *testing.T) {
Expand Down Expand Up @@ -326,6 +343,7 @@ func TestValidatorStreamClientInterceptor(t *testing.T) {
return nil, nil
})
c.So(err, c.ShouldBeNil)


})
}
Binary file modified testdata/desc.pb
Binary file not shown.
Loading

0 comments on commit eef9cc8

Please sign in to comment.