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

Add:dynamic config in registry protocol export

parents fedcd90c ee1c0ce7
No related branches found
No related tags found
No related merge requests found
Showing
with 173 additions and 64 deletions
......@@ -54,10 +54,16 @@ Todo List:
You can know more about dubbo-go by its [roadmap](https://github.com/apache/dubbo-go/wiki/Roadmap).
## 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.
## 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).
## Benchmark
Benchmark project please refer to [go-for-apache-dubbo-benchmark](https://github.com/dubbogo/go-for-apache-dubbo-benchmark)
......
......@@ -58,6 +58,10 @@ Apache License, Version 2.0
这个子目录下的例子展示了如何使用 dubbo-go 。请仔细阅读 [examples/README.md](https://github.com/apache/dubbo-go/blob/develop/examples/README.md) 学习如何处理配置并编译程序。
## 如何贡献
如果您愿意给 [Apache/dubbo-go](https://github.com/apache/dubbo-go) 贡献代码或者文档,我们都热烈欢迎。具体请参考 [contribution intro](https://github.com/apache/dubbo-go/blob/master/cg.md)
## 性能测试 ##
性能测试项目是 [go-for-apache-dubbo-benchmark](https://github.com/dubbogo/go-for-apache-dubbo-benchmark)
......
......@@ -11,7 +11,7 @@ import (
)
func init() {
extension.SetConfigurator("override", newConfigurator)
extension.SetDefaultConfigurator(newConfigurator)
}
func newConfigurator(url *common.URL) cluster.Configurator {
return &overrideConfigurator{configuratorUrl: url}
......
......@@ -46,8 +46,9 @@ const (
)
const (
ANY_VALUE = "*"
ANYHOST_VALUE = "0.0.0.0"
ANY_VALUE = "*"
ANYHOST_VALUE = "0.0.0.0"
REMOVE_VALUE_PREFIX = "-"
)
const (
......
......@@ -37,3 +37,14 @@ func GetConfigurator(name string, url *common.URL) cluster.Configurator {
return configurator[name](url)
}
func SetDefaultConfigurator(v func(url *common.URL) cluster.Configurator) {
configurator["default"] = v
}
func GetDefaultConfigurator(url *common.URL) cluster.Configurator {
if configurator["default"] == nil {
panic("config center for default is not existing, make sure you have import the package.")
}
return configurator["default"](url)
}
......@@ -85,22 +85,23 @@ func (s *TestService1) Version() string {
func TestServiceMap_Register(t *testing.T) {
// lowercase
s0 := &testService{}
methods, err := ServiceMap.Register("testporotocol", s0)
// methods, err := ServiceMap.Register("testporotocol", s0)
_, err := ServiceMap.Register("testporotocol", s0)
assert.EqualError(t, err, "type testService is not exported")
// succ
s := &TestService{}
methods, err = ServiceMap.Register("testporotocol", s)
methods, err := ServiceMap.Register("testporotocol", s)
assert.NoError(t, err)
assert.Equal(t, "MethodOne,MethodThree,methodTwo", methods)
// repeat
methods, err = ServiceMap.Register("testporotocol", s)
_, err = ServiceMap.Register("testporotocol", s)
assert.EqualError(t, err, "service already defined: com.test.Path")
// no method
s1 := &TestService1{}
methods, err = ServiceMap.Register("testporotocol", s1)
_, err = ServiceMap.Register("testporotocol", s1)
assert.EqualError(t, err, "type com.test.Path1 has no exported methods of suitable type")
ServiceMap = &serviceMap{
......
......@@ -32,6 +32,7 @@ import (
import (
"github.com/dubbogo/gost/container"
"github.com/jinzhu/copier"
perrors "github.com/pkg/errors"
)
......@@ -220,9 +221,26 @@ func (c URL) URLEqual(url URL) bool {
if cKey != urlKey {
return false
}
if url.GetParam(constant.ENABLED_KEY, "true") != "true" && url.GetParam(constant.ENABLED_KEY, "") != constant.ANY_VALUE {
return false
}
//TODO :may need add interface key any value condition
if !isMatchCategory(url.GetParam(constant.CATEGORY_KEY, constant.DEFAULT_CATEGORY), c.GetParam(constant.CATEGORY_KEY, constant.DEFAULT_CATEGORY)) {
return false
}
return true
}
func isMatchCategory(category1 string, category2 string) bool {
if len(category2) == 0 {
return category1 == constant.DEFAULT_CATEGORY
} else if strings.Contains(category2, constant.ANY_VALUE) {
return true
} else if strings.Contains(category2, constant.REMOVE_VALUE_PREFIX) {
return !strings.Contains(category2, constant.REMOVE_VALUE_PREFIX+category1)
} else {
strings.Contains(category2, category1)
}
}
func (c URL) String() string {
buildString := fmt.Sprintf(
"%s://%s:%s@%s:%s%s?",
......@@ -460,3 +478,8 @@ func MergeUrl(serviceUrl URL, referenceUrl *URL) URL {
return mergedUrl
}
func (c *URL) Clone() *URL {
newUrl := &URL{}
copier.Copy(newUrl, c)
return newUrl
}
......@@ -242,3 +242,14 @@ func TestURL_SetParams(t *testing.T) {
assert.Equal(t, "3", u1.Params.Get("key"))
assert.Equal(t, "2.6.0", u1.Params.Get("version"))
}
func TestClone(t *testing.T) {
u1, err := NewURL(context.TODO(), "dubbo://:@127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=&version=2.6.0&configVersion=1.0")
assert.NoError(t, err)
u2 := u1.Clone()
assert.Equal(t, u2.Protocol, "dubbo")
assert.Equal(t, "1.0", u2.Params.Get("configVersion"))
u2.Protocol = "provider"
assert.Equal(t, u1.Protocol, "dubbo")
assert.Equal(t, u2.Protocol, "provider")
}
......@@ -58,7 +58,6 @@ type ServiceConfig struct {
unexported *atomic.Bool
exported *atomic.Bool
rpcService common.RPCService
exporters []protocol.Exporter
cacheProtocol protocol.Protocol
cacheMutex sync.Mutex
}
......@@ -127,7 +126,6 @@ func (srvconfig *ServiceConfig) Export() error {
if exporter == nil {
panic(perrors.New(fmt.Sprintf("Registry protocol new exporter error,registry is {%v},url is {%v}", regUrl, url)))
}
srvconfig.exporters = append(srvconfig.exporters, exporter)
}
} else {
invoker := extension.GetProxyFactory(providerConfig.ProxyFactory).GetInvoker(*url)
......@@ -135,7 +133,6 @@ func (srvconfig *ServiceConfig) Export() error {
if exporter == nil {
panic(perrors.New(fmt.Sprintf("Filter protocol without registry new exporter error,url is {%v}", url)))
}
srvconfig.exporters = append(srvconfig.exporters, exporter)
}
}
......
......@@ -69,7 +69,7 @@ func newZookeeperDynamicConfiguration(url *common.URL) (*zookeeperDynamicConfigu
err = c.client.Create(c.rootPath)
c.listener.ListenServiceEvent(c.rootPath, c.cacheListener)
return c, nil
return c, err
}
......@@ -95,7 +95,7 @@ func newMockZookeeperDynamicConfiguration(url *common.URL, opts ...zookeeper.Opt
err = c.client.Create(c.rootPath)
go c.listener.ListenServiceEvent(c.rootPath, c.cacheListener)
return tc, c, nil
return tc, c, err
}
......
......@@ -26,6 +26,7 @@ import (
import (
"github.com/dubbogo/hessian2"
"github.com/dubbogo/hessian2/java_exception"
perrors "github.com/pkg/errors"
)
......@@ -172,7 +173,7 @@ func (u *UserProvider) GetUser3() error {
}
func (u *UserProvider) GetErr(ctx context.Context, req []interface{}, rsp *User) error {
return hessian.NewThrowable("exception")
return java_exception.NewThrowable("exception")
}
func (u *UserProvider) GetUsers(req []interface{}) ([]interface{}, error) {
......
......@@ -31,6 +31,7 @@ import (
import (
"github.com/apache/dubbo-go/config"
hessian "github.com/dubbogo/hessian2"
"github.com/dubbogo/hessian2/java_exception"
)
type Gender hessian.JavaEnum
......@@ -146,7 +147,7 @@ func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User
}
func (u *UserProvider) GetErr(ctx context.Context, req []interface{}, rsp *User) error {
return hessian.NewThrowable("exception")
return java_exception.NewThrowable("exception")
}
func (u *UserProvider) GetUser0(id string, name string) (User, error) {
......
......@@ -2,12 +2,14 @@ module github.com/apache/dubbo-go
require (
github.com/dubbogo/getty v1.0.7
github.com/dubbogo/gost v1.0.0
github.com/dubbogo/hessian2 v1.0.2
github.com/dubbogo/gost v1.1.1
github.com/dubbogo/hessian2 v1.2.0
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8
github.com/magiconair/properties v1.8.1
github.com/pkg/errors v0.8.1
github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec
github.com/stretchr/testify v1.3.0
github.com/ulule/deepcopier v0.0.0-20171107155558-ca99b135e50f
go.uber.org/atomic v1.4.0
go.uber.org/zap v1.10.0
gopkg.in/yaml.v2 v2.2.2
......
......@@ -3,14 +3,16 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dubbogo/getty v1.0.7 h1:5Hg+JwXyCKm9Yr4yJkm98ahhnoa8c2h6br5QJxwQ+YU=
github.com/dubbogo/getty v1.0.7/go.mod h1:cRMSuoCmwc5lULFFnYZTxyCfZhObmRTNbS7XRnPNHSo=
github.com/dubbogo/gost v1.0.0 h1:obKvpJYdrIY2BidHYwYoj2E50OtwCDqVVVTcH2nnhAY=
github.com/dubbogo/gost v1.0.0/go.mod h1:R7wZm1DrmrKGr50mBZVcg6C9ekG8aL5hP+sgWcIDwQg=
github.com/dubbogo/hessian2 v1.0.2 h1:Ka9Z32ZszGAdCpgrGuZQmwkT0qe1pd3o9r7ERCDnSlQ=
github.com/dubbogo/hessian2 v1.0.2/go.mod h1:XFGDn4oSZX26zkcfhkM/fCJrOqwQJxk/xgWW1KMJBKM=
github.com/dubbogo/gost v1.1.1 h1:JCM7vx5edPIjDA5ovJTuzEEXuw2t7xLyrlgi2mi5jHI=
github.com/dubbogo/gost v1.1.1/go.mod h1:R7wZm1DrmrKGr50mBZVcg6C9ekG8aL5hP+sgWcIDwQg=
github.com/dubbogo/hessian2 v1.2.0 h1:5wFYuMzzRhneUAPbVBVKubIknrEjUM/B76vievYD0Vw=
github.com/dubbogo/hessian2 v1.2.0/go.mod h1:7EohF3mE7xmZcj43nP172sapRHOEifcV/jwyHhG4SaY=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 h1:mGIXW/lubQ4B+3bXTLxcTMTjUNDqoF6T/HUW9LbFx9s=
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s=
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
......@@ -22,6 +24,8 @@ github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec/go.mod h1:gi+0
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/ulule/deepcopier v0.0.0-20171107155558-ca99b135e50f h1:QatZ4lsJBY3x1+Imst9g95+vUl7m52dqM9Pi4aSMW8w=
github.com/ulule/deepcopier v0.0.0-20171107155558-ca99b135e50f/go.mod h1:BNLmYJ8oMJPIPpNx5968jCyUhwEU1XT3YsuOqtbo5qo=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
......
......@@ -217,7 +217,6 @@ func (c *Client) call(ct CallType, addr string, svcUrl common.URL, method string
p := &DubboPackage{}
p.Service.Path = strings.TrimPrefix(svcUrl.Path, "/")
p.Service.Target = svcUrl.GetParam(constant.INTERFACE_KEY, "")
p.Service.Interface = svcUrl.GetParam(constant.INTERFACE_KEY, "")
p.Service.Version = svcUrl.GetParam(constant.VERSION_KEY, "")
p.Service.Method = method
......
......@@ -62,13 +62,13 @@ func TestClient_Call(t *testing.T) {
}
c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
user := &User{}
// user := &User{}
//err := c.Call("127.0.0.1:20000", url, "GetBigPkg", []interface{}{nil}, user)
//assert.NoError(t, err)
//assert.NotEqual(t, "", user.Id)
//assert.NotEqual(t, "", user.Name)
user = &User{}
user := &User{}
err := c.Call("127.0.0.1:20000", url, "GetUser", []interface{}{"1", "username"}, user)
assert.NoError(t, err)
assert.Equal(t, User{Id: "1", Name: "username"}, *user)
......
......@@ -49,7 +49,6 @@ func TestDubboPackage_MarshalAndUnmarshal(t *testing.T) {
// request
pkg.Header.Type = hessian.PackageRequest
pkg.Service.Interface = "Service"
pkg.Service.Target = "Service"
pkg.Service.Version = "2.6"
pkg.Service.Method = "Method"
pkg.Service.Timeout = time.Second
......@@ -64,10 +63,10 @@ func TestDubboPackage_MarshalAndUnmarshal(t *testing.T) {
assert.Equal(t, byte(S_Dubbo), pkgres.Header.SerialID)
assert.Equal(t, int64(10086), pkgres.Header.ID)
assert.Equal(t, "2.5.4", pkgres.Body.([]interface{})[0])
assert.Equal(t, "Service", pkgres.Body.([]interface{})[1])
assert.Equal(t, "", pkgres.Body.([]interface{})[1])
assert.Equal(t, "2.6", pkgres.Body.([]interface{})[2])
assert.Equal(t, "Method", pkgres.Body.([]interface{})[3])
assert.Equal(t, "Ljava/lang/String;", pkgres.Body.([]interface{})[4])
assert.Equal(t, []interface{}{"a"}, pkgres.Body.([]interface{})[5])
assert.Equal(t, map[interface{}]interface{}{"interface": "Service", "path": "", "timeout": "1000"}, pkgres.Body.([]interface{})[6])
assert.Equal(t, map[interface{}]interface{}{"interface": "Service", "path": "", "group": "", "timeout": "1000"}, pkgres.Body.([]interface{})[6])
}
......@@ -42,7 +42,7 @@ func TestJsonClientCodec_Write(t *testing.T) {
assert.Equal(t, "{\"jsonrpc\":\"2.0\",\"method\":\"GetUser\",\"params\":[\"args\",2],\"id\":1}\n", string(data))
cd.Args = 1
data, err = codec.Write(cd)
_, err = codec.Write(cd)
assert.EqualError(t, err, "unsupported param type: int")
}
......
......@@ -81,39 +81,17 @@ func NewRegistryDirectory(url *common.URL, registry registry.Registry, opts ...O
}
//subscibe from registry
func (dir *registryDirectory) Subscribe(url common.URL) {
for {
if !dir.registry.IsAvailable() {
logger.Warnf("event listener game over.")
time.Sleep(time.Duration(RegistryConnDelay) * time.Second)
return
}
listener, err := dir.registry.Subscribe(url)
if err != nil {
if !dir.registry.IsAvailable() {
logger.Warnf("event listener game over.")
return
}
logger.Warnf("getListener() = err:%v", perrors.WithStack(err))
time.Sleep(time.Duration(RegistryConnDelay) * time.Second)
continue
}
for {
if serviceEvent, err := listener.Next(); err != nil {
logger.Warnf("Selector.watch() = error{%v}", perrors.WithStack(err))
listener.Close()
time.Sleep(time.Duration(RegistryConnDelay) * time.Second)
return
} else {
logger.Infof("update begin, service event: %v", serviceEvent.String())
go dir.update(serviceEvent)
}
func (dir *registryDirectory) Subscribe(url *common.URL) {
notifyListener := &notifyListener{dir}
dir.registry.Subscribe(url, notifyListener)
}
}
type notifyListener struct {
dir *registryDirectory
}
}
func (nl *notifyListener) Notify(event *registry.ServiceEvent) {
go nl.dir.update(event)
}
//subscribe service from registry , and update the cacheServices
......
......@@ -18,6 +18,7 @@
package protocol
import (
"github.com/apache/dubbo-go/cluster"
"sync"
)
......@@ -71,6 +72,7 @@ func (proto *registryProtocol) Refer(url common.URL) protocol.Invoker {
protocol := registryUrl.GetParam(constant.REGISTRY_KEY, "")
registryUrl.Protocol = protocol
}
var reg registry.Registry
if regI, loaded := proto.registries.Load(registryUrl.Key()); !loaded {
......@@ -90,7 +92,7 @@ func (proto *registryProtocol) Refer(url common.URL) protocol.Invoker {
if err != nil {
logger.Errorf("consumer service %v register registry %v error, error message is %s", serviceUrl.String(), registryUrl.String(), err.Error())
}
go directory.Subscribe(*serviceUrl)
go directory.Subscribe(serviceUrl)
//new cluster invoker
cluster := extension.GetCluster(serviceUrl.GetParam(constant.CLUSTER_KEY, constant.DEFAULT_CLUSTER))
......@@ -101,9 +103,10 @@ func (proto *registryProtocol) Refer(url common.URL) protocol.Invoker {
}
func (proto *registryProtocol) Export(invoker protocol.Invoker) protocol.Exporter {
registryUrl := proto.getRegistryUrl(invoker)
providerUrl := proto.getProviderUrl(invoker)
registryUrl := getRegistryUrl(invoker)
providerUrl := getProviderUrl(invoker)
overriderUrl := getSubscribedOverrideUrl(&providerUrl)
var reg registry.Registry
if regI, loaded := proto.registries.Load(registryUrl.Key()); !loaded {
......@@ -131,9 +134,74 @@ func (proto *registryProtocol) Export(invoker protocol.Invoker) protocol.Exporte
logger.Infof("The exporter has not been cached, and will return a new exporter!")
}
// Deprecated! subscribe to override rules in 2.6.x or before.
overrideSubscribeListener := &overrideSubscribeListener{url: overriderUrl, originInvoker: invoker, protocol: proto}
reg.Subscribe(overriderUrl, overrideSubscribeListener)
return cachedExporter.(protocol.Exporter)
}
func (proto *registryProtocol) reExport(invoker protocol.Invoker, newUrl *common.URL) {
key := getProviderUrl(invoker).Key()
if oldExporter, loaded := proto.bounds.Load(key); loaded {
wrappedNewInvoker := newWrappedInvoker(invoker, *newUrl)
//TODO:MAY not safe
oldExporter.(protocol.Exporter).Unexport()
proto.bounds.Delete(key)
proto.Export(wrappedNewInvoker)
//TODO: unregister & unsubscribe
}
}
func (proto *registryProtocol) overrideWithConfig(providerUrl *common.URL, listener *overrideSubscribeListener) {
}
type overrideSubscribeListener struct {
url *common.URL
originInvoker protocol.Invoker
protocol *registryProtocol
configurator cluster.Configurator
}
func (nl *overrideSubscribeListener) Notify(event *registry.ServiceEvent) {
if isMatched(&(event.Service), nl.url) {
nl.configurator = extension.GetDefaultConfigurator(&(event.Service))
nl.doOverrideIfNecessary()
}
}
func (nl *overrideSubscribeListener) doOverrideIfNecessary() {
providerUrl := getProviderUrl(nl.originInvoker)
key := providerUrl.Key()
if exporter, ok := nl.protocol.bounds.Load(key); ok {
currentUrl := exporter.(protocol.Exporter).GetInvoker().GetUrl()
nl.configurator.Configure(&providerUrl)
if currentUrl.String() == providerUrl.String() {
newRegUrl := nl.originInvoker.GetUrl()
setProviderUrl(&newRegUrl, &providerUrl)
nl.protocol.reExport(nl.originInvoker, &newRegUrl)
}
}
}
func isMatched(url *common.URL, subscribedUrl *common.URL) bool {
// Compatible with the 2.6.x
if len(url.GetParam(constant.CATEGORY_KEY, "")) == 0 && url.Protocol == constant.OVERRIDE_PROTOCOL {
url.AddParam(constant.CATEGORY_KEY, constant.CONFIGURATORS_CATEGORY)
}
if subscribedUrl.URLEqual(*url) {
return true
}
return false
}
func getSubscribedOverrideUrl(providerUrl *common.URL) *common.URL {
newUrl := providerUrl.Clone()
newUrl.Protocol = constant.PROVIDER_PROTOCOL
newUrl.Params.Add(constant.CATEGORY_KEY, constant.CONFIGURATORS_CATEGORY)
newUrl.Params.Add(constant.CHECK_KEY, "false")
return newUrl
}
func (proto *registryProtocol) Destroy() {
for _, ivk := range proto.invokers {
......@@ -158,7 +226,7 @@ func (proto *registryProtocol) Destroy() {
})
}
func (*registryProtocol) getRegistryUrl(invoker protocol.Invoker) common.URL {
func getRegistryUrl(invoker protocol.Invoker) common.URL {
//here add * for return a new url
url := invoker.GetUrl()
//if the protocol == registry ,set protocol the registry value in url.params
......@@ -169,10 +237,13 @@ func (*registryProtocol) getRegistryUrl(invoker protocol.Invoker) common.URL {
return url
}
func (*registryProtocol) getProviderUrl(invoker protocol.Invoker) common.URL {
func getProviderUrl(invoker protocol.Invoker) common.URL {
url := invoker.GetUrl()
return *url.SubURL
}
func setProviderUrl(regURL *common.URL, providerURL *common.URL) {
regURL.SubURL = providerURL
}
func GetProtocol() protocol.Protocol {
if regProtocol != nil {
......
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