Skip to content
Snippets Groups Projects
Commit b3fabcee authored by Patrick's avatar Patrick
Browse files

Merge branch 'develop' into rest_protocol

parents 69020c04 1fa4bf66
No related branches found
No related tags found
No related merge requests found
Showing
with 189 additions and 55 deletions
......@@ -93,7 +93,7 @@ type rest struct {
var count int
func (bi *MockInvoker) Invoke(invocation protocol.Invocation) protocol.Result {
func (bi *MockInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result {
count++
var success bool
var err error = nil
......
......@@ -18,6 +18,7 @@
package proxy
import (
"context"
"reflect"
"sync"
)
......@@ -72,10 +73,11 @@ func (p *Proxy) Implement(v common.RPCService) {
makeDubboCallProxy := func(methodName string, outs []reflect.Type) func(in []reflect.Value) []reflect.Value {
return func(in []reflect.Value) []reflect.Value {
var (
err error
inv *invocation_impl.RPCInvocation
inArr []interface{}
reply reflect.Value
err error
inv *invocation_impl.RPCInvocation
inIArr []interface{}
inVArr []reflect.Value
reply reflect.Value
)
if methodName == "Echo" {
methodName = "$echo"
......@@ -104,27 +106,31 @@ func (p *Proxy) Implement(v common.RPCService) {
}
if end-start <= 0 {
inArr = []interface{}{}
inIArr = []interface{}{}
inVArr = []reflect.Value{}
} else if v, ok := in[start].Interface().([]interface{}); ok && end-start == 1 {
inArr = v
inIArr = v
inVArr = []reflect.Value{in[start]}
} else {
inArr = make([]interface{}, end-start)
inIArr = make([]interface{}, end-start)
inVArr = make([]reflect.Value, end-start)
index := 0
for i := start; i < end; i++ {
inArr[index] = in[i].Interface()
inIArr[index] = in[i].Interface()
inVArr[index] = in[i]
index++
}
}
inv = invocation_impl.NewRPCInvocationWithOptions(invocation_impl.WithMethodName(methodName),
invocation_impl.WithArguments(inArr), invocation_impl.WithReply(reply.Interface()),
invocation_impl.WithCallBack(p.callBack))
invocation_impl.WithArguments(inIArr), invocation_impl.WithReply(reply.Interface()),
invocation_impl.WithCallBack(p.callBack), invocation_impl.WithParameterValues(inVArr))
for k, value := range p.attachments {
inv.SetAttachments(k, value)
}
result := p.invoke.Invoke(inv)
result := p.invoke.Invoke(context.Background(), inv)
err = result.Error()
logger.Infof("[makeDubboCallProxy] result: %v, err: %v", result.Result(), err)
......
......@@ -18,6 +18,7 @@
package proxy_factory
import (
"context"
"reflect"
"strings"
)
......@@ -75,7 +76,7 @@ type ProxyInvoker struct {
protocol.BaseInvoker
}
func (pi *ProxyInvoker) Invoke(invocation protocol.Invocation) protocol.Result {
func (pi *ProxyInvoker) Invoke(context context.Context, invocation protocol.Invocation) protocol.Result {
result := &protocol.RPCResult{}
result.SetAttachments(invocation.Attachments())
......
......@@ -40,7 +40,7 @@ type ConfigCenterConfig struct {
Username string `yaml:"username" json:"username,omitempty"`
Password string `yaml:"password" json:"password,omitempty"`
ConfigFile string `default:"dubbo.properties" yaml:"config_file" json:"config_file,omitempty"`
Namespace string `default:"dubbo.properties" yaml:"namespace" json:"namespace,omitempty"`
Namespace string `default:"dubbo" yaml:"namespace" json:"namespace,omitempty"`
AppConfigFile string `default:"dubbo.properties" yaml:"app_config_file" json:"app_config_file,omitempty"`
AppId string `default:"dubbo" yaml:"app_id" json:"app_id,omitempty"`
TimeoutStr string `yaml:"timeout" json:"timeout,omitempty"`
......
......@@ -91,7 +91,7 @@ func Load() {
continue
}
ref.id = key
ref.Refer()
ref.Refer(rpcService)
ref.Implement(rpcService)
}
//wait for invoker is available, if wait over default 3s, then panic
......
......@@ -25,6 +25,7 @@ import (
import (
"github.com/creasty/defaults"
"github.com/dubbogo/getty"
perrors "github.com/pkg/errors"
"gopkg.in/yaml.v2"
)
......@@ -119,6 +120,10 @@ func ConsumerInit(confConFile string) error {
if consumerConfig.RequestTimeout, err = time.ParseDuration(consumerConfig.Request_Timeout); err != nil {
return perrors.WithMessagef(err, "time.ParseDuration(Request_Timeout{%#v})", consumerConfig.Request_Timeout)
}
if consumerConfig.RequestTimeout >= time.Duration(getty.MaxWheelTimeSpan) {
return perrors.WithMessagef(err, "request_timeout %s should be less than %s",
consumerConfig.Request_Timeout, time.Duration(getty.MaxWheelTimeSpan))
}
}
if consumerConfig.Connect_Timeout != "" {
if consumerConfig.ConnectTimeout, err = time.ParseDuration(consumerConfig.Connect_Timeout); err != nil {
......
......@@ -89,8 +89,12 @@ func (refconfig *ReferenceConfig) UnmarshalYAML(unmarshal func(interface{}) erro
return nil
}
func (refconfig *ReferenceConfig) Refer() {
url := common.NewURLWithOptions(common.WithPath(refconfig.id), common.WithProtocol(refconfig.Protocol), common.WithParams(refconfig.getUrlMap()))
func (refconfig *ReferenceConfig) Refer(impl interface{}) {
url := common.NewURLWithOptions(common.WithPath(refconfig.id),
common.WithProtocol(refconfig.Protocol),
common.WithParams(refconfig.getUrlMap()),
common.WithParamsValue(constant.BEAN_NAME_KEY, refconfig.id),
)
//1. user specified URL, could be peer-to-peer address, or register center's address.
if refconfig.Url != "" {
......@@ -214,7 +218,7 @@ func (refconfig *ReferenceConfig) GenericLoad(id string) {
genericService := NewGenericService(refconfig.id)
SetConsumerService(genericService)
refconfig.id = id
refconfig.Refer()
refconfig.Refer(genericService)
refconfig.Implement(genericService)
return
}
......@@ -184,7 +184,7 @@ func Test_ReferMultireg(t *testing.T) {
extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster)
for _, reference := range consumerConfig.References {
reference.Refer()
reference.Refer(nil)
assert.NotNil(t, reference.invoker)
assert.NotNil(t, reference.pxy)
}
......@@ -197,7 +197,7 @@ func Test_Refer(t *testing.T) {
extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster)
for _, reference := range consumerConfig.References {
reference.Refer()
reference.Refer(nil)
assert.Equal(t, "soa.mock", reference.Params["serviceid"])
assert.NotNil(t, reference.invoker)
assert.NotNil(t, reference.pxy)
......@@ -211,7 +211,7 @@ func Test_ReferAsync(t *testing.T) {
extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster)
for _, reference := range consumerConfig.References {
reference.Refer()
reference.Refer(nil)
assert.Equal(t, "soa.mock", reference.Params["serviceid"])
assert.NotNil(t, reference.invoker)
assert.NotNil(t, reference.pxy)
......@@ -227,7 +227,7 @@ func Test_ReferP2P(t *testing.T) {
m.Url = "dubbo://127.0.0.1:20000"
for _, reference := range consumerConfig.References {
reference.Refer()
reference.Refer(nil)
assert.NotNil(t, reference.invoker)
assert.NotNil(t, reference.pxy)
}
......@@ -241,7 +241,7 @@ func Test_ReferMultiP2P(t *testing.T) {
m.Url = "dubbo://127.0.0.1:20000;dubbo://127.0.0.2:20000"
for _, reference := range consumerConfig.References {
reference.Refer()
reference.Refer(nil)
assert.NotNil(t, reference.invoker)
assert.NotNil(t, reference.pxy)
}
......@@ -256,7 +256,7 @@ func Test_ReferMultiP2PWithReg(t *testing.T) {
m.Url = "dubbo://127.0.0.1:20000;registry://127.0.0.2:20000"
for _, reference := range consumerConfig.References {
reference.Refer()
reference.Refer(nil)
assert.NotNil(t, reference.invoker)
assert.NotNil(t, reference.pxy)
}
......@@ -268,7 +268,7 @@ func Test_Implement(t *testing.T) {
extension.SetProtocol("registry", GetProtocol)
extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster)
for _, reference := range consumerConfig.References {
reference.Refer()
reference.Refer(nil)
reference.Implement(&MockService{})
assert.NotNil(t, reference.GetRPCService())
......@@ -284,7 +284,7 @@ func Test_Forking(t *testing.T) {
m.Url = "dubbo://127.0.0.1:20000;registry://127.0.0.2:20000"
for _, reference := range consumerConfig.References {
reference.Refer()
reference.Refer(nil)
forks := int(reference.invoker.GetUrl().GetParamInt(constant.FORKS_KEY, constant.DEFAULT_FORKS))
assert.Equal(t, 5, forks)
assert.NotNil(t, reference.pxy)
......@@ -301,7 +301,7 @@ func Test_Sticky(t *testing.T) {
m.Url = "dubbo://127.0.0.1:20000;registry://127.0.0.2:20000"
reference := consumerConfig.References["MockService"]
reference.Refer()
reference.Refer(nil)
referenceSticky := reference.invoker.GetUrl().GetParam(constant.STICKY_KEY, "false")
assert.Equal(t, "false", referenceSticky)
......
......@@ -117,8 +117,12 @@ func (srvconfig *ServiceConfig) Export() error {
regUrls := loadRegistries(srvconfig.Registry, providerConfig.Registries, common.PROVIDER)
urlMap := srvconfig.getUrlMap()
for _, proto := range loadProtocol(srvconfig.Protocol, providerConfig.Protocols) {
protocolConfigs := loadProtocol(srvconfig.Protocol, providerConfig.Protocols)
if len(protocolConfigs) == 0 {
logger.Warnf("The service %v's '%v' protocols don't has right protocolConfigs ", srvconfig.InterfaceName, srvconfig.Protocol)
return nil
}
for _, proto := range protocolConfigs {
// registry the service reflect
methods, err := common.ServiceMap.Register(proto.Name, srvconfig.rpcService)
if err != nil {
......
......@@ -93,6 +93,30 @@ func doInitProvider() {
},
},
},
"MockServiceNoRightProtocol": {
InterfaceName: "com.MockService",
Protocol: "mock1",
Registry: "shanghai_reg1,shanghai_reg2,hangzhou_reg1,hangzhou_reg2",
Cluster: "failover",
Loadbalance: "random",
Retries: "3",
Group: "huadong_idc",
Version: "1.0.0",
Methods: []*MethodConfig{
{
Name: "GetUser",
Retries: "2",
Loadbalance: "random",
Weight: 200,
},
{
Name: "GetUser1",
Retries: "2",
Loadbalance: "random",
Weight: 200,
},
},
},
},
Protocols: map[string]*ProtocolConfig{
"mock": {
......
......@@ -58,7 +58,7 @@ func newApolloConfiguration(url *common.URL) (*apolloConfiguration, error) {
configCluster := url.GetParam(constant.CONFIG_CLUSTER_KEY, "")
appId := url.GetParam(constant.CONFIG_APP_ID_KEY, "")
namespaces := url.GetParam(constant.CONFIG_NAMESPACE_KEY, getProperties(DEFAULT_GROUP))
namespaces := getProperties(url.GetParam(constant.CONFIG_NAMESPACE_KEY, DEFAULT_GROUP))
c.appConf = &agollo.AppConfig{
AppId: appId,
Cluster: configCluster,
......
......@@ -192,7 +192,7 @@ func initMockApollo(t *testing.T) *apolloConfiguration {
Address: "106.12.25.204:8080",
AppId: "testApplication_yang",
Cluster: "dev",
Namespace: "mockDubbog.properties",
Namespace: "mockDubbog",
}}
apollo := initApollo()
apolloUrl := strings.ReplaceAll(apollo.URL, "http", "apollo")
......
......@@ -17,12 +17,15 @@
package filter
import (
"context"
)
import (
"github.com/apache/dubbo-go/protocol"
)
// Extension - Filter
type Filter interface {
Invoke(protocol.Invoker, protocol.Invocation) protocol.Result
OnResponse(protocol.Result, protocol.Invoker, protocol.Invocation) protocol.Result
Invoke(context.Context, protocol.Invoker, protocol.Invocation) protocol.Result
OnResponse(context.Context, protocol.Result, protocol.Invoker, protocol.Invocation) protocol.Result
}
......@@ -18,6 +18,7 @@
package filter_impl
import (
"context"
"os"
"reflect"
"strings"
......@@ -66,13 +67,13 @@ type AccessLogFilter struct {
logChan chan AccessLogData
}
func (ef *AccessLogFilter) Invoke(invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
func (ef *AccessLogFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
accessLog := invoker.GetUrl().GetParam(constant.ACCESS_LOG_KEY, "")
if len(accessLog) > 0 {
accessLogData := AccessLogData{data: ef.buildAccessLogData(invoker, invocation), accessLog: accessLog}
ef.logIntoChannel(accessLogData)
}
return invoker.Invoke(invocation)
return invoker.Invoke(ctx, invocation)
}
// it won't block the invocation
......@@ -119,7 +120,7 @@ func (ef *AccessLogFilter) buildAccessLogData(invoker protocol.Invoker, invocati
return dataMap
}
func (ef *AccessLogFilter) OnResponse(result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
func (ef *AccessLogFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
return result
}
......
......@@ -49,7 +49,7 @@ func TestAccessLogFilter_Invoke_Not_Config(t *testing.T) {
inv := invocation.NewRPCInvocation("MethodName", []interface{}{"OK", "Hello"}, attach)
accessLogFilter := GetAccessLogFilter()
result := accessLogFilter.Invoke(invoker, inv)
result := accessLogFilter.Invoke(context.Background(), invoker, inv)
assert.Nil(t, result.Error())
}
......@@ -70,13 +70,13 @@ func TestAccessLogFilter_Invoke_Default_Config(t *testing.T) {
inv := invocation.NewRPCInvocation("MethodName", []interface{}{"OK", "Hello"}, attach)
accessLogFilter := GetAccessLogFilter()
result := accessLogFilter.Invoke(invoker, inv)
result := accessLogFilter.Invoke(context.Background(), invoker, inv)
assert.Nil(t, result.Error())
}
func TestAccessLogFilter_OnResponse(t *testing.T) {
result := &protocol.RPCResult{}
accessLogFilter := GetAccessLogFilter()
response := accessLogFilter.OnResponse(result, nil, nil)
response := accessLogFilter.OnResponse(nil, result, nil, nil)
assert.Equal(t, result, response)
}
......@@ -17,14 +17,23 @@
package filter_impl
import (
"context"
"strconv"
)
import (
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/common/logger"
"github.com/apache/dubbo-go/filter"
"github.com/apache/dubbo-go/protocol"
invocation2 "github.com/apache/dubbo-go/protocol/invocation"
)
const active = "active"
const (
active = "active"
dubboInvokeStartTime = "dubboInvokeStartTime"
)
func init() {
extension.SetFilter(active, GetActiveFilter)
......@@ -33,16 +42,24 @@ func init() {
type ActiveFilter struct {
}
func (ef *ActiveFilter) Invoke(invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
func (ef *ActiveFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
logger.Infof("invoking active filter. %v,%v", invocation.MethodName(), len(invocation.Arguments()))
invocation.(*invocation2.RPCInvocation).SetAttachments(dubboInvokeStartTime, strconv.FormatInt(protocol.CurrentTimeMillis(), 10))
protocol.BeginCount(invoker.GetUrl(), invocation.MethodName())
return invoker.Invoke(invocation)
return invoker.Invoke(ctx, invocation)
}
func (ef *ActiveFilter) OnResponse(result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
func (ef *ActiveFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
protocol.EndCount(invoker.GetUrl(), invocation.MethodName())
startTime, err := strconv.ParseInt(invocation.(*invocation2.RPCInvocation).AttachmentsByKey(dubboInvokeStartTime, "0"), 10, 64)
if err != nil {
result.SetError(err)
logger.Errorf("parse dubbo_invoke_start_time to int64 failed")
return result
}
elapsed := protocol.CurrentTimeMillis() - startTime
protocol.EndCount(invoker.GetUrl(), invocation.MethodName(), elapsed, result.Error() == nil)
return result
}
......
package filter_impl
import (
"context"
"errors"
"strconv"
"testing"
)
import (
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
)
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/protocol"
"github.com/apache/dubbo-go/protocol/invocation"
"github.com/apache/dubbo-go/protocol/mock"
)
func TestActiveFilter_Invoke(t *testing.T) {
invoc := invocation.NewRPCInvocation("test", []interface{}{"OK"}, make(map[string]string, 0))
url, _ := common.NewURL(context.TODO(), "dubbo://192.168.10.10:20000/com.ikurento.user.UserProvider")
filter := ActiveFilter{}
ctrl := gomock.NewController(t)
defer ctrl.Finish()
invoker := mock.NewMockInvoker(ctrl)
invoker.EXPECT().Invoke(gomock.Any()).Return(nil)
invoker.EXPECT().GetUrl().Return(url).Times(1)
filter.Invoke(context.Background(), invoker, invoc)
assert.True(t, invoc.AttachmentsByKey(dubboInvokeStartTime, "") != "")
}
func TestActiveFilter_OnResponse(t *testing.T) {
c := protocol.CurrentTimeMillis()
elapsed := 100
invoc := invocation.NewRPCInvocation("test", []interface{}{"OK"}, map[string]string{
dubboInvokeStartTime: strconv.FormatInt(c-int64(elapsed), 10),
})
url, _ := common.NewURL(context.TODO(), "dubbo://192.168.10.10:20000/com.ikurento.user.UserProvider")
filter := ActiveFilter{}
ctrl := gomock.NewController(t)
defer ctrl.Finish()
invoker := mock.NewMockInvoker(ctrl)
invoker.EXPECT().GetUrl().Return(url).Times(1)
result := &protocol.RPCResult{
Err: errors.New("test"),
}
filter.OnResponse(nil, result, invoker, invoc)
methodStatus := protocol.GetMethodStatus(url, "test")
urlStatus := protocol.GetURLStatus(url)
assert.Equal(t, int32(1), methodStatus.GetTotal())
assert.Equal(t, int32(1), urlStatus.GetTotal())
assert.Equal(t, int32(1), methodStatus.GetFailed())
assert.Equal(t, int32(1), urlStatus.GetFailed())
assert.Equal(t, int32(1), methodStatus.GetSuccessiveRequestFailureCount())
assert.Equal(t, int32(1), urlStatus.GetSuccessiveRequestFailureCount())
assert.True(t, methodStatus.GetFailedElapsed() >= int64(elapsed))
assert.True(t, urlStatus.GetFailedElapsed() >= int64(elapsed))
assert.True(t, urlStatus.GetLastRequestFailedTimestamp() != int64(0))
assert.True(t, methodStatus.GetLastRequestFailedTimestamp() != int64(0))
}
......@@ -17,6 +17,9 @@
package filter_impl
import (
"context"
)
import (
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
......@@ -38,7 +41,7 @@ func init() {
// Echo func(ctx context.Context, arg interface{}, rsp *Xxx) error
type EchoFilter struct{}
func (ef *EchoFilter) Invoke(invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
func (ef *EchoFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
logger.Infof("invoking echo filter.")
logger.Debugf("%v,%v", invocation.MethodName(), len(invocation.Arguments()))
if invocation.MethodName() == constant.ECHO && len(invocation.Arguments()) == 1 {
......@@ -48,10 +51,10 @@ func (ef *EchoFilter) Invoke(invoker protocol.Invoker, invocation protocol.Invoc
}
}
return invoker.Invoke(invocation)
return invoker.Invoke(ctx, invocation)
}
func (ef *EchoFilter) OnResponse(result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
func (ef *EchoFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
return result
}
......
......@@ -18,6 +18,7 @@
package filter_impl
import (
"context"
"testing"
)
......@@ -33,12 +34,10 @@ import (
func TestEchoFilter_Invoke(t *testing.T) {
filter := GetFilter()
result := filter.Invoke(protocol.NewBaseInvoker(common.URL{}),
invocation.NewRPCInvocation("$echo", []interface{}{"OK"}, nil))
result := filter.Invoke(context.Background(), protocol.NewBaseInvoker(common.URL{}), invocation.NewRPCInvocation("$echo", []interface{}{"OK"}, nil))
assert.Equal(t, "OK", result.Result())
result = filter.Invoke(protocol.NewBaseInvoker(common.URL{}),
invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, nil))
result = filter.Invoke(context.Background(), protocol.NewBaseInvoker(common.URL{}), invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, nil))
assert.Nil(t, result.Error())
assert.Nil(t, result.Result())
}
......@@ -18,6 +18,7 @@
package filter_impl
import (
"context"
"strconv"
"sync"
"sync/atomic"
......@@ -75,7 +76,7 @@ type ExecuteState struct {
concurrentCount int64
}
func (ef *ExecuteLimitFilter) Invoke(invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
func (ef *ExecuteLimitFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
methodConfigPrefix := "methods." + invocation.MethodName() + "."
url := invoker.GetUrl()
limitTarget := url.ServiceKey()
......@@ -97,7 +98,7 @@ func (ef *ExecuteLimitFilter) Invoke(invoker protocol.Invoker, invocation protoc
}
if limitRate < 0 {
return invoker.Invoke(invocation)
return invoker.Invoke(ctx, invocation)
}
state, _ := ef.executeState.LoadOrStore(limitTarget, &ExecuteState{
......@@ -113,10 +114,10 @@ func (ef *ExecuteLimitFilter) Invoke(invoker protocol.Invoker, invocation protoc
return extension.GetRejectedExecutionHandler(rejectedHandlerConfig).RejectedExecution(url, invocation)
}
return invoker.Invoke(invocation)
return invoker.Invoke(ctx, invocation)
}
func (ef *ExecuteLimitFilter) OnResponse(result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
func (ef *ExecuteLimitFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
return result
}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment