From 96f5554a4c8b45ca08c25b834b74534a5e5959a6 Mon Sep 17 00:00:00 2001 From: pantianying <601666418@qq.com> Date: Tue, 30 Jul 2019 18:03:24 +0800 Subject: [PATCH] add generic filter --- common/constant/default.go | 2 + config/reference_config.go | 2 +- filter/impl/generic_filter.go | 75 +++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 filter/impl/generic_filter.go diff --git a/common/constant/default.go b/common/constant/default.go index 05461ca6e..7ab92249a 100644 --- a/common/constant/default.go +++ b/common/constant/default.go @@ -38,6 +38,8 @@ const ( PREFIX_DEFAULT_KEY = "default." DEFAULT_SERVICE_FILTERS = "echo" DEFAULT_REFERENCE_FILTERS = "" + GENERIC_REFERENCE_FILTERS = "generic" + GENERIC = "$invoke" ECHO = "$echo" ) diff --git a/config/reference_config.go b/config/reference_config.go index 0ab24e184..c1565004c 100644 --- a/config/reference_config.go +++ b/config/reference_config.go @@ -170,7 +170,7 @@ func (refconfig *ReferenceConfig) getUrlMap() url.Values { //filter urlMap.Set(constant.REFERENCE_FILTER_KEY, mergeValue(consumerConfig.Filter, refconfig.Filter, constant.DEFAULT_REFERENCE_FILTERS)) - + urlMap.Set(constant.REFERENCE_FILTER_KEY, mergeValue(consumerConfig.Filter, refconfig.Filter, constant.GENERIC_REFERENCE_FILTERS)) for _, v := range refconfig.Methods { urlMap.Set("methods."+v.Name+"."+constant.LOADBALANCE_KEY, v.Loadbalance) urlMap.Set("methods."+v.Name+"."+constant.RETRIES_KEY, strconv.FormatInt(v.Retries, 10)) diff --git a/filter/impl/generic_filter.go b/filter/impl/generic_filter.go new file mode 100644 index 000000000..14da6eeab --- /dev/null +++ b/filter/impl/generic_filter.go @@ -0,0 +1,75 @@ +package impl + +import ( + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/filter" + "github.com/apache/dubbo-go/protocol" + invocation2 "github.com/apache/dubbo-go/protocol/invocation" + "reflect" + "strings" +) + +const ( + GENERIC = "generic" +) + +func init() { + extension.SetFilter(GENERIC, GetGenericFilter) +} + +// when do a generic invoke, struct need to be map + +type GenericFilter struct{} + +func (ef *GenericFilter) Invoke(invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { + if invocation.MethodName() == constant.GENERIC { + var newArguments = invocation.Arguments() + for i := range newArguments { + newArguments[i] = Struct2MapAll(newArguments[i]) + } + newInvocation := invocation2.NewRPCInvocation(invocation.MethodName(), newArguments, invocation.Attachments()) + return invoker.Invoke(newInvocation) + } + return invoker.Invoke(invocation) + +} + +func (ef *GenericFilter) OnResponse(result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { + return result +} + +func GetGenericFilter() filter.Filter { + return &GenericFilter{} +} +func Struct2MapAll(obj interface{}) map[string]interface{} { + t := reflect.TypeOf(obj) + v := reflect.ValueOf(obj) + result := make(map[string]interface{}) + if reflect.TypeOf(obj).Kind() == reflect.Struct { + for i := 0; i < t.NumField(); i++ { + if v.Field(i).Kind() == reflect.Struct { + if v.Field(i).CanInterface() { + result[headerAtoa(t.Field(i).Name)] = Struct2MapAll(v.Field(i).Interface()) + } else { + println("not in to map,field:" + t.Field(i).Name) + } + } else { + if v.Field(i).CanInterface() { + if tagName := t.Field(i).Tag.Get("m"); tagName == "" { + result[headerAtoa(t.Field(i).Name)] = v.Field(i).Interface() + } else { + result[tagName] = v.Field(i).Interface() + } + } else { + println("not in to map,field:" + t.Field(i).Name) + } + } + } + } + return result +} +func headerAtoa(a string) (b string) { + b = strings.ToLower(a[:1]) + a[1:] + return +} -- GitLab