Skip to content
Snippets Groups Projects
Commit 05c823a7 authored by vito.he's avatar vito.he
Browse files

Mod:merge from develop

parents 78cd7cfb 5145aed5
No related branches found
No related tags found
No related merge requests found
Showing
with 155 additions and 97 deletions
......@@ -10,6 +10,7 @@
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
coverage.txt
*.idea
*.iml
......
......@@ -54,12 +54,23 @@ Todo List:
You can know more about dubbo-go by its [roadmap](https://github.com/apache/dubbo-go/wiki/Roadmap).
## Document
Move [here](https://dubbogo.github.io/dubbo-go-website/)
## Quick Start
The subdirectory examples shows how to use dubbo-go. Please read the [examples/README.md](https://github.com/apache/dubbo-go/blob/develop/examples/README.md) carefully to learn how to dispose the configuration and compile the program.
## Running unit tests
```bash
go test ./...
# coverage
go test ./... -coverprofile=coverage.txt -covermode=atomic
```
## Contributing
If you are willing to do some code contributions and document contributions to [Apache/dubbo-go](https://github.com/apache/dubbo-go), please visit [contribution intro](https://github.com/apache/dubbo-go/blob/master/cg.md).
......
......@@ -54,10 +54,23 @@ Apache License, Version 2.0
你可以通过访问 [roadmap](https://github.com/apache/dubbo-go/wiki/Roadmap) 知道更多关于 dubbo-go 的信息
## 文档
移步[这里](https://dubbogo.github.io/dubbo-go-website/)
## 快速开始 ##
这个子目录下的例子展示了如何使用 dubbo-go 。请仔细阅读 [examples/README.md](https://github.com/apache/dubbo-go/blob/develop/examples/README.md) 学习如何处理配置并编译程序。
## 运行单测
```bash
go test ./...
# 覆盖率
go test ./... -coverprofile=coverage.txt -covermode=atomic
```
## 如何贡献
如果您愿意给 [Apache/dubbo-go](https://github.com/apache/dubbo-go) 贡献代码或者文档,我们都热烈欢迎。具体请参考 [contribution intro](https://github.com/apache/dubbo-go/blob/master/cg.md)
......
......@@ -143,8 +143,7 @@ func Test_FailoverInvoke2(t *testing.T) {
urlParams.Set(constant.RETRIES_KEY, "2")
urlParams.Set("methods.test."+constant.RETRIES_KEY, "3")
ivc := &invocation.RPCInvocation{}
ivc.SetMethod("test")
ivc := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("test"))
result := normalInvoke(t, 3, urlParams, ivc)
assert.NoError(t, result.Error())
count = 0
......
......@@ -43,8 +43,7 @@ func TestLeastActiveByWeight(t *testing.T) {
invokers = append(invokers, protocol.NewBaseInvoker(url))
}
inv := new(invocation.RPCInvocation)
inv.SetMethod("test")
inv := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("test"))
protocol.BeginCount(invokers[2].GetUrl(), inv.MethodName())
loop = 10000
......
......@@ -67,8 +67,7 @@ func Test_RandomlbSelectWeight(t *testing.T) {
urlParams.Set("methods.test."+constant.WEIGHT_KEY, "10000000000000")
urll, _ := common.NewURL(context.TODO(), fmt.Sprintf("dubbo://192.168.1.100:20000/com.ikurento.user.UserProvider"), common.WithParams(urlParams))
invokers = append(invokers, protocol.NewBaseInvoker(urll))
ivc := &invocation.RPCInvocation{}
ivc.SetMethod("test")
ivc := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("test"))
var selectedInvoker []protocol.Invoker
var selected float64
......@@ -99,8 +98,7 @@ func Test_RandomlbSelectWarmup(t *testing.T) {
urlParams.Set(constant.REMOTE_TIMESTAMP_KEY, strconv.FormatInt(time.Now().Add(time.Minute*(-9)).Unix(), 10))
urll, _ := common.NewURL(context.TODO(), fmt.Sprintf("dubbo://192.168.1.100:20000/com.ikurento.user.UserProvider"), common.WithParams(urlParams))
invokers = append(invokers, protocol.NewBaseInvoker(urll))
ivc := &invocation.RPCInvocation{}
ivc.SetMethod("test")
ivc := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("test"))
var selectedInvoker []protocol.Invoker
var selected float64
......
......@@ -40,6 +40,8 @@ const (
PREFIX_DEFAULT_KEY = "default."
DEFAULT_SERVICE_FILTERS = "echo"
DEFAULT_REFERENCE_FILTERS = ""
GENERIC_REFERENCE_FILTERS = "generic"
GENERIC = "$invoke"
ECHO = "$echo"
)
......
......@@ -29,6 +29,8 @@ const (
SERVICE_KEY = "service"
METHODS_KEY = "methods"
TIMEOUT_KEY = "timeout"
BEAN_NAME_KEY = "bean.name"
GENERIC_KEY = "generic"
)
const (
......
......@@ -85,8 +85,6 @@ func InitLog(logConfFile string) error {
InitLogger(conf)
// set getty log
getty.SetLogger(logger)
return nil
}
......@@ -112,9 +110,16 @@ func InitLogger(conf *zap.Config) {
}
zapLogger, _ := zapLoggerConfig.Build(zap.AddCallerSkip(1))
logger = zapLogger.Sugar()
// set getty log
getty.SetLogger(logger)
}
func SetLogger(log Logger) {
logger = log
getty.SetLogger(logger)
}
func GetLogger() Logger {
return logger
}
......@@ -116,7 +116,9 @@ func (p *Proxy) Implement(v common.RPCService) {
}
}
inv = invocation_impl.NewRPCInvocationForConsumer(methodName, nil, inArr, reply.Interface(), p.callBack, common.URL{}, nil)
inv = invocation_impl.NewRPCInvocationWithOptions(invocation_impl.WithMethodName(methodName),
invocation_impl.WithArguments(inArr), invocation_impl.WithReply(reply.Interface()),
invocation_impl.WithCallBack(p.callBack))
for k, value := range p.attachments {
inv.SetAttachments(k, value)
......
......@@ -43,21 +43,15 @@ type TestService struct {
Echo func(interface{}, *interface{}) error
}
func (s *TestService) Service() string {
func (s *TestService) Reference() string {
return "com.test.Path"
}
func (s *TestService) Version() string {
return ""
}
type TestServiceInt int
func (s *TestServiceInt) Service() string {
func (s *TestServiceInt) Reference() string {
return "com.test.TestServiceInt"
}
func (s *TestServiceInt) Version() string {
return ""
}
func TestProxy_Implement(t *testing.T) {
......
......@@ -36,8 +36,7 @@ import (
// rpc service interface
type RPCService interface {
Service() string // Path InterfaceName
Version() string
Reference() string // rpc service id or reference id
}
// for lowercase func
......@@ -149,7 +148,7 @@ func (sm *serviceMap) Register(protocol string, rcvr RPCService) (string, error)
return "", perrors.New(s)
}
sname = rcvr.Service()
sname = rcvr.Reference()
if server := sm.GetService(protocol, sname); server != nil {
return "", perrors.New("service already defined: " + sname)
}
......@@ -172,8 +171,8 @@ func (sm *serviceMap) Register(protocol string, rcvr RPCService) (string, error)
return strings.TrimSuffix(methods, ","), nil
}
func (sm *serviceMap) UnRegister(protocol, serviceName string) error {
if protocol == "" || serviceName == "" {
func (sm *serviceMap) UnRegister(protocol, serviceId string) error {
if protocol == "" || serviceId == "" {
return perrors.New("protocol or serviceName is nil")
}
sm.mutex.RLock()
......@@ -182,16 +181,16 @@ func (sm *serviceMap) UnRegister(protocol, serviceName string) error {
sm.mutex.RUnlock()
return perrors.New("no services for " + protocol)
}
_, ok = svcs[serviceName]
_, ok = svcs[serviceId]
if !ok {
sm.mutex.RUnlock()
return perrors.New("no service for " + serviceName)
return perrors.New("no service for " + serviceId)
}
sm.mutex.RUnlock()
sm.mutex.Lock()
defer sm.mutex.Unlock()
delete(svcs, serviceName)
delete(svcs, serviceId)
delete(sm.serviceMap, protocol)
return nil
......
......@@ -39,12 +39,9 @@ func (s *TestService) MethodTwo(arg1, arg2, arg3 interface{}) (interface{}, erro
func (s *TestService) MethodThree() error {
return nil
}
func (s *TestService) Service() string {
func (s *TestService) Reference() string {
return "com.test.Path"
}
func (s *TestService) Version() string {
return ""
}
func (s *TestService) MethodMapper() map[string]string {
return map[string]string{
"MethodTwo": "methodTwo",
......@@ -65,22 +62,16 @@ func (s *testService) Method3(ctx context.Context, args []interface{}, rsp *stru
func (s *testService) Method4(ctx context.Context, args []interface{}, rsp *struct{}) *testService {
return nil
}
func (s *testService) Service() string {
func (s *testService) Reference() string {
return "com.test.Path"
}
func (s *testService) Version() string {
return ""
}
type TestService1 struct {
}
func (s *TestService1) Service() string {
func (s *TestService1) Reference() string {
return "com.test.Path1"
}
func (s *TestService1) Version() string {
return ""
}
func TestServiceMap_Register(t *testing.T) {
// lowercase
......@@ -181,7 +172,7 @@ func TestSuiteMethod(t *testing.T) {
// wrong number of in return
s1 := &testService{}
method, ok = reflect.TypeOf(s1).MethodByName("Version")
method, ok = reflect.TypeOf(s1).MethodByName("Reference")
assert.True(t, ok)
methodType = suiteMethod(method)
assert.Nil(t, methodType)
......
......@@ -136,6 +136,11 @@ func WithPath(path string) option {
}
}
func WithLocation(location string) option {
return func(url *URL) {
url.Location = location
}
}
func NewURLWithOptions(opts ...option) *URL {
url := &URL{}
for _, opt := range opts {
......
......@@ -107,7 +107,8 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC
setBaseValue := func(f reflect.Value) {
ok, value := config.GetProperty(getKeyPrefix(val, id) + key)
if ok {
if f.Kind() == reflect.Int64 {
switch f.Kind() {
case reflect.Int64:
x, err := strconv.Atoi(value)
if err != nil {
logger.Errorf("Dynamic change the configuration in struct {%v} field {%v} error ,error message is {%v}",
......@@ -120,21 +121,16 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC
val.Type().Name(), val.Type().Field(i).Name, perrors.Errorf("the int64 value {%v} from config center is overflow", int64(x)))
}
}
}
if f.Kind() == reflect.String {
case reflect.String:
f.SetString(value)
}
if f.Kind() == reflect.Bool {
case reflect.Bool:
x, err := strconv.ParseBool(value)
if err != nil {
logger.Errorf("Dynamic change the configuration in struct {%v} field {%v} error ,error message is {%v}",
val.Type().Name(), val.Type().Field(i).Name, err)
}
f.SetBool(x)
}
if f.Kind() == reflect.Float64 {
case reflect.Float64:
x, err := strconv.ParseFloat(value, 64)
if err != nil {
logger.Errorf("Dynamic change the configuration in struct {%v} field {%v} error ,error message is {%v}",
......@@ -147,7 +143,10 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC
val.Type().Name(), val.Type().Field(i).Name, perrors.Errorf("the float64 value {%v} from config center is overflow", x))
}
}
default:
logger.Warnf("The kind of field {%v} is not supported ", f.Kind().String())
}
}
}
......@@ -180,25 +179,32 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC
}
if f.Kind() == reflect.Map {
//initiate config
s := reflect.New(f.Type().Elem().Elem())
prefix := s.MethodByName("Prefix").Call(nil)[0].String()
m := config.GetSubProperty(prefix)
for k := range m {
f.SetMapIndex(reflect.ValueOf(k), reflect.New(f.Type().Elem().Elem()))
if f.Type().Elem().Kind() == reflect.Ptr {
//initiate config
s := reflect.New(f.Type().Elem().Elem())
prefix := s.MethodByName("Prefix").Call(nil)[0].String()
m := config.GetSubProperty(prefix)
for k := range m {
f.SetMapIndex(reflect.ValueOf(k), reflect.New(f.Type().Elem().Elem()))
}
}
//iter := f.MapRange()
for _, k := range f.MapKeys() {
v := f.MapIndex(k)
if v.Kind() == reflect.Ptr {
switch v.Kind() {
case reflect.Ptr:
if v.Elem().Kind() == reflect.Struct {
setFieldValue(v.Elem(), k, config)
} else {
setBaseValue(v.Elem())
}
case reflect.Int64, reflect.String, reflect.Bool, reflect.Float64:
setBaseValue(v)
default:
logger.Warnf("The kind of field {%v} is not supported ", v.Kind().String())
}
}
}
......
......@@ -35,8 +35,8 @@ func Test_refresh(t *testing.T) {
c := &BaseConfig{}
mockMap := map[string]string{}
mockMap["dubbo.registries.shanghai_reg1.protocol"] = "mock100"
mockMap["dubbo.reference.MockService.MockService.retries"] = "10"
mockMap["dubbo.MockService.MockService.GetUser.retries"] = "10"
mockMap["dubbo.reference.com.MockService.MockService.retries"] = "10"
mockMap["dubbo.com.MockService.MockService.GetUser.retries"] = "10"
mockMap["dubbo.consumer.check"] = "false"
mockMap["dubbo.application.name"] = "dubbo"
......@@ -88,7 +88,7 @@ func Test_refresh(t *testing.T) {
},
References: map[string]*ReferenceConfig{
"MockService": {
InterfaceName: "MockService",
InterfaceName: "com.MockService",
Protocol: "mock",
Cluster: "failover",
Loadbalance: "random",
......@@ -98,13 +98,14 @@ func Test_refresh(t *testing.T) {
Methods: []*MethodConfig{
{
InterfaceId: "MockService",
InterfaceName: "MockService",
InterfaceName: "com.MockService",
Name: "GetUser",
Retries: 2,
Loadbalance: "random",
},
{InterfaceId: "MockService",
InterfaceName: "MockService",
{
InterfaceId: "MockService",
InterfaceName: "com.MockService",
Name: "GetUser1",
Retries: 2,
Loadbalance: "random",
......@@ -128,8 +129,8 @@ func Test_refreshProvider(t *testing.T) {
c := &BaseConfig{}
mockMap := map[string]string{}
mockMap["dubbo.registries.shanghai_reg1.protocol"] = "mock100"
mockMap["dubbo.service.MockService.MockService.retries"] = "10"
mockMap["dubbo.MockService.MockService.GetUser.retries"] = "10"
mockMap["dubbo.service.com.MockService.MockService.retries"] = "10"
mockMap["dubbo.com.MockService.MockService.GetUser.retries"] = "10"
mockMap["dubbo.consumer.check"] = "false"
mockMap["dubbo.application.name"] = "dubbo"
mockMap["dubbo.protocols.jsonrpc1.name"] = "jsonrpc"
......@@ -183,7 +184,7 @@ func Test_refreshProvider(t *testing.T) {
},
Services: map[string]*ServiceConfig{
"MockService": {
InterfaceName: "MockService",
InterfaceName: "com.MockService",
Protocol: "mock",
Cluster: "failover",
Loadbalance: "random",
......@@ -193,13 +194,13 @@ func Test_refreshProvider(t *testing.T) {
Methods: []*MethodConfig{
{
InterfaceId: "MockService",
InterfaceName: "MockService",
InterfaceName: "com.MockService",
Name: "GetUser",
Retries: 2,
Loadbalance: "random",
},
{InterfaceId: "MockService",
InterfaceName: "MockService",
InterfaceName: "com.MockService",
Name: "GetUser1",
Retries: 2,
Loadbalance: "random",
......
......@@ -46,11 +46,11 @@ func init() {
confConFile = os.Getenv(constant.CONF_CONSUMER_FILE_PATH)
confProFile = os.Getenv(constant.CONF_PROVIDER_FILE_PATH)
if errCon := consumerInit(confConFile); errCon != nil {
if errCon := ConsumerInit(confConFile); errCon != nil {
log.Printf("[consumerInit] %#v", errCon)
consumerConfig = nil
}
if errPro := providerInit(confProFile); errPro != nil {
if errPro := ProviderInit(confProFile); errPro != nil {
log.Printf("[providerInit] %#v", errPro)
providerConfig = nil
}
......@@ -58,11 +58,6 @@ func init() {
// Dubbo Init
func Load() {
var (
refMap map[string]*ReferenceConfig
srvMap map[string]*ServiceConfig
)
// reference config
if consumerConfig == nil {
logger.Warnf("consumerConfig is nil!")
......@@ -70,18 +65,20 @@ func Load() {
if err := configCenterRefreshConsumer(); err != nil {
logger.Errorf("[consumer config center refresh] %#v", err)
}
refMap = make(map[string]*ReferenceConfig)
for _, ref := range consumerConfig.References {
rpcService := GetConsumerService(ref.InterfaceName)
for key, ref := range consumerConfig.References {
if ref.Generic {
genericService := NewGenericService(key)
SetConsumerService(genericService)
}
rpcService := GetConsumerService(key)
if rpcService == nil {
logger.Warnf("%s is not exsist!", ref.InterfaceName)
logger.Warnf("%s is not exsist!", key)
continue
}
ref.id = key
ref.Refer()
ref.Implement(rpcService)
refMap[ref.InterfaceName] = ref
}
//wait for invoker is available, if wait over default 3s, then panic
var count int
......@@ -121,18 +118,17 @@ func Load() {
if err := configCenterRefreshProvider(); err != nil {
logger.Errorf("[provider config center refresh] %#v", err)
}
srvMap = make(map[string]*ServiceConfig)
for _, svs := range providerConfig.Services {
rpcService := GetProviderService(svs.InterfaceName)
for key, svs := range providerConfig.Services {
rpcService := GetProviderService(key)
if rpcService == nil {
logger.Warnf("%s is not exsist!", svs.InterfaceName)
logger.Warnf("%s is not exsist!", key)
continue
}
svs.id = key
svs.Implement(rpcService)
if err := svs.Export(); err != nil {
panic(fmt.Sprintf("service %s export failed! ", svs.InterfaceName))
panic(fmt.Sprintf("service %s export failed! ", key))
}
srvMap[svs.InterfaceName] = svs
}
}
}
......@@ -144,5 +140,5 @@ func GetRPCService(name string) common.RPCService {
// create rpc service for consumer
func RPCService(service common.RPCService) {
providerConfig.Services[service.Service()].Implement(service)
consumerConfig.References[service.Reference()].Implement(service)
}
......@@ -45,15 +45,16 @@ func TestConfigLoader(t *testing.T) {
assert.Nil(t, providerConfig)
assert.Equal(t, ProviderConfig{}, GetProviderConfig())
err = consumerInit(conPath)
err = ConsumerInit(conPath)
assert.NoError(t, err)
err = providerInit(proPath)
err = ProviderInit(proPath)
assert.NoError(t, err)
assert.NotNil(t, consumerConfig)
assert.NotEqual(t, ConsumerConfig{}, GetConsumerConfig())
assert.NotNil(t, providerConfig)
assert.NotEqual(t, ProviderConfig{}, GetProviderConfig())
assert.Equal(t, "soa.com.ikurento.user.UserProvider", GetConsumerConfig().References["UserProvider"].Params["serviceid"])
}
func TestLoad(t *testing.T) {
......@@ -70,12 +71,12 @@ func TestLoad(t *testing.T) {
Load()
assert.Equal(t, ms, GetRPCService(ms.Service()))
assert.Equal(t, ms, GetRPCService(ms.Reference()))
ms2 := &struct {
MockService
}{}
RPCService(ms2)
assert.NotEqual(t, ms2, GetRPCService(ms2.Service()))
assert.NotEqual(t, ms2, GetRPCService(ms2.Reference()))
conServices = map[string]common.RPCService{}
proServices = map[string]common.RPCService{}
......@@ -83,6 +84,7 @@ func TestLoad(t *testing.T) {
consumerConfig = nil
providerConfig = nil
}
func TestWithNoRegLoad(t *testing.T) {
doInit()
doinit()
......@@ -98,12 +100,12 @@ func TestWithNoRegLoad(t *testing.T) {
Load()
assert.Equal(t, ms, GetRPCService(ms.Service()))
assert.Equal(t, ms, GetRPCService(ms.Reference()))
ms2 := &struct {
MockService
}{}
RPCService(ms2)
assert.NotEqual(t, ms2, GetRPCService(ms2.Service()))
assert.NotEqual(t, ms2, GetRPCService(ms2.Reference()))
conServices = map[string]common.RPCService{}
proServices = map[string]common.RPCService{}
......@@ -111,6 +113,7 @@ func TestWithNoRegLoad(t *testing.T) {
consumerConfig = nil
providerConfig = nil
}
func TestConfigLoaderWithConfigCenter(t *testing.T) {
extension.SetConfigCenterFactory("mock", func() config_center.DynamicConfigurationFactory {
return &config_center.MockDynamicConfigurationFactory{}
......@@ -126,10 +129,10 @@ func TestConfigLoaderWithConfigCenter(t *testing.T) {
assert.Nil(t, providerConfig)
assert.Equal(t, ProviderConfig{}, GetProviderConfig())
err = consumerInit(conPath)
err = ConsumerInit(conPath)
configCenterRefreshConsumer()
assert.NoError(t, err)
err = providerInit(proPath)
err = ProviderInit(proPath)
configCenterRefreshProvider()
assert.NoError(t, err)
......
......@@ -61,6 +61,7 @@ func (*ConsumerConfig) Prefix() string {
func SetConsumerConfig(c ConsumerConfig) {
consumerConfig = &c
}
func GetConsumerConfig() ConsumerConfig {
if consumerConfig == nil {
logger.Warnf("consumerConfig is nil!")
......@@ -69,7 +70,7 @@ func GetConsumerConfig() ConsumerConfig {
return *consumerConfig
}
func consumerInit(confConFile string) error {
func ConsumerInit(confConFile string) error {
if confConFile == "" {
return perrors.Errorf("application configure(consumer) file name is nil")
}
......
/*
* 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 config
type GenericService struct {
Invoke func(req []interface{}) (interface{}, error) `dubbo:"$invoke"`
referenceStr string
}
func NewGenericService(referenceStr string) *GenericService {
return &GenericService{referenceStr: referenceStr}
}
func (u *GenericService) Reference() string {
return u.referenceStr
}
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