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

Merge branch 'develop' into metadata_report

parents e204bc23 8394c305
No related branches found
No related tags found
No related merge requests found
Showing
with 119 additions and 56 deletions
...@@ -16,6 +16,8 @@ Apache License, Version 2.0 ...@@ -16,6 +16,8 @@ Apache License, Version 2.0
## Release note ## ## Release note ##
[v1.4.0-rc1 - Mar 12, 2020](https://github.com/apache/dubbo-go/releases/tag/v1.4.0-rc1)
[v1.3.0 - Mar 1, 2020](https://github.com/apache/dubbo-go/releases/tag/v1.3.0) [v1.3.0 - Mar 1, 2020](https://github.com/apache/dubbo-go/releases/tag/v1.3.0)
[v1.2.0 - Nov 15, 2019](https://github.com/apache/dubbo-go/releases/tag/v1.2.0) [v1.2.0 - Nov 15, 2019](https://github.com/apache/dubbo-go/releases/tag/v1.2.0)
...@@ -28,7 +30,7 @@ Apache License, Version 2.0 ...@@ -28,7 +30,7 @@ Apache License, Version 2.0
Both extension module and layered project architecture is according to Apache Dubbo (including protocol layer, registry layer, cluster layer, config layer and so on), the advantage of this arch is as following: you can implement these layered interfaces in your own way, override the default implementation of dubbo-go by calling 'extension.SetXXX' of extension, complete your special needs without modifying the source code. At the same time, you are welcome to contribute implementation of useful extension to the community. Both extension module and layered project architecture is according to Apache Dubbo (including protocol layer, registry layer, cluster layer, config layer and so on), the advantage of this arch is as following: you can implement these layered interfaces in your own way, override the default implementation of dubbo-go by calling 'extension.SetXXX' of extension, complete your special needs without modifying the source code. At the same time, you are welcome to contribute implementation of useful extension to the community.
![frame design](https://raw.githubusercontent.com/wiki/dubbo/dubbo-go/dubbo-go%E4%BB%A3%E7%A0%81%E5%88%86%E5%B1%82%E8%AE%BE%E8%AE%A1.png) ![dubbo go extend](./doc/pic/arch/dubbo-go-ext.png)
If you wanna know more about dubbo-go, please visit this reference [Project Architeture design](https://github.com/apache/dubbo-go/wiki/dubbo-go-V1.0-design) If you wanna know more about dubbo-go, please visit this reference [Project Architeture design](https://github.com/apache/dubbo-go/wiki/dubbo-go-V1.0-design)
......
...@@ -15,6 +15,8 @@ Apache License, Version 2.0 ...@@ -15,6 +15,8 @@ Apache License, Version 2.0
## 发布日志 ## ## 发布日志 ##
[v1.4.0-rc1 - 2020年3月12日](https://github.com/apache/dubbo-go/releases/tag/v1.4.0-rc1)
[v1.3.0 - 2020年3月1日](https://github.com/apache/dubbo-go/releases/tag/v1.3.0) [v1.3.0 - 2020年3月1日](https://github.com/apache/dubbo-go/releases/tag/v1.3.0)
[v1.2.0 - 2019年11月15日](https://github.com/apache/dubbo-go/releases/tag/v1.2.0) [v1.2.0 - 2019年11月15日](https://github.com/apache/dubbo-go/releases/tag/v1.2.0)
...@@ -27,7 +29,7 @@ Apache License, Version 2.0 ...@@ -27,7 +29,7 @@ Apache License, Version 2.0
基于dubbo的extension模块和分层的代码设计(包括 protocol layer, registry layer, cluster layer, config 等等)。我们的目标是:你可以对这些分层接口进行新的实现,并通过调用 extension 模块的“ extension.SetXXX ”方法来覆盖 dubbo-go [同 go-for-apache-dubbo ]的默认实现,以完成自己的特殊需求而无需修改源代码。同时,欢迎你为社区贡献有用的拓展实现。 基于dubbo的extension模块和分层的代码设计(包括 protocol layer, registry layer, cluster layer, config 等等)。我们的目标是:你可以对这些分层接口进行新的实现,并通过调用 extension 模块的“ extension.SetXXX ”方法来覆盖 dubbo-go [同 go-for-apache-dubbo ]的默认实现,以完成自己的特殊需求而无需修改源代码。同时,欢迎你为社区贡献有用的拓展实现。
![框架设计](https://raw.githubusercontent.com/wiki/dubbo/dubbo-go/dubbo-go%E4%BB%A3%E7%A0%81%E5%88%86%E5%B1%82%E8%AE%BE%E8%AE%A1.png) ![dubbo go extend](./doc/pic/arch/dubbo-go-ext.png)
关于详细设计请阅读 [code layered design](https://github.com/apache/dubbo-go/wiki/dubbo-go-V1.0-design) 关于详细设计请阅读 [code layered design](https://github.com/apache/dubbo-go/wiki/dubbo-go-V1.0-design)
......
...@@ -71,7 +71,8 @@ var ( ...@@ -71,7 +71,8 @@ var (
// ServiceMap ... // ServiceMap ...
// todo: lowerecas? // todo: lowerecas?
ServiceMap = &serviceMap{ ServiceMap = &serviceMap{
serviceMap: make(map[string]map[string]*Service), serviceMap: make(map[string]map[string]*Service),
interfaceMap: make(map[string][]*Service),
} }
) )
...@@ -152,10 +153,12 @@ func (s *Service) Rcvr() reflect.Value { ...@@ -152,10 +153,12 @@ func (s *Service) Rcvr() reflect.Value {
////////////////////////// //////////////////////////
type serviceMap struct { type serviceMap struct {
mutex sync.RWMutex // protects the serviceMap mutex sync.RWMutex // protects the serviceMap
serviceMap map[string]map[string]*Service // protocol -> service name -> service serviceMap map[string]map[string]*Service // protocol -> service name -> service
interfaceMap map[string][]*Service // interface -> service
} }
// GetService get a service defination by protocol and name
func (sm *serviceMap) GetService(protocol, name string) *Service { func (sm *serviceMap) GetService(protocol, name string) *Service {
sm.mutex.RLock() sm.mutex.RLock()
defer sm.mutex.RUnlock() defer sm.mutex.RUnlock()
...@@ -168,10 +171,24 @@ func (sm *serviceMap) GetService(protocol, name string) *Service { ...@@ -168,10 +171,24 @@ func (sm *serviceMap) GetService(protocol, name string) *Service {
return nil return nil
} }
func (sm *serviceMap) Register(protocol string, rcvr RPCService) (string, error) { // GetInterface get an interface defination by interface name
func (sm *serviceMap) GetInterface(interfaceName string) []*Service {
sm.mutex.RLock()
defer sm.mutex.RUnlock()
if s, ok := sm.interfaceMap[interfaceName]; ok {
return s
}
return nil
}
// Register register a service by @interfaceName and @protocol
func (sm *serviceMap) Register(interfaceName, protocol string, rcvr RPCService) (string, error) {
if sm.serviceMap[protocol] == nil { if sm.serviceMap[protocol] == nil {
sm.serviceMap[protocol] = make(map[string]*Service) sm.serviceMap[protocol] = make(map[string]*Service)
} }
if sm.interfaceMap[interfaceName] == nil {
sm.interfaceMap[interfaceName] = make([]*Service, 0, 16)
}
s := new(Service) s := new(Service)
s.rcvrType = reflect.TypeOf(rcvr) s.rcvrType = reflect.TypeOf(rcvr)
...@@ -206,32 +223,65 @@ func (sm *serviceMap) Register(protocol string, rcvr RPCService) (string, error) ...@@ -206,32 +223,65 @@ func (sm *serviceMap) Register(protocol string, rcvr RPCService) (string, error)
} }
sm.mutex.Lock() sm.mutex.Lock()
sm.serviceMap[protocol][s.name] = s sm.serviceMap[protocol][s.name] = s
sm.interfaceMap[interfaceName] = append(sm.interfaceMap[interfaceName], s)
sm.mutex.Unlock() sm.mutex.Unlock()
return strings.TrimSuffix(methods, ","), nil return strings.TrimSuffix(methods, ","), nil
} }
func (sm *serviceMap) UnRegister(protocol, serviceId string) error { // UnRegister cancel a service by @interfaceName, @protocol and @serviceId
func (sm *serviceMap) UnRegister(interfaceName, protocol, serviceId string) error {
if protocol == "" || serviceId == "" { if protocol == "" || serviceId == "" {
return perrors.New("protocol or serviceName is nil") return perrors.New("protocol or serviceName is nil")
} }
sm.mutex.RLock()
svcs, ok := sm.serviceMap[protocol] var (
if !ok { err error
sm.mutex.RUnlock() index = -1
return perrors.New("no services for " + protocol) svcs map[string]*Service
svrs []*Service
ok bool
)
f := func() error {
sm.mutex.RLock()
defer sm.mutex.RUnlock()
svcs, ok = sm.serviceMap[protocol]
if !ok {
return perrors.New("no services for " + protocol)
}
s, ok := svcs[serviceId]
if !ok {
return perrors.New("no service for " + serviceId)
}
svrs, ok = sm.interfaceMap[interfaceName]
if !ok {
return perrors.New("no service for " + interfaceName)
}
for i, svr := range svrs {
if svr == s {
index = i
}
}
return nil
} }
_, ok = svcs[serviceId]
if !ok { if err = f(); err != nil {
sm.mutex.RUnlock() return err
return perrors.New("no service for " + serviceId)
} }
sm.mutex.RUnlock()
sm.mutex.Lock() sm.mutex.Lock()
defer sm.mutex.Unlock() defer sm.mutex.Unlock()
sm.interfaceMap[interfaceName] = make([]*Service, 0, len(svrs))
for i, _ := range svrs {
if i != index {
sm.interfaceMap[interfaceName] = append(sm.interfaceMap[interfaceName], svrs[i])
}
}
delete(svcs, serviceId) delete(svcs, serviceId)
delete(sm.serviceMap, protocol) if len(sm.serviceMap) == 0 {
delete(sm.serviceMap, protocol)
}
return nil return nil
} }
......
...@@ -77,46 +77,48 @@ func TestServiceMap_Register(t *testing.T) { ...@@ -77,46 +77,48 @@ func TestServiceMap_Register(t *testing.T) {
// lowercase // lowercase
s0 := &testService{} s0 := &testService{}
// methods, err := ServiceMap.Register("testporotocol", s0) // methods, err := ServiceMap.Register("testporotocol", s0)
_, err := ServiceMap.Register("testporotocol", s0) _, err := ServiceMap.Register("testService", "testporotocol", s0)
assert.EqualError(t, err, "type testService is not exported") assert.EqualError(t, err, "type testService is not exported")
// succ // succ
s := &TestService{} s := &TestService{}
methods, err := ServiceMap.Register("testporotocol", s) methods, err := ServiceMap.Register("testService", "testporotocol", s)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "MethodOne,MethodThree,methodTwo", methods) assert.Equal(t, "MethodOne,MethodThree,methodTwo", methods)
// repeat // repeat
_, err = ServiceMap.Register("testporotocol", s) _, err = ServiceMap.Register("testService", "testporotocol", s)
assert.EqualError(t, err, "service already defined: com.test.Path") assert.EqualError(t, err, "service already defined: com.test.Path")
// no method // no method
s1 := &TestService1{} s1 := &TestService1{}
_, err = ServiceMap.Register("testporotocol", s1) _, err = ServiceMap.Register("testService", "testporotocol", s1)
assert.EqualError(t, err, "type com.test.Path1 has no exported methods of suitable type") assert.EqualError(t, err, "type com.test.Path1 has no exported methods of suitable type")
ServiceMap = &serviceMap{ ServiceMap = &serviceMap{
serviceMap: make(map[string]map[string]*Service), serviceMap: make(map[string]map[string]*Service),
interfaceMap: make(map[string][]*Service),
} }
} }
func TestServiceMap_UnRegister(t *testing.T) { func TestServiceMap_UnRegister(t *testing.T) {
s := &TestService{} s := &TestService{}
_, err := ServiceMap.Register("testprotocol", s) _, err := ServiceMap.Register("TestService", "testprotocol", s)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, ServiceMap.GetService("testprotocol", "com.test.Path")) assert.NotNil(t, ServiceMap.GetService("testprotocol", "com.test.Path"))
assert.Equal(t, 1, len(ServiceMap.GetInterface("TestService")))
err = ServiceMap.UnRegister("", "com.test.Path") err = ServiceMap.UnRegister("", "", "com.test.Path")
assert.EqualError(t, err, "protocol or serviceName is nil") assert.EqualError(t, err, "protocol or serviceName is nil")
err = ServiceMap.UnRegister("protocol", "com.test.Path") err = ServiceMap.UnRegister("", "protocol", "com.test.Path")
assert.EqualError(t, err, "no services for protocol") assert.EqualError(t, err, "no services for protocol")
err = ServiceMap.UnRegister("testprotocol", "com.test.Path1") err = ServiceMap.UnRegister("", "testprotocol", "com.test.Path1")
assert.EqualError(t, err, "no service for com.test.Path1") assert.EqualError(t, err, "no service for com.test.Path1")
// succ // succ
err = ServiceMap.UnRegister("testprotocol", "com.test.Path") err = ServiceMap.UnRegister("TestService", "testprotocol", "com.test.Path")
assert.NoError(t, err) assert.NoError(t, err)
} }
......
...@@ -200,7 +200,7 @@ func Load() { ...@@ -200,7 +200,7 @@ func Load() {
svs.Implement(rpcService) svs.Implement(rpcService)
svs.Protocols = providerConfig.Protocols svs.Protocols = providerConfig.Protocols
if err := svs.Export(); err != nil { if err := svs.Export(); err != nil {
panic(fmt.Sprintf("service %s export failed! ", key)) panic(fmt.Sprintf("service %s export failed! err: %#v", key, err))
} }
} }
} }
......
...@@ -82,7 +82,8 @@ func TestLoad(t *testing.T) { ...@@ -82,7 +82,8 @@ func TestLoad(t *testing.T) {
conServices = map[string]common.RPCService{} conServices = map[string]common.RPCService{}
proServices = map[string]common.RPCService{} proServices = map[string]common.RPCService{}
common.ServiceMap.UnRegister("mock", "MockService") err := common.ServiceMap.UnRegister("com.MockService", "mock", "MockService")
assert.Nil(t, err)
consumerConfig = nil consumerConfig = nil
providerConfig = nil providerConfig = nil
} }
...@@ -110,7 +111,7 @@ func TestLoadWithSingleReg(t *testing.T) { ...@@ -110,7 +111,7 @@ func TestLoadWithSingleReg(t *testing.T) {
conServices = map[string]common.RPCService{} conServices = map[string]common.RPCService{}
proServices = map[string]common.RPCService{} proServices = map[string]common.RPCService{}
common.ServiceMap.UnRegister("mock", "MockService") common.ServiceMap.UnRegister("com.MockService", "mock", "MockService")
consumerConfig = nil consumerConfig = nil
providerConfig = nil providerConfig = nil
} }
...@@ -139,7 +140,7 @@ func TestWithNoRegLoad(t *testing.T) { ...@@ -139,7 +140,7 @@ func TestWithNoRegLoad(t *testing.T) {
conServices = map[string]common.RPCService{} conServices = map[string]common.RPCService{}
proServices = map[string]common.RPCService{} proServices = map[string]common.RPCService{}
common.ServiceMap.UnRegister("mock", "MockService") common.ServiceMap.UnRegister("com.MockService", "mock", "MockService")
consumerConfig = nil consumerConfig = nil
providerConfig = nil providerConfig = nil
} }
......
...@@ -188,7 +188,7 @@ func (c *ReferenceConfig) getUrlMap() url.Values { ...@@ -188,7 +188,7 @@ func (c *ReferenceConfig) getUrlMap() url.Values {
urlMap.Set(constant.VERSION_KEY, c.Version) urlMap.Set(constant.VERSION_KEY, c.Version)
urlMap.Set(constant.GENERIC_KEY, strconv.FormatBool(c.Generic)) urlMap.Set(constant.GENERIC_KEY, strconv.FormatBool(c.Generic))
urlMap.Set(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER)) urlMap.Set(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER))
urlMap.Set(constant.CATEGORY_KEY, (common.RoleType(common.CONSUMER)).String())
urlMap.Set(constant.RELEASE_KEY, "dubbo-golang-"+constant.Version) urlMap.Set(constant.RELEASE_KEY, "dubbo-golang-"+constant.Version)
urlMap.Set(constant.SIDE_KEY, (common.RoleType(common.CONSUMER)).Role()) urlMap.Set(constant.SIDE_KEY, (common.RoleType(common.CONSUMER)).Role())
......
...@@ -138,7 +138,7 @@ func (c *ServiceConfig) Export() error { ...@@ -138,7 +138,7 @@ func (c *ServiceConfig) Export() error {
} }
for _, proto := range protocolConfigs { for _, proto := range protocolConfigs {
// registry the service reflect // registry the service reflect
methods, err := common.ServiceMap.Register(proto.Name, c.rpcService) methods, err := common.ServiceMap.Register(c.InterfaceName, proto.Name, c.rpcService)
if err != nil { if err != nil {
err := perrors.Errorf("The service %v export the protocol %v error! Error message is %v .", c.InterfaceName, proto.Name, err.Error()) err := perrors.Errorf("The service %v export the protocol %v error! Error message is %v .", c.InterfaceName, proto.Name, err.Error())
logger.Errorf(err.Error()) logger.Errorf(err.Error())
...@@ -225,7 +225,6 @@ func (c *ServiceConfig) getUrlMap() url.Values { ...@@ -225,7 +225,6 @@ func (c *ServiceConfig) getUrlMap() url.Values {
urlMap.Set(constant.GROUP_KEY, c.Group) urlMap.Set(constant.GROUP_KEY, c.Group)
urlMap.Set(constant.VERSION_KEY, c.Version) urlMap.Set(constant.VERSION_KEY, c.Version)
urlMap.Set(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER)) urlMap.Set(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))
urlMap.Set(constant.CATEGORY_KEY, (common.RoleType(common.PROVIDER)).String())
urlMap.Set(constant.RELEASE_KEY, "dubbo-golang-"+constant.Version) urlMap.Set(constant.RELEASE_KEY, "dubbo-golang-"+constant.Version)
urlMap.Set(constant.SIDE_KEY, (common.RoleType(common.PROVIDER)).Role()) urlMap.Set(constant.SIDE_KEY, (common.RoleType(common.PROVIDER)).Role())
......
...@@ -76,7 +76,7 @@ func newZookeeperDynamicConfiguration(url *common.URL) (*zookeeperDynamicConfigu ...@@ -76,7 +76,7 @@ func newZookeeperDynamicConfiguration(url *common.URL) (*zookeeperDynamicConfigu
c.cacheListener = NewCacheListener(c.rootPath) c.cacheListener = NewCacheListener(c.rootPath)
err = c.client.Create(c.rootPath) err = c.client.Create(c.rootPath)
c.listener.ListenServiceEvent(c.rootPath, c.cacheListener) c.listener.ListenServiceEvent(url, c.rootPath, c.cacheListener)
return c, err return c, err
} }
...@@ -102,7 +102,7 @@ func newMockZookeeperDynamicConfiguration(url *common.URL, opts ...zookeeper.Opt ...@@ -102,7 +102,7 @@ func newMockZookeeperDynamicConfiguration(url *common.URL, opts ...zookeeper.Opt
c.cacheListener = NewCacheListener(c.rootPath) c.cacheListener = NewCacheListener(c.rootPath)
err = c.client.Create(c.rootPath) err = c.client.Create(c.rootPath)
go c.listener.ListenServiceEvent(c.rootPath, c.cacheListener) go c.listener.ListenServiceEvent(url, c.rootPath, c.cacheListener)
return tc, c, err return tc, c, err
} }
......
doc/pic/arch/dubbo-go-arch.png

211 KiB | W: | H:

doc/pic/arch/dubbo-go-arch.png

128 KiB | W: | H:

doc/pic/arch/dubbo-go-arch.png
doc/pic/arch/dubbo-go-arch.png
doc/pic/arch/dubbo-go-arch.png
doc/pic/arch/dubbo-go-arch.png
  • 2-up
  • Swipe
  • Onion skin
doc/pic/arch/dubbo-go-ext.png

119 KiB

...@@ -96,7 +96,7 @@ func TestGenericServiceFilter_Invoke(t *testing.T) { ...@@ -96,7 +96,7 @@ func TestGenericServiceFilter_Invoke(t *testing.T) {
hessian.Object("222")}, hessian.Object("222")},
} }
s := &TestService{} s := &TestService{}
_, _ = common.ServiceMap.Register("testprotocol", s) _, _ = common.ServiceMap.Register("TestService", "testprotocol", s)
rpcInvocation := invocation.NewRPCInvocation(methodName, aurguments, nil) rpcInvocation := invocation.NewRPCInvocation(methodName, aurguments, nil)
filter := GetGenericServiceFilter() filter := GetGenericServiceFilter()
url, _ := common.NewURL("testprotocol://127.0.0.1:20000/com.test.Path") url, _ := common.NewURL("testprotocol://127.0.0.1:20000/com.test.Path")
......
...@@ -162,7 +162,7 @@ func InitTest(t *testing.T) (protocol.Protocol, common.URL) { ...@@ -162,7 +162,7 @@ func InitTest(t *testing.T) (protocol.Protocol, common.URL) {
hessian.RegisterPOJO(&User{}) hessian.RegisterPOJO(&User{})
methods, err := common.ServiceMap.Register("dubbo", &UserProvider{}) methods, err := common.ServiceMap.Register("com.ikurento.user.UserProvider", "dubbo", &UserProvider{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "GetBigPkg,GetUser,GetUser0,GetUser1,GetUser2,GetUser3,GetUser4,GetUser5,GetUser6", methods) assert.Equal(t, "GetBigPkg,GetUser,GetUser0,GetUser1,GetUser2,GetUser3,GetUser4,GetUser5,GetUser6", methods)
......
...@@ -43,8 +43,9 @@ func NewDubboExporter(key string, invoker protocol.Invoker, exporterMap *sync.Ma ...@@ -43,8 +43,9 @@ func NewDubboExporter(key string, invoker protocol.Invoker, exporterMap *sync.Ma
// Unexport ... // Unexport ...
func (de *DubboExporter) Unexport() { func (de *DubboExporter) Unexport() {
serviceId := de.GetInvoker().GetUrl().GetParam(constant.BEAN_NAME_KEY, "") serviceId := de.GetInvoker().GetUrl().GetParam(constant.BEAN_NAME_KEY, "")
interfaceName := de.GetInvoker().GetUrl().GetParam(constant.INTERFACE_KEY, "")
de.BaseExporter.Unexport() de.BaseExporter.Unexport()
err := common.ServiceMap.UnRegister(DUBBO, serviceId) err := common.ServiceMap.UnRegister(interfaceName, DUBBO, serviceId)
if err != nil { if err != nil {
logger.Errorf("[DubboExporter.Unexport] error: %v", err) logger.Errorf("[DubboExporter.Unexport] error: %v", err)
} }
......
...@@ -43,8 +43,9 @@ func NewGrpcExporter(key string, invoker protocol.Invoker, exporterMap *sync.Map ...@@ -43,8 +43,9 @@ func NewGrpcExporter(key string, invoker protocol.Invoker, exporterMap *sync.Map
// Unexport ... // Unexport ...
func (gg *GrpcExporter) Unexport() { func (gg *GrpcExporter) Unexport() {
serviceId := gg.GetInvoker().GetUrl().GetParam(constant.BEAN_NAME_KEY, "") serviceId := gg.GetInvoker().GetUrl().GetParam(constant.BEAN_NAME_KEY, "")
interfaceName := gg.GetInvoker().GetUrl().GetParam(constant.INTERFACE_KEY, "")
gg.BaseExporter.Unexport() gg.BaseExporter.Unexport()
err := common.ServiceMap.UnRegister(GRPC, serviceId) err := common.ServiceMap.UnRegister(interfaceName, GRPC, serviceId)
if err != nil { if err != nil {
logger.Errorf("[GrpcExporter.Unexport] error: %v", err) logger.Errorf("[GrpcExporter.Unexport] error: %v", err)
} }
......
...@@ -50,7 +50,7 @@ type ( ...@@ -50,7 +50,7 @@ type (
func TestHTTPClient_Call(t *testing.T) { func TestHTTPClient_Call(t *testing.T) {
methods, err := common.ServiceMap.Register("jsonrpc", &UserProvider{}) methods, err := common.ServiceMap.Register("com.ikurento.user.UserProvider", "jsonrpc", &UserProvider{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "GetUser,GetUser0,GetUser1,GetUser2,GetUser3,GetUser4", methods) assert.Equal(t, "GetUser,GetUser0,GetUser1,GetUser2,GetUser3,GetUser4", methods)
......
...@@ -43,8 +43,9 @@ func NewJsonrpcExporter(key string, invoker protocol.Invoker, exporterMap *sync. ...@@ -43,8 +43,9 @@ func NewJsonrpcExporter(key string, invoker protocol.Invoker, exporterMap *sync.
// Unexport ... // Unexport ...
func (je *JsonrpcExporter) Unexport() { func (je *JsonrpcExporter) Unexport() {
serviceId := je.GetInvoker().GetUrl().GetParam(constant.BEAN_NAME_KEY, "") serviceId := je.GetInvoker().GetUrl().GetParam(constant.BEAN_NAME_KEY, "")
interfaceName := je.GetInvoker().GetUrl().GetParam(constant.INTERFACE_KEY, "")
je.BaseExporter.Unexport() je.BaseExporter.Unexport()
err := common.ServiceMap.UnRegister(JSONRPC, serviceId) err := common.ServiceMap.UnRegister(interfaceName, JSONRPC, serviceId)
if err != nil { if err != nil {
logger.Errorf("[JsonrpcExporter.Unexport] error: %v", err) logger.Errorf("[JsonrpcExporter.Unexport] error: %v", err)
} }
......
...@@ -36,7 +36,7 @@ import ( ...@@ -36,7 +36,7 @@ import (
func TestJsonrpcInvoker_Invoke(t *testing.T) { func TestJsonrpcInvoker_Invoke(t *testing.T) {
methods, err := common.ServiceMap.Register("jsonrpc", &UserProvider{}) methods, err := common.ServiceMap.Register("UserProvider", "jsonrpc", &UserProvider{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "GetUser,GetUser0,GetUser1,GetUser2,GetUser3,GetUser4", methods) assert.Equal(t, "GetUser,GetUser0,GetUser1,GetUser2,GetUser3,GetUser4", methods)
......
...@@ -40,10 +40,12 @@ func init() { ...@@ -40,10 +40,12 @@ func init() {
extension.SetRestClient(constant.DEFAULT_REST_CLIENT, NewRestyClient) extension.SetRestClient(constant.DEFAULT_REST_CLIENT, NewRestyClient)
} }
// RestyClient a rest client implement by Resty
type RestyClient struct { type RestyClient struct {
client *resty.Client client *resty.Client
} }
// NewRestyClient a constructor of RestyClient
func NewRestyClient(restOption *client.RestOptions) client.RestClient { func NewRestyClient(restOption *client.RestOptions) client.RestClient {
client := resty.New() client := resty.New()
client.SetTransport( client.SetTransport(
...@@ -65,21 +67,21 @@ func NewRestyClient(restOption *client.RestOptions) client.RestClient { ...@@ -65,21 +67,21 @@ func NewRestyClient(restOption *client.RestOptions) client.RestClient {
} }
} }
func (rc *RestyClient) Do(restRequest *client.RestRequest, res interface{}) error { // Do send request by RestyClient
r, err := rc.client.R(). func (rc *RestyClient) Do(restRequest *client.RestClientRequest, res interface{}) error {
SetHeader("Content-Type", restRequest.Consumes). req := rc.client.R()
SetHeader("Accept", restRequest.Produces). req.Header = restRequest.Header
resp, err := req.
SetPathParams(restRequest.PathParams). SetPathParams(restRequest.PathParams).
SetQueryParams(restRequest.QueryParams). SetQueryParams(restRequest.QueryParams).
SetHeaders(restRequest.Headers).
SetBody(restRequest.Body). SetBody(restRequest.Body).
SetResult(res). SetResult(res).
Execute(restRequest.Method, "http://"+path.Join(restRequest.Location, restRequest.Path)) Execute(restRequest.Method, "http://"+path.Join(restRequest.Location, restRequest.Path))
if err != nil { if err != nil {
return perrors.WithStack(err) return perrors.WithStack(err)
} }
if r.IsError() { if resp.IsError() {
return perrors.New(r.String()) return perrors.New(resp.String())
} }
return nil return nil
} }
...@@ -18,26 +18,28 @@ ...@@ -18,26 +18,28 @@
package client package client
import ( import (
"net/http"
"time" "time"
) )
// RestOptions
type RestOptions struct { type RestOptions struct {
RequestTimeout time.Duration RequestTimeout time.Duration
ConnectTimeout time.Duration ConnectTimeout time.Duration
} }
type RestRequest struct { // RestClientRequest
type RestClientRequest struct {
Header http.Header
Location string Location string
Path string Path string
Produces string
Consumes string
Method string Method string
PathParams map[string]string PathParams map[string]string
QueryParams map[string]string QueryParams map[string]string
Body interface{} Body interface{}
Headers map[string]string
} }
// RestClient user can implement this client interface to send request
type RestClient interface { type RestClient interface {
Do(request *RestRequest, res interface{}) error Do(request *RestClientRequest, res interface{}) error
} }
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