Merge branch 'master' of https://github.com/apache/dubbo-go
diff --git a/.gitignore b/.gitignore
index 3769d10..f369c28 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@
*.dll
*.so
*.dylib
+*.jar
# Test binary, build with `go test -c`
*.test
@@ -17,10 +18,15 @@
target/
classes
-
-# Gopkg.lock
+# go mod, go test
vendor/
+coverage.txt
logs/
.vscode/
coverage.txt
+
+# unit test
+remoting/zookeeper/zookeeper-4unittest/
+config_center/zookeeper/zookeeper-4unittest/
+registry/zookeeper/zookeeper-4unittest/
diff --git a/CHANGE.md b/CHANGE.md
new file mode 100644
index 0000000..cdfca4f
--- /dev/null
+++ b/CHANGE.md
@@ -0,0 +1,26 @@
+# Release Notes
+
+## 1.1.0
+
+### New Features
+
+- Support Java bigdecimal<https://github.com/apache/dubbo-go/pull/126>;
+- Support all JDK exceptions<https://github.com/apache/dubbo-go/pull/120>;
+- Support multi-version of service<https://github.com/apache/dubbo-go/pull/119>;
+- Allow user set custom params for registry<https://github.com/apache/dubbo-go/pull/117>;
+- Support zookeeper config center<https://github.com/apache/dubbo-go/pull/99>;
+- Failsafe/Failback Cluster Strategy<https://github.com/apache/dubbo-go/pull/136>;
+
+### Enhancement
+
+- Use time wheel instead of time.After to defeat timer object memory leakage<https://github.com/apache/dubbo-go/pull/130> ;
+
+### Bugfixes
+
+- Preventing dead loop when got zookeeper unregister event<https://github.com/apache/dubbo-go/pull/129>;
+- Delete ineffassign<https://github.com/apache/dubbo-go/pull/127>;
+- Add wg.Done() for mockDataListener<https://github.com/apache/dubbo-go/pull/118>;
+- Delete wrong spelling words<https://github.com/apache/dubbo-go/pull/107>;
+- Use sync.Map to defeat from gettyClientPool deadlock<https://github.com/apache/dubbo-go/pull/106>;
+- Handle panic when function args list is empty<https://github.com/apache/dubbo-go/pull/98>;
+- url.Values is not safe map<https://github.com/apache/dubbo-go/pull/172>;
diff --git a/LICENSE b/LICENSE
index e9ba4dd..e76f9d9 100644
--- a/LICENSE
+++ b/LICENSE
@@ -176,7 +176,6 @@
END OF TERMS AND CONDITIONS
-
Licensed 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
diff --git a/README.md b/README.md
index 833d278..25c7283 100644
--- a/README.md
+++ b/README.md
@@ -6,9 +6,6 @@
---
Apache Dubbo Go Implementation.
-![Apache Dubbo-go](./dubbogo.png "Apache Dubbo-go")
-
-Apache/Dubbo-go image, licensed under [Creative Commons 3.0 Attributions license](https://creativecommons.org/licenses/by/3.0/).
## License
@@ -34,19 +31,19 @@
- Transport: HTTP, TCP
- Codec: JsonRPC v2, Hessian v2
- Registry: ZooKeeper/[etcd v3](https://github.com/apache/dubbo-go/pull/148)/[nacos](https://github.com/apache/dubbo-go/pull/151)/[consul](https://github.com/apache/dubbo-go/pull/121)
-- Configure Center: Zookeeper
+- Dynamic Configure Center & Service Management Configurator: Zookeeper
- Cluster Strategy: Failover/[Failfast](https://github.com/apache/dubbo-go/pull/140)/[Failsafe/Failback](https://github.com/apache/dubbo-go/pull/136)/[Available](https://github.com/apache/dubbo-go/pull/155)/[Broadcast](https://github.com/apache/dubbo-go/pull/158)/[Forking](https://github.com/apache/dubbo-go/pull/161)
- Load Balance: Random/[RoundRobin](https://github.com/apache/dubbo-go/pull/66)/[LeastActive](https://github.com/apache/dubbo-go/pull/65)
-- Filter: Echo Health Check/[Circuit break and service downgrade](https://github.com/apache/dubbo-go/pull/133)
+- Filter: Echo Health Check/[Circuit break and service downgrade](https://github.com/apache/dubbo-go/pull/133)/[TokenFilter](https://github.com/apache/dubbo-go/pull/202)
- Other feature: [generic invoke](https://github.com/apache/dubbo-go/pull/122)/start check/connecting certain provider/multi-protocols/multi-registries/multi-versions/service group
Working List:
- Load Balance: ConsistentHash
-- Filter: TokenFilter/AccessLogFilter/CountFilter/ExecuteLimitFilter/TpsLimitFilter
+- Filter: AccessLogFilter/CountFilter/ExecuteLimitFilter/TpsLimitFilter
- Registry: k8s
- Configure Center: apollo
-- Dynamic Configuration Center & Metadata Center (dubbo v2.7.x)
+- Metadata Center (dubbo v2.7.x)
- Metrics: Promethus(dubbo v2.7.x)
Todo List:
@@ -67,6 +64,19 @@
## Running unit tests
+### Prepare
+
+Mac/Linux
+```bash
+sh ./before_ut.sh
+```
+
+Windows
+```bash
+before_ut.bat
+```
+
+# Run
```bash
go test ./...
diff --git a/README_CN.md b/README_CN.md
index 3b8ddff..e34cf6a 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -5,9 +5,6 @@
---
Apache Dubbo Go 语言实现
-![Apache Dubbo-go](./dubbogo.png "Apache Dubbo-go")
-
-Apache/Dubbo-go image, licensed under [Creative Commons 3.0 Attributions license](https://creativecommons.org/licenses/by/3.0/).
## 证书 ##
@@ -33,20 +30,20 @@
- 传输协议: HTTP, TCP
- 序列化协议: JsonRPC v2, Hessian v2
- 注册中心: ZooKeeper/[etcd v3](https://github.com/apache/dubbo-go/pull/148)/[nacos](https://github.com/apache/dubbo-go/pull/151)/[consul](https://github.com/apache/dubbo-go/pull/121)
-- 配置中心: Zookeeper
+- 动态配置中心与服务治理配置器(config center): Zookeeper
- 集群策略: Failover/[Failfast](https://github.com/apache/dubbo-go/pull/140)/[Failsafe/Failback](https://github.com/apache/dubbo-go/pull/136)/[Available](https://github.com/apache/dubbo-go/pull/155)/[Broadcast](https://github.com/apache/dubbo-go/pull/158)/[Forking](https://github.com/apache/dubbo-go/pull/161)
- 负载均衡策略: Random/[RoundRobin](https://github.com/apache/dubbo-go/pull/66)/[LeastActive](https://github.com/apache/dubbo-go/pull/65)
-- 过滤器: Echo Health Check/[服务熔断&降级](https://github.com/apache/dubbo-go/pull/133)
+- 过滤器: Echo Health Check/[服务熔断&降级](https://github.com/apache/dubbo-go/pull/133)/[TokenFilter](https://github.com/apache/dubbo-go/pull/202)
- 其他功能支持: [泛化调用](https://github.com/apache/dubbo-go/pull/122)/启动时检查/服务直连/多服务协议/多注册中心/多服务版本/服务分组
开发中列表:
- 集群策略: Forking
- 负载均衡策略: ConsistentHash
-- 过滤器: TokenFilter/AccessLogFilter/CountFilter/ExecuteLimitFilter/TpsLimitFilter
+- 过滤器: AccessLogFilter/CountFilter/ExecuteLimitFilter/TpsLimitFilter
- 注册中心: k8s
- 配置中心: apollo
-- 动态配置中心 & 元数据中心 (dubbo v2.7.x)
+- 元数据中心 (dubbo v2.7.x)
- Metrics: Promethus(dubbo v2.7.x)
任务列表:
@@ -67,10 +64,23 @@
## 运行单测
+### 准备
+
+Mac/Linux
+```bash
+sh ./before_ut.sh
+```
+
+Windows
+```bash
+before_ut.bat
+```
+
+# 执行
```bash
go test ./...
-# 覆盖率
+# coverage
go test ./... -coverprofile=coverage.txt -covermode=atomic
```
diff --git a/before_ut.bat b/before_ut.bat
new file mode 100644
index 0000000..a10df71
--- /dev/null
+++ b/before_ut.bat
@@ -0,0 +1,5 @@
+set zkJar=zookeeper-3.4.9-fatjar.jar
+md remoting\zookeeper\zookeeper-4unittest\contrib\fatjar config_center\zookeeper\zookeeper-4unittest\contrib\fatjar registry\zookeeper\zookeeper-4unittest\contrib\fatjar
+curl -L https://github.com/dubbogo/resources/raw/master/zookeeper-4unitest/contrib/fatjar/%zkJar% -o remoting/zookeeper/zookeeper-4unittest/contrib/fatjar/%zkJar%
+xcopy /f "remoting/zookeeper/zookeeper-4unittest/contrib/fatjar/%zkJar%" "config_center/zookeeper/zookeeper-4unittest/contrib/fatjar/"
+xcopy /f "remoting/zookeeper/zookeeper-4unittest/contrib/fatjar/%zkJar%" "registry/zookeeper/zookeeper-4unittest/contrib/fatjar/"
\ No newline at end of file
diff --git a/before_ut.sh b/before_ut.sh
new file mode 100644
index 0000000..7acee76
--- /dev/null
+++ b/before_ut.sh
@@ -0,0 +1,4 @@
+mkdir -p remoting/zookeeper/zookeeper-4unittest/contrib/fatjar config_center/zookeeper/zookeeper-4unittest/contrib/fatjar registry/zookeeper/zookeeper-4unittest/contrib/fatjar
+wget -P "remoting/zookeeper/zookeeper-4unittest/contrib/fatjar" https://github.com/dubbogo/resources/raw/master/zookeeper-4unitest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar
+cp remoting/zookeeper/zookeeper-4unittest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar config_center/zookeeper/zookeeper-4unittest/contrib/fatjar/
+cp remoting/zookeeper/zookeeper-4unittest/contrib/fatjar/zookeeper-3.4.9-fatjar.jar registry/zookeeper/zookeeper-4unittest/contrib/fatjar/
\ No newline at end of file
diff --git a/cluster/cluster_impl/failback_cluster_invoker.go b/cluster/cluster_impl/failback_cluster_invoker.go
index 027461c..c8dbeda 100644
--- a/cluster/cluster_impl/failback_cluster_invoker.go
+++ b/cluster/cluster_impl/failback_cluster_invoker.go
@@ -18,6 +18,7 @@
package cluster_impl
import (
+ "strconv"
"sync"
"time"
)
@@ -54,15 +55,18 @@
invoker := &failbackClusterInvoker{
baseClusterInvoker: newBaseClusterInvoker(directory),
}
- retriesConfig := invoker.GetUrl().GetParamInt(constant.RETRIES_KEY, constant.DEFAULT_FAILBACK_TIMES)
- if retriesConfig <= 0 {
- retriesConfig = constant.DEFAULT_FAILBACK_TIMES
+ retriesConfig := invoker.GetUrl().GetParam(constant.RETRIES_KEY, constant.DEFAULT_FAILBACK_TIMES)
+ retries, err := strconv.Atoi(retriesConfig)
+ if err != nil || retries < 0 {
+ logger.Error("Your retries config is invalid,pls do a check. And will use the default fail back times configuration instead.")
+ retries = constant.DEFAULT_FAILBACK_TIMES_INT
}
+
failbackTasksConfig := invoker.GetUrl().GetParamInt(constant.FAIL_BACK_TASKS_KEY, constant.DEFAULT_FAILBACK_TASKS)
if failbackTasksConfig <= 0 {
failbackTasksConfig = constant.DEFAULT_FAILBACK_TASKS
}
- invoker.maxRetries = retriesConfig
+ invoker.maxRetries = int64(retries)
invoker.failbackTasks = failbackTasksConfig
return invoker
}
diff --git a/cluster/cluster_impl/failover_cluster_invoker.go b/cluster/cluster_impl/failover_cluster_invoker.go
index 3dd8c41..70db6d4 100644
--- a/cluster/cluster_impl/failover_cluster_invoker.go
+++ b/cluster/cluster_impl/failover_cluster_invoker.go
@@ -18,12 +18,17 @@
package cluster_impl
import (
+ "strconv"
+)
+
+import (
perrors "github.com/pkg/errors"
)
import (
"github.com/apache/dubbo-go/cluster"
"github.com/apache/dubbo-go/common/constant"
+ "github.com/apache/dubbo-go/common/logger"
"github.com/apache/dubbo-go/common/utils"
"github.com/apache/dubbo-go/protocol"
)
@@ -53,16 +58,21 @@
url := invokers[0].GetUrl()
//get reties
- retries := url.GetParamInt(constant.RETRIES_KEY, constant.DEFAULT_RETRIES)
+ retriesConfig := url.GetParam(constant.RETRIES_KEY, constant.DEFAULT_RETRIES)
//Get the service method loadbalance config if have
- if v := url.GetMethodParamInt(methodName, constant.RETRIES_KEY, 0); v != 0 {
- retries = v
+ if v := url.GetMethodParam(methodName, constant.RETRIES_KEY, ""); len(v) != 0 {
+ retriesConfig = v
+ }
+ retries, err := strconv.Atoi(retriesConfig)
+ if err != nil || retries < 0 {
+ logger.Error("Your retries config is invalid,pls do a check. And will use the default retries configuration instead.")
+ retries = constant.DEFAULT_RETRIES_INT
}
invoked := []protocol.Invoker{}
providers := []string{}
var result protocol.Result
- for i := int64(0); i < retries; i++ {
+ for i := 0; i <= retries; i++ {
//Reselect before retry to avoid a change of candidate `invokers`.
//NOTE: if `invokers` changed, then `invoked` also lose accuracy.
if i > 0 {
diff --git a/cluster/cluster_impl/failover_cluster_test.go b/cluster/cluster_impl/failover_cluster_test.go
index dc039db..78b7993 100644
--- a/cluster/cluster_impl/failover_cluster_test.go
+++ b/cluster/cluster_impl/failover_cluster_test.go
@@ -118,14 +118,14 @@
}
func Test_FailoverInvokeSuccess(t *testing.T) {
urlParams := url.Values{}
- result := normalInvoke(t, 2, urlParams)
+ result := normalInvoke(t, 3, urlParams)
assert.NoError(t, result.Error())
count = 0
}
func Test_FailoverInvokeFail(t *testing.T) {
urlParams := url.Values{}
- result := normalInvoke(t, 3, urlParams)
+ result := normalInvoke(t, 4, urlParams)
assert.Errorf(t, result.Error(), "error")
count = 0
}
@@ -133,7 +133,7 @@
func Test_FailoverInvoke1(t *testing.T) {
urlParams := url.Values{}
urlParams.Set(constant.RETRIES_KEY, "3")
- result := normalInvoke(t, 3, urlParams)
+ result := normalInvoke(t, 4, urlParams)
assert.NoError(t, result.Error())
count = 0
}
@@ -144,7 +144,7 @@
urlParams.Set("methods.test."+constant.RETRIES_KEY, "3")
ivc := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("test"))
- result := normalInvoke(t, 3, urlParams, ivc)
+ result := normalInvoke(t, 4, urlParams, ivc)
assert.NoError(t, result.Error())
count = 0
}
diff --git a/cluster/directory/base_directory.go b/cluster/directory/base_directory.go
index b201197..1d59b51 100644
--- a/cluster/directory/base_directory.go
+++ b/cluster/directory/base_directory.go
@@ -42,6 +42,9 @@
func (dir *BaseDirectory) GetUrl() common.URL {
return *dir.url
}
+func (dir *BaseDirectory) GetDirectoryUrl() *common.URL {
+ return dir.url
+}
func (dir *BaseDirectory) Destroy(doDestroy func()) {
if dir.destroyed.CAS(false, true) {
diff --git a/cluster/loadbalance/least_active.go b/cluster/loadbalance/least_active.go
index 39c5620..aa69f3c 100644
--- a/cluster/loadbalance/least_active.go
+++ b/cluster/loadbalance/least_active.go
@@ -15,7 +15,6 @@
* limitations under the License.
*/
-// @author yiji@apache.org
package loadbalance
import (
diff --git a/cluster/loadbalance/round_robin_test.go b/cluster/loadbalance/round_robin_test.go
index e261884..0b8e89c 100644
--- a/cluster/loadbalance/round_robin_test.go
+++ b/cluster/loadbalance/round_robin_test.go
@@ -1,3 +1,20 @@
+/*
+ * 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 loadbalance
import (
diff --git a/common/config/environment.go b/common/config/environment.go
index 8709d69..931f046 100644
--- a/common/config/environment.go
+++ b/common/config/environment.go
@@ -23,15 +23,21 @@
"sync"
)
+import (
+ "github.com/apache/dubbo-go/config_center"
+)
+
// There is dubbo.properties file and application level config center configuration which higner than normal config center in java. So in java the
// configuration sequence will be config center > application level config center > dubbo.properties > spring bean configuration.
// But in go, neither the dubbo.properties file or application level config center configuration will not support for the time being.
// We just have config center configuration which can override configuration in consumer.yaml & provider.yaml.
// But for add these features in future ,I finish the environment struct following Environment class in java.
type Environment struct {
- configCenterFirst bool
- externalConfigs sync.Map
- externalConfigMap sync.Map
+ configCenterFirst bool
+ externalConfigs sync.Map
+ externalConfigMap sync.Map
+ appExternalConfigMap sync.Map
+ dynamicConfiguration config_center.DynamicConfiguration
}
var (
@@ -45,6 +51,9 @@
})
return instance
}
+func NewEnvInstance() {
+ instance = &Environment{configCenterFirst: true}
+}
//func (env *Environment) SetConfigCenterFirst() {
// env.configCenterFirst = true
@@ -60,23 +69,34 @@
}
}
+func (env *Environment) UpdateAppExternalConfigMap(externalMap map[string]string) {
+ for k, v := range externalMap {
+ env.appExternalConfigMap.Store(k, v)
+ }
+}
+
func (env *Environment) Configuration() *list.List {
list := list.New()
- memConf := newInmemoryConfiguration()
- memConf.setProperties(&(env.externalConfigMap))
- list.PushBack(memConf)
+ // The sequence would be: SystemConfiguration -> ExternalConfiguration -> AppExternalConfiguration -> AbstractConfig -> PropertiesConfiguration
+ list.PushFront(newInmemoryConfiguration(&(env.externalConfigMap)))
+ list.PushFront(newInmemoryConfiguration(&(env.appExternalConfigMap)))
return list
}
+func (env *Environment) SetDynamicConfiguration(dc config_center.DynamicConfiguration) {
+ env.dynamicConfiguration = dc
+}
+
+func (env *Environment) GetDynamicConfiguration() config_center.DynamicConfiguration {
+ return env.dynamicConfiguration
+}
+
type InmemoryConfiguration struct {
store *sync.Map
}
-func newInmemoryConfiguration() *InmemoryConfiguration {
- return &InmemoryConfiguration{}
-}
-func (conf *InmemoryConfiguration) setProperties(p *sync.Map) {
- conf.store = p
+func newInmemoryConfiguration(p *sync.Map) *InmemoryConfiguration {
+ return &InmemoryConfiguration{store: p}
}
func (conf *InmemoryConfiguration) GetProperty(key string) (bool, string) {
diff --git a/common/config/environment_test.go b/common/config/environment_test.go
index ab7cafa..2d84dc4 100644
--- a/common/config/environment_test.go
+++ b/common/config/environment_test.go
@@ -19,6 +19,7 @@
import (
"testing"
)
+
import (
"github.com/stretchr/testify/assert"
)
@@ -38,7 +39,7 @@
func TestEnvironment_ConfigurationAndGetProperty(t *testing.T) {
GetEnvInstance().UpdateExternalConfigMap(map[string]string{"1": "2"})
list := GetEnvInstance().Configuration()
- ok, v := list.Front().Value.(*InmemoryConfiguration).GetProperty("1")
+ ok, v := list.Back().Value.(*InmemoryConfiguration).GetProperty("1")
assert.True(t, ok)
assert.Equal(t, "2", v)
}
diff --git a/common/constant/default.go b/common/constant/default.go
index d103c6a..405920e 100644
--- a/common/constant/default.go
+++ b/common/constant/default.go
@@ -18,27 +18,35 @@
package constant
const (
- DUBBO = "dubbo"
+ DUBBO = "dubbo"
+ PROVIDER_PROTOCOL = "provider"
+ //compatible with 2.6.x
+ OVERRIDE_PROTOCOL = "override"
+ EMPTY_PROTOCOL = "empty"
+ ROUTER_PROTOCOL = "router"
)
+
const (
DEFAULT_WEIGHT = 100 //
DEFAULT_WARMUP = 10 * 60 // in java here is 10*60*1000 because of System.currentTimeMillis() is measured in milliseconds & in go time.Unix() is second
)
const (
- DEFAULT_LOADBALANCE = "random"
- DEFAULT_RETRIES = 2
- DEFAULT_PROTOCOL = "dubbo"
- DEFAULT_REG_TIMEOUT = "10s"
- DEFAULT_CLUSTER = "failover"
- DEFAULT_FAILBACK_TIMES = 3
- DEFAULT_FAILBACK_TASKS = 100
+ DEFAULT_LOADBALANCE = "random"
+ DEFAULT_RETRIES = "2"
+ DEFAULT_RETRIES_INT = 2
+ DEFAULT_PROTOCOL = "dubbo"
+ DEFAULT_REG_TIMEOUT = "10s"
+ DEFAULT_CLUSTER = "failover"
+ DEFAULT_FAILBACK_TIMES = "3"
+ DEFAULT_FAILBACK_TIMES_INT = 3
+ DEFAULT_FAILBACK_TASKS = 100
)
const (
DEFAULT_KEY = "default"
PREFIX_DEFAULT_KEY = "default."
- DEFAULT_SERVICE_FILTERS = "echo"
+ DEFAULT_SERVICE_FILTERS = "echo,token"
DEFAULT_REFERENCE_FILTERS = ""
GENERIC_REFERENCE_FILTERS = "generic"
GENERIC = "$invoke"
@@ -46,5 +54,16 @@
)
const (
- ANY_VALUE = "*"
+ ANY_VALUE = "*"
+ ANYHOST_VALUE = "0.0.0.0"
+ REMOVE_VALUE_PREFIX = "-"
+)
+
+const (
+ CONFIGURATORS_CATEGORY = "configurators"
+ ROUTER_CATEGORY = "category"
+ DEFAULT_CATEGORY = PROVIDER_CATEGORY
+ DYNAMIC_CONFIGURATORS_CATEGORY = "dynamicconfigurators"
+ APP_DYNAMIC_CONFIGURATORS_CATEGORY = "appdynamicconfigurators"
+ PROVIDER_CATEGORY = "providers"
)
diff --git a/common/constant/key.go b/common/constant/key.go
index ed60c24..abb78c9 100644
--- a/common/constant/key.go
+++ b/common/constant/key.go
@@ -22,15 +22,22 @@
)
const (
- GROUP_KEY = "group"
- VERSION_KEY = "version"
- INTERFACE_KEY = "interface"
- PATH_KEY = "path"
- SERVICE_KEY = "service"
- METHODS_KEY = "methods"
- TIMEOUT_KEY = "timeout"
- BEAN_NAME_KEY = "bean.name"
- GENERIC_KEY = "generic"
+ GROUP_KEY = "group"
+ VERSION_KEY = "version"
+ INTERFACE_KEY = "interface"
+ PATH_KEY = "path"
+ SERVICE_KEY = "service"
+ METHODS_KEY = "methods"
+ TIMEOUT_KEY = "timeout"
+ CATEGORY_KEY = "category"
+ CHECK_KEY = "check"
+ ENABLED_KEY = "enabled"
+ SIDE_KEY = "side"
+ OVERRIDE_PROVIDERS_KEY = "providerAddresses"
+ BEAN_NAME_KEY = "bean.name"
+ GENERIC_KEY = "generic"
+ CLASSIFIER_KEY = "classifier"
+ TOKEN_KEY = "token"
)
const (
@@ -79,16 +86,23 @@
)
const (
- CONFIG_NAMESPACE_KEY = "config.namespace"
- CONFIG_TIMEOUT_KET = "config.timeout"
+ CONFIG_NAMESPACE_KEY = "config.namespace"
+ CONFIG_TIMEOUT_KET = "config.timeout"
+ CONFIG_VERSION_KEY = "configVersion"
+ COMPATIBLE_CONFIG_KEY = "compatible_config"
)
const (
- RegistryConfigPrefix = "dubbo.registries."
- ReferenceConfigPrefix = "dubbo.reference."
- ServiceConfigPrefix = "dubbo.service."
- ProtocolConfigPrefix = "dubbo.protocols."
- ProviderConfigPrefix = "dubbo.provider."
- ConsumerConfigPrefix = "dubbo.consumer."
+ RegistryConfigPrefix = "dubbo.registries."
+ SingleRegistryConfigPrefix = "dubbo.registry."
+ ReferenceConfigPrefix = "dubbo.reference."
+ ServiceConfigPrefix = "dubbo.service."
+ ProtocolConfigPrefix = "dubbo.protocols."
+ ProviderConfigPrefix = "dubbo.provider."
+ ConsumerConfigPrefix = "dubbo.consumer."
+)
+
+const (
+ CONFIGURATORS_SUFFIX = ".configurators"
)
const (
diff --git a/common/extension/configurator.go b/common/extension/configurator.go
new file mode 100644
index 0000000..40d134f
--- /dev/null
+++ b/common/extension/configurator.go
@@ -0,0 +1,60 @@
+/*
+ * 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 extension
+
+import (
+ "github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/config_center"
+)
+
+const DefaultKey = "default"
+
+type getConfiguratorFunc func(url *common.URL) config_center.Configurator
+
+var (
+ configurator = make(map[string]getConfiguratorFunc)
+)
+
+func SetConfigurator(name string, v getConfiguratorFunc) {
+ configurator[name] = v
+}
+
+func GetConfigurator(name string, url *common.URL) config_center.Configurator {
+ if configurator[name] == nil {
+ panic("configurator for " + name + " is not existing, make sure you have import the package.")
+ }
+ return configurator[name](url)
+
+}
+func SetDefaultConfigurator(v getConfiguratorFunc) {
+ configurator[DefaultKey] = v
+}
+
+func GetDefaultConfigurator(url *common.URL) config_center.Configurator {
+ if configurator[DefaultKey] == nil {
+ panic("configurator for default is not existing, make sure you have import the package.")
+ }
+ return configurator[DefaultKey](url)
+
+}
+func GetDefaultConfiguratorFunc() getConfiguratorFunc {
+ if configurator[DefaultKey] == nil {
+ panic("configurator for default is not existing, make sure you have import the package.")
+ }
+ return configurator[DefaultKey]
+}
diff --git a/common/extension/router_factory.go b/common/extension/router_factory.go
index f364292..6f27aaf 100644
--- a/common/extension/router_factory.go
+++ b/common/extension/router_factory.go
@@ -1,3 +1,20 @@
+/*
+ * 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 extension
import (
diff --git a/common/proxy/proxy_factory/default.go b/common/proxy/proxy_factory/default.go
index 1665a73..bafba60 100644
--- a/common/proxy/proxy_factory/default.go
+++ b/common/proxy/proxy_factory/default.go
@@ -18,9 +18,19 @@
package proxy_factory
import (
+ "reflect"
+ "strings"
+)
+
+import (
+ perrors "github.com/pkg/errors"
+)
+
+import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
+ "github.com/apache/dubbo-go/common/logger"
"github.com/apache/dubbo-go/common/proxy"
"github.com/apache/dubbo-go/protocol"
)
@@ -51,6 +61,86 @@
return proxy.NewProxy(invoker, nil, attachments)
}
func (factory *DefaultProxyFactory) GetInvoker(url common.URL) protocol.Invoker {
- // todo: call service
- return protocol.NewBaseInvoker(url)
+ return &ProxyInvoker{
+ BaseInvoker: *protocol.NewBaseInvoker(url),
+ }
+}
+
+type ProxyInvoker struct {
+ protocol.BaseInvoker
+}
+
+func (pi *ProxyInvoker) Invoke(invocation protocol.Invocation) protocol.Result {
+ result := &protocol.RPCResult{}
+ result.SetAttachments(invocation.Attachments())
+
+ url := pi.GetUrl()
+
+ methodName := invocation.MethodName()
+ proto := url.Protocol
+ path := strings.TrimPrefix(url.Path, "/")
+ args := invocation.Arguments()
+
+ // get service
+ svc := common.ServiceMap.GetService(proto, path)
+ if svc == nil {
+ logger.Errorf("cannot find service [%s] in %s", path, proto)
+ result.SetError(perrors.Errorf("cannot find service [%s] in %s", path, proto))
+ return result
+ }
+
+ // get method
+ method := svc.Method()[methodName]
+ if method == nil {
+ logger.Errorf("cannot find method [%s] of service [%s] in %s", methodName, path, proto)
+ result.SetError(perrors.Errorf("cannot find method [%s] of service [%s] in %s", methodName, path, proto))
+ return result
+ }
+
+ in := []reflect.Value{svc.Rcvr()}
+ if method.CtxType() != nil {
+ in = append(in, method.SuiteContext(nil)) // todo: ctx will be used later.
+ }
+
+ // prepare argv
+ if (len(method.ArgsType()) == 1 || len(method.ArgsType()) == 2 && method.ReplyType() == nil) && method.ArgsType()[0].String() == "[]interface {}" {
+ in = append(in, reflect.ValueOf(args))
+ } else {
+ for i := 0; i < len(args); i++ {
+ t := reflect.ValueOf(args[i])
+ if !t.IsValid() {
+ at := method.ArgsType()[i]
+ if at.Kind() == reflect.Ptr {
+ at = at.Elem()
+ }
+ t = reflect.New(at)
+ }
+ in = append(in, t)
+ }
+ }
+
+ // prepare replyv
+ var replyv reflect.Value
+ if method.ReplyType() == nil && len(method.ArgsType()) > 0 {
+ replyv = reflect.New(method.ArgsType()[len(method.ArgsType())-1].Elem())
+ in = append(in, replyv)
+ }
+
+ returnValues := method.Method().Func.Call(in)
+
+ var retErr interface{}
+ if len(returnValues) == 1 {
+ retErr = returnValues[0].Interface()
+ } else {
+ replyv = returnValues[0]
+ retErr = returnValues[1].Interface()
+ }
+ if retErr != nil {
+ result.SetError(retErr.(error))
+ } else {
+ if replyv.IsValid() && (replyv.Kind() != reflect.Ptr || replyv.Kind() == reflect.Ptr && replyv.Elem().IsValid()) {
+ result.SetResult(replyv.Interface())
+ }
+ }
+ return result
}
diff --git a/common/url.go b/common/url.go
index fb31129..bf58ca1 100644
--- a/common/url.go
+++ b/common/url.go
@@ -31,7 +31,10 @@
)
import (
+ "github.com/dubbogo/gost/container"
+ "github.com/jinzhu/copier"
perrors "github.com/pkg/errors"
+ "github.com/satori/go.uuid"
)
import (
@@ -71,7 +74,7 @@
Port string
//url.Values is not safe map, add to avoid concurrent map read and map write error
paramsLock sync.RWMutex
- Params url.Values
+ params url.Values
PrimitiveURL string
ctx context.Context
}
@@ -108,19 +111,22 @@
func WithParams(params url.Values) option {
return func(url *URL) {
- url.Params = params
+ url.params = params
}
}
+
func WithParamsValue(key, val string) option {
return func(url *URL) {
- url.Params.Set(key, val)
+ url.SetParam(key, val)
}
}
+
func WithProtocol(proto string) option {
return func(url *URL) {
url.Protocol = proto
}
}
+
func WithIp(ip string) option {
return func(url *URL) {
url.Ip = ip
@@ -144,6 +150,19 @@
url.Location = location
}
}
+
+func WithToken(token string) option {
+ return func(url *URL) {
+ if len(token) > 0 {
+ value := token
+ if strings.ToLower(token) == "true" || strings.ToLower(token) == "default" {
+ value = uuid.NewV4().String()
+ }
+ url.SetParam(constant.TOKEN_KEY, value)
+ }
+ }
+}
+
func NewURLWithOptions(opts ...option) *URL {
url := &URL{}
for _, opt := range opts {
@@ -185,7 +204,7 @@
return s, perrors.Errorf("url.Parse(url string{%s}), error{%v}", rawUrlString, err)
}
- s.Params, err = url.ParseQuery(serviceUrl.RawQuery)
+ s.params, err = url.ParseQuery(serviceUrl.RawQuery)
if err != nil {
return s, perrors.Errorf("url.ParseQuery(raw url string{%s}), error{%v}", serviceUrl.RawQuery, err)
}
@@ -226,14 +245,40 @@
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 {
+ return strings.Contains(category2, category1)
+ }
+}
func (c URL) String() string {
- buildString := fmt.Sprintf(
- "%s://%s:%s@%s:%s%s?",
- c.Protocol, c.Username, c.Password, c.Ip, c.Port, c.Path)
- buildString += c.Params.Encode()
+ var buildString string
+ if len(c.Username) == 0 && len(c.Password) == 0 {
+ buildString = fmt.Sprintf(
+ "%s://%s:%s%s?",
+ c.Protocol, c.Ip, c.Port, c.Path)
+ } else {
+ buildString = fmt.Sprintf(
+ "%s://%s:%s@%s:%s%s?",
+ c.Protocol, c.Username, c.Password, c.Ip, c.Port, c.Path)
+ }
+ c.paramsLock.RLock()
+ buildString += c.params.Encode()
+ c.paramsLock.RUnlock()
return buildString
}
@@ -268,6 +313,11 @@
return buf.String()
}
+func (c *URL) EncodedServiceKey() string {
+ serviceKey := c.ServiceKey()
+ return strings.Replace(serviceKey, "/", "*", 1)
+}
+
func (c URL) Context() context.Context {
return c.ctx
}
@@ -287,20 +337,43 @@
func (c *URL) AddParam(key string, value string) {
c.paramsLock.Lock()
- c.Params.Add(key, value)
+ c.params.Add(key, value)
c.paramsLock.Unlock()
}
+func (c *URL) SetParam(key string, value string) {
+ c.paramsLock.Lock()
+ c.params.Set(key, value)
+ c.paramsLock.Unlock()
+}
+
+func (c *URL) RangeParams(f func(key, value string) bool) {
+ c.paramsLock.RLock()
+ defer c.paramsLock.RUnlock()
+ for k, v := range c.params {
+ if !f(k, v[0]) {
+ break
+ }
+ }
+}
+
func (c URL) GetParam(s string, d string) string {
var r string
c.paramsLock.RLock()
- if r = c.Params.Get(s); len(r) == 0 {
+ if r = c.params.Get(s); len(r) == 0 {
r = d
}
c.paramsLock.RUnlock()
return r
}
+
+func (c URL) GetParams() url.Values {
+ return c.params
+}
+
func (c URL) GetParamAndDecoded(key string) (string, error) {
+ c.paramsLock.RLock()
+ defer c.paramsLock.RUnlock()
ruleDec, err := base64.URLEncoding.DecodeString(c.GetParam(key, ""))
value := string(ruleDec)
return value, err
@@ -321,7 +394,7 @@
case "path":
return c.Path
default:
- return c.Params.Get(key)
+ return c.GetParam(key, "")
}
}
@@ -330,7 +403,7 @@
var r bool
var err error
- if r, err = strconv.ParseBool(c.Params.Get(s)); err != nil {
+ if r, err = strconv.ParseBool(c.GetParam(s, "")); err != nil {
return d
}
return r
@@ -339,7 +412,8 @@
func (c URL) GetParamInt(s string, d int64) int64 {
var r int
var err error
- if r, err = strconv.Atoi(c.Params.Get(s)); r == 0 || err != nil {
+
+ if r, err = strconv.Atoi(c.GetParam(s, "")); r == 0 || err != nil {
return d
}
return int64(r)
@@ -348,7 +422,9 @@
func (c URL) GetMethodParamInt(method string, key string, d int64) int64 {
var r int
var err error
- if r, err = strconv.Atoi(c.Params.Get("methods." + method + "." + key)); r == 0 || err != nil {
+ c.paramsLock.RLock()
+ defer c.paramsLock.RUnlock()
+ if r, err = strconv.Atoi(c.GetParam("methods."+method+"."+key, "")); r == 0 || err != nil {
return d
}
return int64(r)
@@ -365,20 +441,37 @@
func (c URL) GetMethodParam(method string, key string, d string) string {
var r string
- if r = c.Params.Get("methods." + method + "." + key); r == "" {
+ if r = c.GetParam("methods."+method+"."+key, ""); r == "" {
r = d
}
return r
}
+func (c *URL) RemoveParams(set *container.HashSet) {
+ c.paramsLock.Lock()
+ defer c.paramsLock.Unlock()
+ for k := range set.Items {
+ s := k.(string)
+ delete(c.params, s)
+ }
+}
+
+func (c *URL) SetParams(m url.Values) {
+ for k := range m {
+ c.SetParam(k, m.Get(k))
+ }
+}
+
// ToMap transfer URL to Map
func (c URL) ToMap() map[string]string {
paramsMap := make(map[string]string)
- for k, v := range c.Params {
- paramsMap[k] = v[0]
- }
+ c.RangeParams(func(key, value string) bool {
+ paramsMap[key] = value
+ return true
+ })
+
if c.Protocol != "" {
paramsMap["protocol"] = c.Protocol
}
@@ -413,40 +506,24 @@
// configuration > reference config >service config
// in this function we should merge the reference local url config into the service url from registry.
//TODO configuration merge, in the future , the configuration center's config should merge too.
-func MergeUrl(serviceUrl URL, referenceUrl *URL) URL {
- mergedUrl := serviceUrl
- var methodConfigMergeFcn = []func(method string){}
+
+func MergeUrl(serviceUrl *URL, referenceUrl *URL) *URL {
+ mergedUrl := serviceUrl.Clone()
+
//iterator the referenceUrl if serviceUrl not have the key ,merge in
-
- for k, v := range referenceUrl.Params {
- if _, ok := mergedUrl.Params[k]; !ok {
- mergedUrl.Params.Set(k, v[0])
+ referenceUrl.RangeParams(func(key, value string) bool {
+ if v := mergedUrl.GetParam(key, ""); len(v) == 0 {
+ mergedUrl.SetParam(key, value)
}
- }
- //loadBalance strategy config
- if v := referenceUrl.Params.Get(constant.LOADBALANCE_KEY); v != "" {
- mergedUrl.Params.Set(constant.LOADBALANCE_KEY, v)
- }
- methodConfigMergeFcn = append(methodConfigMergeFcn, func(method string) {
- if v := referenceUrl.Params.Get(method + "." + constant.LOADBALANCE_KEY); v != "" {
- mergedUrl.Params.Set(method+"."+constant.LOADBALANCE_KEY, v)
- }
+ return true
})
-
- //cluster strategy config
- if v := referenceUrl.Params.Get(constant.CLUSTER_KEY); v != "" {
- mergedUrl.Params.Set(constant.CLUSTER_KEY, v)
- }
- methodConfigMergeFcn = append(methodConfigMergeFcn, func(method string) {
- if v := referenceUrl.Params.Get(method + "." + constant.CLUSTER_KEY); v != "" {
- mergedUrl.Params.Set(method+"."+constant.CLUSTER_KEY, v)
- }
- })
+ //loadBalance,cluster,retries strategy config
+ methodConfigMergeFcn := mergeNormalParam(mergedUrl, referenceUrl, []string{constant.LOADBALANCE_KEY, constant.CLUSTER_KEY, constant.RETRIES_KEY})
//remote timestamp
- if v := serviceUrl.Params.Get(constant.TIMESTAMP_KEY); v != "" {
- mergedUrl.Params.Set(constant.REMOTE_TIMESTAMP_KEY, v)
- mergedUrl.Params.Set(constant.TIMESTAMP_KEY, referenceUrl.Params.Get(constant.TIMESTAMP_KEY))
+ if v := serviceUrl.GetParam(constant.TIMESTAMP_KEY, ""); len(v) > 0 {
+ mergedUrl.SetParam(constant.REMOTE_TIMESTAMP_KEY, v)
+ mergedUrl.SetParam(constant.TIMESTAMP_KEY, referenceUrl.GetParam(constant.TIMESTAMP_KEY, ""))
}
//finally execute methodConfigMergeFcn
@@ -458,3 +535,28 @@
return mergedUrl
}
+func (c *URL) Clone() *URL {
+ newUrl := &URL{}
+ copier.Copy(newUrl, c)
+ newUrl.params = url.Values{}
+ c.RangeParams(func(key, value string) bool {
+ newUrl.SetParam(key, value)
+ return true
+ })
+ return newUrl
+}
+
+func mergeNormalParam(mergedUrl *URL, referenceUrl *URL, paramKeys []string) []func(method string) {
+ var methodConfigMergeFcn = []func(method string){}
+ for _, paramKey := range paramKeys {
+ if v := referenceUrl.GetParam(paramKey, ""); len(v) > 0 {
+ mergedUrl.SetParam(paramKey, v)
+ }
+ methodConfigMergeFcn = append(methodConfigMergeFcn, func(method string) {
+ if v := referenceUrl.GetParam(method+"."+paramKey, ""); len(v) > 0 {
+ mergedUrl.SetParam(method+"."+paramKey, v)
+ }
+ })
+ }
+ return methodConfigMergeFcn
+}
diff --git a/common/url_test.go b/common/url_test.go
index 143e31c..41fd374 100644
--- a/common/url_test.go
+++ b/common/url_test.go
@@ -52,11 +52,11 @@
assert.Equal(t, "127.0.0.1", u.Ip)
assert.Equal(t, "8080", u.Port)
assert.Equal(t, methods, u.Methods)
- assert.Equal(t, params, u.Params)
+ assert.Equal(t, params, u.params)
}
func TestURL(t *testing.T) {
- u, err := NewURL(context.TODO(), "dubbo://:@127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&"+
+ u, err := NewURL(context.TODO(), "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&"+
"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+
"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&"+
"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&"+
@@ -74,16 +74,16 @@
assert.Equal(t, "anyhost=true&application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-"+
"provider-golang-1.0.0&environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%"+
"2C&module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&side=provider&timeout=3000&t"+
- "imestamp=1556509797245", u.Params.Encode())
+ "imestamp=1556509797245", u.params.Encode())
- assert.Equal(t, "dubbo://:@127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&application=BDTServi"+
+ assert.Equal(t, "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&application=BDTServi"+
"ce&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&environment=dev&interface=com.ikure"+
"nto.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&module=dubbogo+user-info+server&org=ikurento.com&owner="+
"ZX&pid=1447&revision=0.0.1&side=provider&timeout=3000×tamp=1556509797245", u.String())
}
func TestURLWithoutSchema(t *testing.T) {
- u, err := NewURL(context.TODO(), "@127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&"+
+ u, err := NewURL(context.TODO(), "127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&"+
"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+
"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&"+
"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&"+
@@ -101,22 +101,22 @@
assert.Equal(t, "anyhost=true&application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-"+
"provider-golang-1.0.0&environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%"+
"2C&module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&side=provider&timeout=3000&t"+
- "imestamp=1556509797245", u.Params.Encode())
+ "imestamp=1556509797245", u.params.Encode())
- assert.Equal(t, "dubbo://:@127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&application=BDTServi"+
+ assert.Equal(t, "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&application=BDTServi"+
"ce&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&environment=dev&interface=com.ikure"+
"nto.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&module=dubbogo+user-info+server&org=ikurento.com&owner="+
"ZX&pid=1447&revision=0.0.1&side=provider&timeout=3000×tamp=1556509797245", u.String())
}
func TestURL_URLEqual(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")
+ 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")
assert.NoError(t, err)
- u2, err := NewURL(context.TODO(), "dubbo://:@127.0.0.2:20001/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=&version=2.6.0")
+ u2, err := NewURL(context.TODO(), "dubbo://127.0.0.2:20001/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=&version=2.6.0")
assert.NoError(t, err)
assert.True(t, u1.URLEqual(u2))
- u3, err := NewURL(context.TODO(), "dubbo://:@127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=gg&version=2.6.0")
+ u3, err := NewURL(context.TODO(), "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=gg&version=2.6.0")
assert.NoError(t, err)
assert.False(t, u1.URLEqual(u3))
}
@@ -124,7 +124,7 @@
func TestURL_GetParam(t *testing.T) {
params := url.Values{}
params.Set("key", "value")
- u := URL{baseUrl: baseUrl{Params: params}}
+ u := URL{baseUrl: baseUrl{params: params}}
v := u.GetParam("key", "default")
assert.Equal(t, "value", v)
@@ -136,7 +136,7 @@
func TestURL_GetParamInt(t *testing.T) {
params := url.Values{}
params.Set("key", "3")
- u := URL{baseUrl: baseUrl{Params: params}}
+ u := URL{baseUrl: baseUrl{params: params}}
v := u.GetParamInt("key", 1)
assert.Equal(t, int64(3), v)
@@ -148,7 +148,7 @@
func TestURL_GetParamBool(t *testing.T) {
params := url.Values{}
params.Set("force", "true")
- u := URL{baseUrl: baseUrl{Params: params}}
+ u := URL{baseUrl: baseUrl{params: params}}
v := u.GetParamBool("force", false)
assert.Equal(t, true, v)
@@ -161,7 +161,7 @@
rule := "host = 2.2.2.2,1.1.1.1,3.3.3.3 & host !=1.1.1.1 => host = 1.2.3.4"
params := url.Values{}
params.Set("rule", base64.URLEncoding.EncodeToString([]byte(rule)))
- u := URL{baseUrl: baseUrl{Params: params}}
+ u := URL{baseUrl: baseUrl{params: params}}
v, _ := u.GetParamAndDecoded("rule")
assert.Equal(t, rule, v)
}
@@ -196,7 +196,7 @@
func TestURL_GetMethodParamInt(t *testing.T) {
params := url.Values{}
params.Set("methods.GetValue.timeout", "3")
- u := URL{baseUrl: baseUrl{Params: params}}
+ u := URL{baseUrl: baseUrl{params: params}}
v := u.GetMethodParamInt("GetValue", "timeout", 1)
assert.Equal(t, int64(3), v)
@@ -208,7 +208,7 @@
func TestURL_GetMethodParam(t *testing.T) {
params := url.Values{}
params.Set("methods.GetValue.timeout", "3s")
- u := URL{baseUrl: baseUrl{Params: params}}
+ u := URL{baseUrl: baseUrl{params: params}}
v := u.GetMethodParam("GetValue", "timeout", "1s")
assert.Equal(t, "3s", v)
@@ -220,15 +220,42 @@
func TestMergeUrl(t *testing.T) {
referenceUrlParams := url.Values{}
referenceUrlParams.Set(constant.CLUSTER_KEY, "random")
+ referenceUrlParams.Set(constant.RETRIES_KEY, "1")
referenceUrlParams.Set("test3", "1")
+ referenceUrlParams.Set("methods.testMethod."+constant.RETRIES_KEY, "1")
serviceUrlParams := url.Values{}
serviceUrlParams.Set("test2", "1")
serviceUrlParams.Set(constant.CLUSTER_KEY, "roundrobin")
- referenceUrl, _ := NewURL(context.TODO(), "mock1://127.0.0.1:1111", WithParams(referenceUrlParams))
+ serviceUrlParams.Set(constant.RETRIES_KEY, "2")
+ serviceUrlParams.Set("methods.testMethod."+constant.RETRIES_KEY, "2")
+ referenceUrl, _ := NewURL(context.TODO(), "mock1://127.0.0.1:1111", WithParams(referenceUrlParams), WithMethods([]string{"testMethod"}))
serviceUrl, _ := NewURL(context.TODO(), "mock2://127.0.0.1:20000", WithParams(serviceUrlParams))
- mergedUrl := MergeUrl(serviceUrl, &referenceUrl)
+ mergedUrl := MergeUrl(&serviceUrl, &referenceUrl)
assert.Equal(t, "random", mergedUrl.GetParam(constant.CLUSTER_KEY, ""))
assert.Equal(t, "1", mergedUrl.GetParam("test2", ""))
assert.Equal(t, "1", mergedUrl.GetParam("test3", ""))
+ assert.Equal(t, "1", mergedUrl.GetParam(constant.RETRIES_KEY, ""))
+ assert.Equal(t, "1", mergedUrl.GetParam("methods.testMethod."+constant.RETRIES_KEY, ""))
+}
+
+func TestURL_SetParams(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)
+ params := url.Values{}
+ params.Set("key", "3")
+ u1.SetParams(params)
+ assert.Equal(t, "3", u1.GetParam("key", ""))
+ assert.Equal(t, "2.6.0", u1.GetParam("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.GetParam("configVersion", ""))
+ u2.Protocol = "provider"
+ assert.Equal(t, u1.Protocol, "dubbo")
+ assert.Equal(t, u2.Protocol, "provider")
}
diff --git a/common/utils/net.go b/common/utils/net.go
index 41d7b9e..47a2502 100644
--- a/common/utils/net.go
+++ b/common/utils/net.go
@@ -19,6 +19,7 @@
import (
"net"
+ "strings"
)
import (
@@ -37,44 +38,39 @@
}
}
-// ref: https://stackoverflow.com/questions/23558425/how-do-i-get-the-local-ip-address-in-go
func GetLocalIP() (string, error) {
- ifs, err := net.Interfaces()
+ faces, err := net.Interfaces()
if err != nil {
return "", perrors.WithStack(err)
}
- var ipAddr []byte
- for _, i := range ifs {
- addrs, err := i.Addrs()
+ var addr net.IP
+ for _, face := range faces {
+ if !isValidNetworkInterface(face) {
+ continue
+ }
+
+ addrs, err := face.Addrs()
if err != nil {
return "", perrors.WithStack(err)
}
- var ip net.IP
- for _, addr := range addrs {
- switch v := addr.(type) {
- case *net.IPNet:
- ip = v.IP
- case *net.IPAddr:
- ip = v.IP
- }
- if !ip.IsLoopback() && ip.To4() != nil && isPrivateIP(ip.String()) {
- ipAddr = ip
- break
+ if ipv4, ok := getValidIPv4(addrs); ok {
+ addr = ipv4
+ if isPrivateIP(ipv4) {
+ return ipv4.String(), nil
}
}
}
- if ipAddr == nil {
+ if addr == nil {
return "", perrors.Errorf("can not get local IP")
}
- return net.IP(ipAddr).String(), nil
+ return addr.String(), nil
}
-func isPrivateIP(ipAddr string) bool {
- ip := net.ParseIP(ipAddr)
+func isPrivateIP(ip net.IP) bool {
for _, priv := range privateBlocks {
if priv.Contains(ip) {
return true
@@ -82,3 +78,47 @@
}
return false
}
+
+func getValidIPv4(addrs []net.Addr) (net.IP, bool) {
+ for _, addr := range addrs {
+ var ip net.IP
+
+ switch v := addr.(type) {
+ case *net.IPNet:
+ ip = v.IP
+ case *net.IPAddr:
+ ip = v.IP
+ }
+
+ if ip == nil || ip.IsLoopback() {
+ continue
+ }
+
+ ip = ip.To4()
+ if ip == nil {
+ // not an valid ipv4 address
+ continue
+ }
+
+ return ip, true
+ }
+ return nil, false
+}
+
+func isValidNetworkInterface(face net.Interface) bool {
+ if face.Flags&net.FlagUp == 0 {
+ // interface down
+ return false
+ }
+
+ if face.Flags&net.FlagLoopback != 0 {
+ // loopback interface
+ return false
+ }
+
+ if strings.Contains(strings.ToLower(face.Name), "docker") {
+ return false
+ }
+
+ return true
+}
diff --git a/config/application_config.go b/config/application_config.go
index af4ffd6..fcd4d38 100644
--- a/config/application_config.go
+++ b/config/application_config.go
@@ -17,7 +17,13 @@
package config
-import "github.com/apache/dubbo-go/common/constant"
+import (
+ "github.com/creasty/defaults"
+)
+
+import (
+ "github.com/apache/dubbo-go/common/constant"
+)
type ApplicationConfig struct {
Organization string `yaml:"organization" json:"organization,omitempty" property:"organization"`
@@ -37,3 +43,13 @@
func (c *ApplicationConfig) SetId(id string) {
}
+func (c *ApplicationConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ if err := defaults.Set(c); err != nil {
+ return err
+ }
+ type plain ApplicationConfig
+ if err := unmarshal((*plain)(c)); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/config/base_config.go b/config/base_config.go
index 54ad8ab..264eeda 100644
--- a/config/base_config.go
+++ b/config/base_config.go
@@ -20,10 +20,13 @@
"context"
"reflect"
"strconv"
+ "strings"
)
+
import (
perrors "github.com/pkg/errors"
)
+
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/config"
@@ -60,6 +63,7 @@
factory := extension.GetConfigCenterFactory(c.ConfigCenterConfig.Protocol)
dynamicConfig, err := factory.GetDynamicConfiguration(c.configCenterUrl)
+ config.GetEnvInstance().SetDynamicConfiguration(dynamicConfig)
if err != nil {
logger.Errorf("Get dynamic configuration error , error message is %v", err)
return perrors.WithStack(err)
@@ -69,43 +73,109 @@
logger.Errorf("Get config content in dynamic configuration error , error message is %v", err)
return perrors.WithStack(err)
}
+ var appGroup string
+ var appContent string
+ if providerConfig != nil && providerConfig.ApplicationConfig != nil &&
+ reflect.ValueOf(c.fatherConfig).Elem().Type().Name() == "ProviderConfig" {
+ appGroup = providerConfig.ApplicationConfig.Name
+ } else if consumerConfig != nil && consumerConfig.ApplicationConfig != nil &&
+ reflect.ValueOf(c.fatherConfig).Elem().Type().Name() == "ConsumerConfig" {
+ appGroup = consumerConfig.ApplicationConfig.Name
+ }
+
+ if len(appGroup) != 0 {
+ configFile := c.ConfigCenterConfig.AppConfigFile
+ if len(configFile) == 0 {
+ configFile = c.ConfigCenterConfig.ConfigFile
+ }
+ appContent, err = dynamicConfig.GetConfig(configFile, config_center.WithGroup(appGroup))
+ }
+ //global config file
mapContent, err := dynamicConfig.Parser().Parse(content)
if err != nil {
return perrors.WithStack(err)
}
config.GetEnvInstance().UpdateExternalConfigMap(mapContent)
+
+ //appGroup config file
+ if len(appContent) != 0 {
+ appMapConent, err := dynamicConfig.Parser().Parse(appContent)
+ if err != nil {
+ return perrors.WithStack(err)
+ }
+ config.GetEnvInstance().UpdateAppExternalConfigMap(appMapConent)
+ }
+
return nil
}
-func getKeyPrefix(val reflect.Value, id reflect.Value) string {
+func getKeyPrefix(val reflect.Value) []string {
var (
prefix string
- idStr string
)
- if id.Kind() == reflect.String {
- idStr = id.Interface().(string)
- }
if val.CanAddr() {
prefix = val.Addr().MethodByName("Prefix").Call(nil)[0].String()
} else {
prefix = val.MethodByName("Prefix").Call(nil)[0].String()
}
+ var retPrefixs []string
- if idStr != "" {
- return prefix + idStr + "."
- } else {
- return prefix
+ for _, pfx := range strings.Split(prefix, "|") {
+
+ retPrefixs = append(retPrefixs, pfx)
+
}
-}
+ return retPrefixs
+}
+func getPtrElement(v reflect.Value) reflect.Value {
+ if v.Kind() == reflect.Ptr {
+ v = v.Elem()
+ if v.Kind() == reflect.Ptr {
+ return getPtrElement(v)
+ }
+ }
+ return v
+}
func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryConfiguration) {
for i := 0; i < val.NumField(); i++ {
if key := val.Type().Field(i).Tag.Get("property"); key != "-" && key != "" {
f := val.Field(i)
if f.IsValid() {
setBaseValue := func(f reflect.Value) {
- ok, value := config.GetProperty(getKeyPrefix(val, id) + key)
+
+ var (
+ ok bool
+ value string
+ idStr string
+ )
+
+ prefixs := getKeyPrefix(val)
+
+ if id.Kind() == reflect.String {
+ idStr = id.Interface().(string)
+ }
+
+ for _, pfx := range prefixs {
+
+ if len(pfx) > 0 {
+ if len(idStr) > 0 {
+ ok, value = config.GetProperty(pfx + idStr + "." + key)
+ }
+ if len(value) == 0 || !ok {
+ ok, value = config.GetProperty(pfx + key)
+ }
+
+ } else {
+ ok, value = config.GetProperty(key)
+ }
+
+ if ok {
+ break
+ }
+
+ }
if ok {
switch f.Kind() {
case reflect.Int64:
@@ -151,12 +221,12 @@
}
- setBaseValue(f)
if f.Kind() == reflect.Ptr {
- if f.Elem().Kind() == reflect.Struct {
- setFieldValue(f.Elem(), reflect.Value{}, config)
+ f = getPtrElement(f)
+ if f.Kind() == reflect.Struct {
+ setFieldValue(f, reflect.Value{}, config)
} else {
- setBaseValue(f.Elem())
+ setBaseValue(f)
}
}
@@ -167,10 +237,11 @@
for i := 0; i < f.Len(); i++ {
e := f.Index(i)
if e.Kind() == reflect.Ptr {
- if e.Elem().Kind() == reflect.Struct {
- setFieldValue(e.Elem(), reflect.Value{}, config)
+ e = getPtrElement(e)
+ if e.Kind() == reflect.Struct {
+ setFieldValue(e, reflect.Value{}, config)
} else {
- setBaseValue(e.Elem())
+ setBaseValue(e)
}
}
@@ -183,10 +254,16 @@
//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()))
+ for _, pfx := range strings.Split(prefix, "|") {
+ m := config.GetSubProperty(pfx)
+ if m != nil {
+ for k := range m {
+ f.SetMapIndex(reflect.ValueOf(k), reflect.New(f.Type().Elem().Elem()))
+ }
+ }
+
}
+
}
//iter := f.MapRange()
@@ -195,10 +272,11 @@
v := f.MapIndex(k)
switch v.Kind() {
case reflect.Ptr:
- if v.Elem().Kind() == reflect.Struct {
- setFieldValue(v.Elem(), k, config)
+ v = getPtrElement(v)
+ if v.Kind() == reflect.Struct {
+ setFieldValue(v, k, config)
} else {
- setBaseValue(v.Elem())
+ setBaseValue(v)
}
case reflect.Int64, reflect.String, reflect.Bool, reflect.Float64:
setBaseValue(v)
@@ -207,6 +285,7 @@
}
}
}
+ setBaseValue(f)
}
}
@@ -214,8 +293,13 @@
}
func (c *BaseConfig) fresh() {
configList := config.GetEnvInstance().Configuration()
- config := configList.Front().Value.(*config.InmemoryConfiguration)
+ for element := configList.Front(); element != nil; element = element.Next() {
+ config := element.Value.(*config.InmemoryConfiguration)
+ c.freshInternalConfig(config)
+ }
+}
+func (c *BaseConfig) freshInternalConfig(config *config.InmemoryConfiguration) {
//reflect to init struct
tp := reflect.ValueOf(c.fatherConfig).Elem().Type()
initializeStruct(tp, reflect.ValueOf(c.fatherConfig).Elem())
diff --git a/config/base_config_test.go b/config/base_config_test.go
index d07d983..6dc3749 100644
--- a/config/base_config_test.go
+++ b/config/base_config_test.go
@@ -92,7 +92,7 @@
Protocol: "mock",
Cluster: "failover",
Loadbalance: "random",
- Retries: 3,
+ Retries: "3",
Group: "huadong_idc",
Version: "1.0.0",
Methods: []*MethodConfig{
@@ -100,14 +100,14 @@
InterfaceId: "MockService",
InterfaceName: "com.MockService",
Name: "GetUser",
- Retries: 2,
+ Retries: "2",
Loadbalance: "random",
},
{
InterfaceId: "MockService",
InterfaceName: "com.MockService",
Name: "GetUser1",
- Retries: 2,
+ Retries: "2",
Loadbalance: "random",
},
},
@@ -118,9 +118,261 @@
c.SetFatherConfig(father)
c.fresh()
assert.Equal(t, "mock100", father.Registries["shanghai_reg1"].Protocol)
- assert.Equal(t, int64(10), father.References["MockService"].Retries)
+ assert.Equal(t, "10", father.References["MockService"].Retries)
- assert.Equal(t, int64(10), father.References["MockService"].Methods[0].Retries)
+ assert.Equal(t, "10", father.References["MockService"].Methods[0].Retries)
+ assert.Equal(t, &[]bool{false}[0], father.Check)
+ assert.Equal(t, "dubbo", father.ApplicationConfig.Name)
+}
+
+func Test_appExternal_refresh(t *testing.T) {
+ c := &BaseConfig{}
+ mockMap := map[string]string{}
+ mockMap["dubbo.registries.shanghai_reg1.protocol"] = "mock100"
+ mockMap["dubbo.reference.com.MockService.MockService.retries"] = "10"
+ mockMap["dubbo.reference.com.MockService.retries"] = "5"
+ mockMap["dubbo.com.MockService.MockService.GetUser.retries"] = "10"
+ mockMap["dubbo.consumer.check"] = "false"
+ mockMap["dubbo.application.name"] = "dubbo"
+
+ config.GetEnvInstance().UpdateAppExternalConfigMap(mockMap)
+ mockMap["dubbo.consumer.check"] = "true"
+ config.GetEnvInstance().UpdateExternalConfigMap(mockMap)
+ father := &ConsumerConfig{
+ Check: &[]bool{true}[0],
+ ApplicationConfig: &ApplicationConfig{
+ Organization: "dubbo_org",
+ Name: "dubbo",
+ Module: "module",
+ Version: "2.6.0",
+ Owner: "dubbo",
+ Environment: "test"},
+ Registries: map[string]*RegistryConfig{
+ //"shanghai_reg1": {
+ // id: "shanghai_reg1",
+ // Protocol: "mock",
+ // TimeoutStr: "2s",
+ // Group: "shanghai_idc",
+ // Address: "127.0.0.1:2181",
+ // Username: "user1",
+ // Password: "pwd1",
+ //},
+ "shanghai_reg2": {
+ Protocol: "mock",
+ TimeoutStr: "2s",
+ Group: "shanghai_idc",
+ Address: "127.0.0.2:2181",
+ Username: "user1",
+ Password: "pwd1",
+ },
+ "hangzhou_reg1": {
+ Protocol: "mock",
+ TimeoutStr: "2s",
+ Group: "hangzhou_idc",
+ Address: "127.0.0.3:2181",
+ Username: "user1",
+ Password: "pwd1",
+ },
+ "hangzhou_reg2": {
+ Protocol: "mock",
+ TimeoutStr: "2s",
+ Group: "hangzhou_idc",
+ Address: "127.0.0.4:2181",
+ Username: "user1",
+ Password: "pwd1",
+ },
+ },
+ References: map[string]*ReferenceConfig{
+ "MockService": {
+ InterfaceName: "com.MockService",
+ Protocol: "mock",
+ Cluster: "failover",
+ Loadbalance: "random",
+ Retries: "3",
+ Group: "huadong_idc",
+ Version: "1.0.0",
+ Methods: []*MethodConfig{
+ {
+ InterfaceId: "MockService",
+ InterfaceName: "com.MockService",
+ Name: "GetUser",
+ Retries: "2",
+ Loadbalance: "random",
+ },
+ {
+ InterfaceId: "MockService",
+ InterfaceName: "com.MockService",
+ Name: "GetUser1",
+ Retries: "2",
+ Loadbalance: "random",
+ },
+ },
+ },
+ },
+ }
+
+ c.SetFatherConfig(father)
+ c.fresh()
+ assert.Equal(t, "mock100", father.Registries["shanghai_reg1"].Protocol)
+ assert.Equal(t, "10", father.References["MockService"].Retries)
+
+ assert.Equal(t, "10", father.References["MockService"].Methods[0].Retries)
+ assert.Equal(t, &[]bool{true}[0], father.Check)
+ assert.Equal(t, "dubbo", father.ApplicationConfig.Name)
+}
+
+func Test_appExternalWithoutId_refresh(t *testing.T) {
+ c := &BaseConfig{}
+ mockMap := map[string]string{}
+ mockMap["dubbo.registries.shanghai_reg1.protocol"] = "mock100"
+ mockMap["dubbo.reference.com.MockService.retries"] = "10"
+ mockMap["dubbo.com.MockService.MockService.GetUser.retries"] = "10"
+ mockMap["dubbo.consumer.check"] = "false"
+ mockMap["dubbo.application.name"] = "dubbo"
+
+ config.GetEnvInstance().UpdateAppExternalConfigMap(mockMap)
+ mockMap["dubbo.consumer.check"] = "true"
+ config.GetEnvInstance().UpdateExternalConfigMap(mockMap)
+ father := &ConsumerConfig{
+ Check: &[]bool{true}[0],
+ ApplicationConfig: &ApplicationConfig{
+ Organization: "dubbo_org",
+ Name: "dubbo",
+ Module: "module",
+ Version: "2.6.0",
+ Owner: "dubbo",
+ Environment: "test"},
+ Registries: map[string]*RegistryConfig{
+ //"shanghai_reg1": {
+ // id: "shanghai_reg1",
+ // Protocol: "mock",
+ // TimeoutStr: "2s",
+ // Group: "shanghai_idc",
+ // Address: "127.0.0.1:2181",
+ // Username: "user1",
+ // Password: "pwd1",
+ //},
+ "shanghai_reg2": {
+ Protocol: "mock",
+ TimeoutStr: "2s",
+ Group: "shanghai_idc",
+ Address: "127.0.0.2:2181",
+ Username: "user1",
+ Password: "pwd1",
+ },
+ "hangzhou_reg1": {
+ Protocol: "mock",
+ TimeoutStr: "2s",
+ Group: "hangzhou_idc",
+ Address: "127.0.0.3:2181",
+ Username: "user1",
+ Password: "pwd1",
+ },
+ "hangzhou_reg2": {
+ Protocol: "mock",
+ TimeoutStr: "2s",
+ Group: "hangzhou_idc",
+ Address: "127.0.0.4:2181",
+ Username: "user1",
+ Password: "pwd1",
+ },
+ },
+ References: map[string]*ReferenceConfig{
+ "MockService": {
+ InterfaceName: "com.MockService",
+ Protocol: "mock",
+ Cluster: "failover",
+ Loadbalance: "random",
+ Retries: "3",
+ Group: "huadong_idc",
+ Version: "1.0.0",
+ Methods: []*MethodConfig{
+ {
+ InterfaceId: "MockService",
+ InterfaceName: "com.MockService",
+ Name: "GetUser",
+ Retries: "3",
+ Loadbalance: "random",
+ },
+ {
+ InterfaceId: "MockService",
+ InterfaceName: "com.MockService",
+ Name: "GetUser1",
+ Retries: "2",
+ Loadbalance: "random",
+ },
+ },
+ },
+ },
+ }
+
+ c.SetFatherConfig(father)
+ c.fresh()
+ assert.Equal(t, "mock100", father.Registries["shanghai_reg1"].Protocol)
+ assert.Equal(t, "10", father.References["MockService"].Retries)
+
+ assert.Equal(t, "10", father.References["MockService"].Methods[0].Retries)
+ assert.Equal(t, &[]bool{true}[0], father.Check)
+ assert.Equal(t, "dubbo", father.ApplicationConfig.Name)
+}
+
+func Test_refresh_singleRegistry(t *testing.T) {
+ c := &BaseConfig{}
+ mockMap := map[string]string{}
+ mockMap["dubbo.registry.address"] = "mock100://127.0.0.1:2181"
+ 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"
+
+ config.GetEnvInstance().UpdateExternalConfigMap(mockMap)
+
+ father := &ConsumerConfig{
+ Check: &[]bool{true}[0],
+ ApplicationConfig: &ApplicationConfig{
+ Organization: "dubbo_org",
+ Name: "dubbo",
+ Module: "module",
+ Version: "2.6.0",
+ Owner: "dubbo",
+ Environment: "test"},
+ Registries: map[string]*RegistryConfig{},
+ Registry: &RegistryConfig{},
+ References: map[string]*ReferenceConfig{
+ "MockService": {
+ InterfaceName: "com.MockService",
+ Protocol: "mock",
+ Cluster: "failover",
+ Loadbalance: "random",
+ Retries: "3",
+ Group: "huadong_idc",
+ Version: "1.0.0",
+ Methods: []*MethodConfig{
+ {
+ InterfaceId: "MockService",
+ InterfaceName: "com.MockService",
+ Name: "GetUser",
+ Retries: "2",
+ Loadbalance: "random",
+ },
+ {
+ InterfaceId: "MockService",
+ InterfaceName: "com.MockService",
+ Name: "GetUser1",
+ Retries: "2",
+ Loadbalance: "random",
+ },
+ },
+ },
+ },
+ }
+
+ c.SetFatherConfig(father)
+ c.fresh()
+ assert.Equal(t, "mock100://127.0.0.1:2181", father.Registry.Address)
+ assert.Equal(t, "10", father.References["MockService"].Retries)
+
+ assert.Equal(t, "10", father.References["MockService"].Methods[0].Retries)
assert.Equal(t, &[]bool{false}[0], father.Check)
assert.Equal(t, "dubbo", father.ApplicationConfig.Name)
}
@@ -188,7 +440,7 @@
Protocol: "mock",
Cluster: "failover",
Loadbalance: "random",
- Retries: 3,
+ Retries: "3",
Group: "huadong_idc",
Version: "1.0.0",
Methods: []*MethodConfig{
@@ -196,13 +448,13 @@
InterfaceId: "MockService",
InterfaceName: "com.MockService",
Name: "GetUser",
- Retries: 2,
+ Retries: "2",
Loadbalance: "random",
},
{InterfaceId: "MockService",
InterfaceName: "com.MockService",
Name: "GetUser1",
- Retries: 2,
+ Retries: "2",
Loadbalance: "random",
},
},
@@ -213,9 +465,9 @@
c.SetFatherConfig(father)
c.fresh()
assert.Equal(t, "mock100", father.Registries["shanghai_reg1"].Protocol)
- assert.Equal(t, int64(10), father.Services["MockService"].Retries)
+ assert.Equal(t, "10", father.Services["MockService"].Retries)
- assert.Equal(t, int64(10), father.Services["MockService"].Methods[0].Retries)
+ assert.Equal(t, "10", father.Services["MockService"].Methods[0].Retries)
assert.Equal(t, "dubbo", father.ApplicationConfig.Name)
assert.Equal(t, "20001", father.Protocols["jsonrpc1"].Port)
}
@@ -233,7 +485,7 @@
}}
err := c.startConfigCenter(context.Background())
assert.NoError(t, err)
- b, v := config.GetEnvInstance().Configuration().Front().Value.(*config.InmemoryConfiguration).GetProperty("dubbo.application.organization")
+ b, v := config.GetEnvInstance().Configuration().Back().Value.(*config.InmemoryConfiguration).GetProperty("dubbo.application.organization")
assert.True(t, b)
assert.Equal(t, "ikurento.com", v)
}
diff --git a/config/config_center_config.go b/config/config_center_config.go
index 47efce1..ed43558 100644
--- a/config/config_center_config.go
+++ b/config/config_center_config.go
@@ -22,15 +22,31 @@
"time"
)
+import (
+ "github.com/creasty/defaults"
+)
+
type ConfigCenterConfig struct {
- context context.Context
- Protocol string `required:"true" yaml:"protocol" json:"protocol,omitempty"`
- Address string `yaml:"address" json:"address,omitempty"`
- Cluster string `yaml:"cluster" json:"cluster,omitempty"`
- Group string `default:"dubbo" yaml:"group" json:"group,omitempty"`
- 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"`
- TimeoutStr string `yaml:"timeout" json:"timeout,omitempty"`
- timeout time.Duration
+ context context.Context
+ Protocol string `required:"true" yaml:"protocol" json:"protocol,omitempty"`
+ Address string `yaml:"address" json:"address,omitempty"`
+ Cluster string `yaml:"cluster" json:"cluster,omitempty"`
+ Group string `default:"dubbo" yaml:"group" json:"group,omitempty"`
+ 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"`
+ AppConfigFile string `default:"dubbo.properties" yaml:"app_config_file" json:"app_config_file,omitempty"`
+ TimeoutStr string `yaml:"timeout" json:"timeout,omitempty"`
+ timeout time.Duration
+}
+
+func (c *ConfigCenterConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ if err := defaults.Set(c); err != nil {
+ return err
+ }
+ type plain ConfigCenterConfig
+ if err := unmarshal((*plain)(c)); err != nil {
+ return err
+ }
+ return nil
}
diff --git a/config/config_loader.go b/config/config_loader.go
index c5127c8..0b48761 100644
--- a/config/config_loader.go
+++ b/config/config_loader.go
@@ -54,6 +54,19 @@
providerConfig = nil
}
}
+func checkRegistries(registries map[string]*RegistryConfig, singleRegistry *RegistryConfig) {
+ if len(registries) == 0 && singleRegistry != nil {
+ registries[constant.DEFAULT_KEY] = singleRegistry
+ }
+}
+
+func checkApplicationName(config *ApplicationConfig) {
+ if config == nil || len(config.Name) == 0 {
+ errMsg := "application config must not be nil, pls check your configuration"
+ logger.Errorf(errMsg)
+ panic(errMsg)
+ }
+}
// Dubbo Init
func Load() {
@@ -61,9 +74,11 @@
if consumerConfig == nil {
logger.Warnf("consumerConfig is nil!")
} else {
+ checkApplicationName(consumerConfig.ApplicationConfig)
if err := configCenterRefreshConsumer(); err != nil {
logger.Errorf("[consumer config center refresh] %#v", err)
}
+ checkRegistries(consumerConfig.Registries, consumerConfig.Registry)
for key, ref := range consumerConfig.References {
if ref.Generic {
genericService := NewGenericService(key)
@@ -92,7 +107,9 @@
checkok = false
count++
if count > maxWait {
- panic(fmt.Sprintf("Failed to check the status of the service %v . No provider available for the service to the consumer use dubbo version %v", refconfig.InterfaceName, constant.Version))
+ errMsg := fmt.Sprintf("Failed to check the status of the service %v . No provider available for the service to the consumer use dubbo version %v", refconfig.InterfaceName, constant.Version)
+ logger.Error(errMsg)
+ panic(errMsg)
}
time.Sleep(time.Second * 1)
break
@@ -113,9 +130,11 @@
if providerConfig == nil {
logger.Warnf("providerConfig is nil!")
} else {
+ checkApplicationName(providerConfig.ApplicationConfig)
if err := configCenterRefreshProvider(); err != nil {
logger.Errorf("[provider config center refresh] %#v", err)
}
+ checkRegistries(providerConfig.Registries, providerConfig.Registry)
for key, svs := range providerConfig.Services {
rpcService := GetProviderService(key)
if rpcService == nil {
diff --git a/config/config_loader_test.go b/config/config_loader_test.go
index 107fea0..498f826 100644
--- a/config/config_loader_test.go
+++ b/config/config_loader_test.go
@@ -29,6 +29,8 @@
import (
"github.com/apache/dubbo-go/cluster/cluster_impl"
"github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/common/config"
+ "github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/common/proxy/proxy_factory"
"github.com/apache/dubbo-go/config_center"
@@ -58,8 +60,36 @@
}
func TestLoad(t *testing.T) {
- doInit()
- doinit()
+ doInitConsumer()
+ doInitProvider()
+
+ ms := &MockService{}
+ SetConsumerService(ms)
+ SetProviderService(ms)
+
+ extension.SetProtocol("registry", GetProtocol)
+ extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster)
+ extension.SetProxyFactory("default", proxy_factory.NewDefaultProxyFactory)
+
+ Load()
+
+ assert.Equal(t, ms, GetRPCService(ms.Reference()))
+ ms2 := &struct {
+ MockService
+ }{}
+ RPCService(ms2)
+ assert.NotEqual(t, ms2, GetRPCService(ms2.Reference()))
+
+ conServices = map[string]common.RPCService{}
+ proServices = map[string]common.RPCService{}
+ common.ServiceMap.UnRegister("mock", "MockService")
+ consumerConfig = nil
+ providerConfig = nil
+}
+
+func TestLoadWithSingleReg(t *testing.T) {
+ doInitConsumerWithSingleRegistry()
+ doInitProviderWithSingleRegistry()
ms := &MockService{}
SetConsumerService(ms)
@@ -86,8 +116,8 @@
}
func TestWithNoRegLoad(t *testing.T) {
- doInit()
- doinit()
+ doInitConsumer()
+ doInitProvider()
providerConfig.Services["MockService"].Registry = ""
consumerConfig.References["MockService"].Registry = ""
ms := &MockService{}
@@ -145,3 +175,60 @@
assert.Equal(t, "127.0.0.1:2181", consumerConfig.Registries["hangzhouzk"].Address)
}
+
+func TestConfigLoaderWithConfigCenterSingleRegistry(t *testing.T) {
+ consumerConfig = nil
+ providerConfig = nil
+ config.NewEnvInstance()
+ extension.SetConfigCenterFactory("mock", func() config_center.DynamicConfigurationFactory {
+ return &config_center.MockDynamicConfigurationFactory{Content: `
+ dubbo.consumer.request_timeout=5s
+ dubbo.consumer.connect_timeout=5s
+ dubbo.application.organization=ikurento.com
+ dubbo.application.name=BDTService
+ dubbo.application.module=dubbogo user-info server
+ dubbo.application.version=0.0.1
+ dubbo.application.owner=ZX
+ dubbo.application.environment=dev
+ dubbo.registry.address=mock://127.0.0.1:2182
+ dubbo.service.com.ikurento.user.UserProvider.protocol=dubbo
+ dubbo.service.com.ikurento.user.UserProvider.interface=com.ikurento.user.UserProvider
+ dubbo.service.com.ikurento.user.UserProvider.loadbalance=random
+ dubbo.service.com.ikurento.user.UserProvider.warmup=100
+ dubbo.service.com.ikurento.user.UserProvider.cluster=failover
+ dubbo.protocols.jsonrpc1.name=jsonrpc
+ dubbo.protocols.jsonrpc1.ip=127.0.0.1
+ dubbo.protocols.jsonrpc1.port=20001
+`}
+ })
+
+ conPath, err := filepath.Abs("./testdata/consumer_config_with_configcenter.yml")
+ assert.NoError(t, err)
+ proPath, err := filepath.Abs("./testdata/provider_config.yml")
+ assert.NoError(t, err)
+
+ assert.Nil(t, consumerConfig)
+ assert.Equal(t, ConsumerConfig{}, GetConsumerConfig())
+ assert.Nil(t, providerConfig)
+ assert.Equal(t, ProviderConfig{}, GetProviderConfig())
+
+ err = ConsumerInit(conPath)
+ checkApplicationName(consumerConfig.ApplicationConfig)
+ configCenterRefreshConsumer()
+ checkRegistries(consumerConfig.Registries, consumerConfig.Registry)
+ assert.NoError(t, err)
+ err = ProviderInit(proPath)
+ checkApplicationName(providerConfig.ApplicationConfig)
+ configCenterRefreshProvider()
+ checkRegistries(providerConfig.Registries, providerConfig.Registry)
+ 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, "BDTService", consumerConfig.ApplicationConfig.Name)
+ assert.Equal(t, "mock://127.0.0.1:2182", consumerConfig.Registries[constant.DEFAULT_KEY].Address)
+
+}
diff --git a/config/config_utils.go b/config/config_utils.go
index 9083734..6bc574a 100644
--- a/config/config_utils.go
+++ b/config/config_utils.go
@@ -21,6 +21,7 @@
"regexp"
"strings"
)
+
import (
"github.com/apache/dubbo-go/common/constant"
)
diff --git a/config/consumer_config.go b/config/consumer_config.go
index 737339a..b1ebdd5 100644
--- a/config/consumer_config.go
+++ b/config/consumer_config.go
@@ -22,10 +22,13 @@
"path"
"time"
)
+
import (
+ "github.com/creasty/defaults"
perrors "github.com/pkg/errors"
"gopkg.in/yaml.v2"
)
+
import (
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/logger"
@@ -39,7 +42,7 @@
BaseConfig `yaml:",inline"`
Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"`
// application
- ApplicationConfig *ApplicationConfig `yaml:"application_config" json:"application_config,omitempty" property:"application_config"`
+ ApplicationConfig *ApplicationConfig `yaml:"application" json:"application,omitempty" property:"application"`
// client
Connect_Timeout string `default:"100ms" yaml:"connect_timeout" json:"connect_timeout,omitempty" property:"connect_timeout"`
ConnectTimeout time.Duration
@@ -49,9 +52,22 @@
ProxyFactory string `yaml:"proxy_factory" default:"default" json:"proxy_factory,omitempty" property:"proxy_factory"`
Check *bool `yaml:"check" json:"check,omitempty" property:"check"`
+ Registry *RegistryConfig `yaml:"registry" json:"registry,omitempty" property:"registry"`
Registries map[string]*RegistryConfig `yaml:"registries" json:"registries,omitempty" property:"registries"`
References map[string]*ReferenceConfig `yaml:"references" json:"references,omitempty" property:"references"`
ProtocolConf interface{} `yaml:"protocol_conf" json:"protocol_conf,omitempty" property:"protocol_conf"`
+ FilterConf interface{} `yaml:"filter_conf" json:"filter_conf,omitempty" property:"filter_conf" `
+}
+
+func (c *ConsumerConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ if err := defaults.Set(c); err != nil {
+ return err
+ }
+ type plain ConsumerConfig
+ if err := unmarshal((*plain)(c)); err != nil {
+ return err
+ }
+ return nil
}
func (*ConsumerConfig) Prefix() string {
diff --git a/config/method_config.go b/config/method_config.go
index 95479d1..ac9242a 100644
--- a/config/method_config.go
+++ b/config/method_config.go
@@ -17,6 +17,10 @@
package config
import (
+ "github.com/creasty/defaults"
+)
+
+import (
"github.com/apache/dubbo-go/common/constant"
)
@@ -24,7 +28,7 @@
InterfaceId string
InterfaceName string
Name string `yaml:"name" json:"name,omitempty" property:"name"`
- Retries int64 `yaml:"retries" json:"retries,omitempty" property:"retries"`
+ Retries string `yaml:"retries" json:"retries,omitempty" property:"retries"`
Loadbalance string `yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"`
Weight int64 `yaml:"weight" json:"weight,omitempty" property:"weight"`
}
@@ -36,3 +40,14 @@
return constant.DUBBO + "." + c.InterfaceName + "." + c.Name + "."
}
}
+
+func (c *MethodConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ if err := defaults.Set(c); err != nil {
+ return err
+ }
+ type plain MethodConfig
+ if err := unmarshal((*plain)(c)); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/config/protocol_config.go b/config/protocol_config.go
index 6440f30..b714236 100644
--- a/config/protocol_config.go
+++ b/config/protocol_config.go
@@ -19,6 +19,7 @@
import (
"strings"
)
+
import (
"github.com/apache/dubbo-go/common/constant"
)
diff --git a/config/provider_config.go b/config/provider_config.go
index a504eea..00faa1d 100644
--- a/config/provider_config.go
+++ b/config/provider_config.go
@@ -23,6 +23,7 @@
)
import (
+ "github.com/creasty/defaults"
perrors "github.com/pkg/errors"
"gopkg.in/yaml.v2"
)
@@ -41,11 +42,24 @@
Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"`
ProxyFactory string `yaml:"proxy_factory" default:"default" json:"proxy_factory,omitempty" property:"proxy_factory"`
- ApplicationConfig *ApplicationConfig `yaml:"application_config" json:"application_config,omitempty" property:"application_config"`
+ ApplicationConfig *ApplicationConfig `yaml:"application" json:"application,omitempty" property:"application"`
+ Registry *RegistryConfig `yaml:"registry" json:"registry,omitempty" property:"registry"`
Registries map[string]*RegistryConfig `yaml:"registries" json:"registries,omitempty" property:"registries"`
Services map[string]*ServiceConfig `yaml:"services" json:"services,omitempty" property:"services"`
Protocols map[string]*ProtocolConfig `yaml:"protocols" json:"protocols,omitempty" property:"protocols"`
ProtocolConf interface{} `yaml:"protocol_conf" json:"protocol_conf,omitempty" property:"protocol_conf" `
+ FilterConf interface{} `yaml:"filter_conf" json:"filter_conf,omitempty" property:"filter_conf" `
+}
+
+func (c *ProviderConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ if err := defaults.Set(c); err != nil {
+ return err
+ }
+ type plain ProviderConfig
+ if err := unmarshal((*plain)(c)); err != nil {
+ return err
+ }
+ return nil
}
func (*ProviderConfig) Prefix() string {
diff --git a/config/provider_config_test.go b/config/provider_config_test.go
new file mode 100644
index 0000000..db4b5f9
--- /dev/null
+++ b/config/provider_config_test.go
@@ -0,0 +1,33 @@
+package config
+
+import (
+ "path/filepath"
+ "testing"
+)
+
+import (
+ "github.com/stretchr/testify/assert"
+)
+
+func TestConsumerInit(t *testing.T) {
+ conPath, err := filepath.Abs("./testdata/consumer_config_with_configcenter.yml")
+ assert.NoError(t, err)
+ assert.NoError(t, ConsumerInit(conPath))
+ assert.Equal(t, "default", consumerConfig.ProxyFactory)
+ assert.Equal(t, "dubbo.properties", consumerConfig.ConfigCenterConfig.ConfigFile)
+ assert.Equal(t, "100ms", consumerConfig.Connect_Timeout)
+}
+
+func TestConsumerInitWithDefaultProtocol(t *testing.T) {
+ conPath, err := filepath.Abs("./testdata/consumer_config_withoutProtocol.yml")
+ assert.NoError(t, err)
+ assert.NoError(t, ConsumerInit(conPath))
+ assert.Equal(t, "dubbo", consumerConfig.References["UserProvider"].Protocol)
+}
+
+func TestProviderInitWithDefaultProtocol(t *testing.T) {
+ conPath, err := filepath.Abs("./testdata/provider_config_withoutProtocol.yml")
+ assert.NoError(t, err)
+ assert.NoError(t, ProviderInit(conPath))
+ assert.Equal(t, "dubbo", providerConfig.Services["UserProvider"].Protocol)
+}
diff --git a/config/reference_config.go b/config/reference_config.go
index f90e3aa..26976f1 100644
--- a/config/reference_config.go
+++ b/config/reference_config.go
@@ -26,6 +26,10 @@
)
import (
+ "github.com/creasty/defaults"
+)
+
+import (
"github.com/apache/dubbo-go/cluster/directory"
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
@@ -43,11 +47,11 @@
Check *bool `yaml:"check" json:"check,omitempty" property:"check"`
Url string `yaml:"url" json:"url,omitempty" property:"url"`
Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"`
- Protocol string `yaml:"protocol" json:"protocol,omitempty" property:"protocol"`
+ Protocol string `default:"dubbo" yaml:"protocol" json:"protocol,omitempty" property:"protocol"`
Registry string `yaml:"registry" json:"registry,omitempty" property:"registry"`
Cluster string `yaml:"cluster" json:"cluster,omitempty" property:"cluster"`
Loadbalance string `yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"`
- Retries int64 `yaml:"retries" json:"retries,omitempty" property:"retries"`
+ Retries string `yaml:"retries" json:"retries,omitempty" property:"retries"`
Group string `yaml:"group" json:"group,omitempty" property:"group"`
Version string `yaml:"version" json:"version,omitempty" property:"version"`
Methods []*MethodConfig `yaml:"methods" json:"methods,omitempty" property:"methods"`
@@ -68,6 +72,7 @@
}
func (refconfig *ReferenceConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
+
type rf ReferenceConfig
raw := rf{} // Put your defaults here
if err := unmarshal(&raw); err != nil {
@@ -75,6 +80,10 @@
}
*refconfig = ReferenceConfig(raw)
+ if err := defaults.Set(refconfig); err != nil {
+ return err
+ }
+
return nil
}
@@ -97,8 +106,8 @@
serviceUrl.Path = "/" + refconfig.id
}
// merge url need to do
- newUrl := common.MergeUrl(serviceUrl, url)
- refconfig.urls = append(refconfig.urls, &newUrl)
+ newUrl := common.MergeUrl(&serviceUrl, url)
+ refconfig.urls = append(refconfig.urls, newUrl)
}
}
@@ -154,7 +163,7 @@
urlMap.Set(constant.TIMESTAMP_KEY, strconv.FormatInt(time.Now().Unix(), 10))
urlMap.Set(constant.CLUSTER_KEY, refconfig.Cluster)
urlMap.Set(constant.LOADBALANCE_KEY, refconfig.Loadbalance)
- urlMap.Set(constant.RETRIES_KEY, strconv.FormatInt(refconfig.Retries, 10))
+ urlMap.Set(constant.RETRIES_KEY, refconfig.Retries)
urlMap.Set(constant.GROUP_KEY, refconfig.Group)
urlMap.Set(constant.VERSION_KEY, refconfig.Version)
urlMap.Set(constant.GENERIC_KEY, strconv.FormatBool(refconfig.Generic))
@@ -180,7 +189,7 @@
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))
+ urlMap.Set("methods."+v.Name+"."+constant.RETRIES_KEY, v.Retries)
}
return urlMap
diff --git a/config/reference_config_test.go b/config/reference_config_test.go
index 774fece..a81dbf0 100644
--- a/config/reference_config_test.go
+++ b/config/reference_config_test.go
@@ -20,8 +20,6 @@
import (
"sync"
"testing"
-
- "github.com/apache/dubbo-go/common/constant"
)
import (
@@ -31,13 +29,14 @@
import (
"github.com/apache/dubbo-go/cluster/cluster_impl"
"github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/protocol"
)
var regProtocol protocol.Protocol
-func doInit() {
+func doInitConsumer() {
consumerConfig = &ConsumerConfig{
ApplicationConfig: &ApplicationConfig{
Organization: "dubbo_org",
@@ -91,18 +90,63 @@
Protocol: "mock",
Cluster: "failover",
Loadbalance: "random",
- Retries: 3,
+ Retries: "3",
Group: "huadong_idc",
Version: "1.0.0",
Methods: []*MethodConfig{
{
Name: "GetUser",
- Retries: 2,
+ Retries: "2",
Loadbalance: "random",
},
{
Name: "GetUser1",
- Retries: 2,
+ Retries: "2",
+ Loadbalance: "random",
+ },
+ },
+ },
+ },
+ }
+}
+
+func doInitConsumerWithSingleRegistry() {
+ consumerConfig = &ConsumerConfig{
+ ApplicationConfig: &ApplicationConfig{
+ Organization: "dubbo_org",
+ Name: "dubbo",
+ Module: "module",
+ Version: "2.6.0",
+ Owner: "dubbo",
+ Environment: "test"},
+ Registry: &RegistryConfig{
+ Address: "mock://27.0.0.1:2181",
+ Username: "user1",
+ Password: "pwd1",
+ },
+ Registries: map[string]*RegistryConfig{},
+ References: map[string]*ReferenceConfig{
+ "MockService": {
+ Params: map[string]string{
+ "serviceid": "soa.mock",
+ "forks": "5",
+ },
+ InterfaceName: "com.MockService",
+ Protocol: "mock",
+ Cluster: "failover",
+ Loadbalance: "random",
+ Retries: "3",
+ Group: "huadong_idc",
+ Version: "1.0.0",
+ Methods: []*MethodConfig{
+ {
+ Name: "GetUser",
+ Retries: "2",
+ Loadbalance: "random",
+ },
+ {
+ Name: "GetUser1",
+ Retries: "2",
Loadbalance: "random",
},
},
@@ -112,7 +156,7 @@
}
func Test_ReferMultireg(t *testing.T) {
- doInit()
+ doInitConsumer()
extension.SetProtocol("registry", GetProtocol)
extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster)
@@ -125,7 +169,7 @@
}
func Test_Refer(t *testing.T) {
- doInit()
+ doInitConsumer()
extension.SetProtocol("registry", GetProtocol)
extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster)
@@ -138,7 +182,7 @@
consumerConfig = nil
}
func Test_ReferP2P(t *testing.T) {
- doInit()
+ doInitConsumer()
extension.SetProtocol("dubbo", GetProtocol)
m := consumerConfig.References["MockService"]
m.Url = "dubbo://127.0.0.1:20000"
@@ -152,7 +196,7 @@
}
func Test_ReferMultiP2P(t *testing.T) {
- doInit()
+ doInitConsumer()
extension.SetProtocol("dubbo", GetProtocol)
m := consumerConfig.References["MockService"]
m.Url = "dubbo://127.0.0.1:20000;dubbo://127.0.0.2:20000"
@@ -166,7 +210,7 @@
}
func Test_ReferMultiP2PWithReg(t *testing.T) {
- doInit()
+ doInitConsumer()
extension.SetProtocol("dubbo", GetProtocol)
extension.SetProtocol("registry", GetProtocol)
m := consumerConfig.References["MockService"]
@@ -181,7 +225,7 @@
}
func Test_Implement(t *testing.T) {
- doInit()
+ doInitConsumer()
extension.SetProtocol("registry", GetProtocol)
extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster)
for _, reference := range consumerConfig.References {
@@ -194,7 +238,7 @@
}
func Test_Forking(t *testing.T) {
- doInit()
+ doInitConsumer()
extension.SetProtocol("dubbo", GetProtocol)
extension.SetProtocol("registry", GetProtocol)
m := consumerConfig.References["MockService"]
diff --git a/config/registry_config.go b/config/registry_config.go
index 0abdab8..9ffa41e 100644
--- a/config/registry_config.go
+++ b/config/registry_config.go
@@ -25,6 +25,10 @@
)
import (
+ "github.com/creasty/defaults"
+)
+
+import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/logger"
@@ -42,8 +46,19 @@
Params map[string]string `yaml:"params" json:"params,omitempty" property:"params"`
}
+func (c *RegistryConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ if err := defaults.Set(c); err != nil {
+ return err
+ }
+ type plain RegistryConfig
+ if err := unmarshal((*plain)(c)); err != nil {
+ return err
+ }
+ return nil
+}
+
func (*RegistryConfig) Prefix() string {
- return constant.RegistryConfigPrefix
+ return constant.RegistryConfigPrefix + "|" + constant.SingleRegistryConfigPrefix
}
func loadRegistries(targetRegistries string, registries map[string]*RegistryConfig, roleType common.RoleType) []*common.URL {
@@ -73,27 +88,22 @@
url common.URL
err error
)
- if addresses := strings.Split(registryConf.Address, ","); len(addresses) > 1 {
- url, err = common.NewURL(
- context.Background(),
- constant.REGISTRY_PROTOCOL+"://"+addresses[0],
- common.WithParams(registryConf.getUrlMap(roleType)),
- common.WithUsername(registryConf.Username),
- common.WithPassword(registryConf.Password),
- common.WithLocation(registryConf.Address),
- )
- } else {
- url, err = common.NewURL(
- context.Background(),
- constant.REGISTRY_PROTOCOL+"://"+registryConf.Address,
- common.WithParams(registryConf.getUrlMap(roleType)),
- common.WithUsername(registryConf.Username),
- common.WithPassword(registryConf.Password),
- )
- }
+
+ addresses := strings.Split(registryConf.Address, ",")
+ address := addresses[0]
+ address = traslateRegistryConf(address, registryConf)
+ url, err = common.NewURL(
+ context.Background(),
+ constant.REGISTRY_PROTOCOL+"://"+address,
+ common.WithParams(registryConf.getUrlMap(roleType)),
+ common.WithUsername(registryConf.Username),
+ common.WithPassword(registryConf.Password),
+ common.WithLocation(registryConf.Address),
+ )
if err != nil {
- logger.Errorf("The registry id:%s url is invalid ,and will skip the registry, error: %#v", k, err)
+ logger.Errorf("The registry id:%s url is invalid , error: %#v", k, err)
+ panic(err)
} else {
urls = append(urls, &url)
}
@@ -115,3 +125,17 @@
}
return urlMap
}
+
+func traslateRegistryConf(address string, registryConf *RegistryConfig) string {
+ if strings.Contains(address, "://") {
+ translatedUrl, err := url.Parse(address)
+ if err != nil {
+ logger.Errorf("The registry url is invalid , error: %#v", err)
+ panic(err)
+ }
+ address = translatedUrl.Host
+ registryConf.Protocol = translatedUrl.Scheme
+ registryConf.Address = strings.Replace(registryConf.Address, translatedUrl.Scheme+"://", "", -1)
+ }
+ return address
+}
diff --git a/config/registry_config_test.go b/config/registry_config_test.go
index f600a21..45d38b2 100644
--- a/config/registry_config_test.go
+++ b/config/registry_config_test.go
@@ -20,9 +20,13 @@
"fmt"
"testing"
)
+
+import (
+ "github.com/stretchr/testify/assert"
+)
+
import (
"github.com/apache/dubbo-go/common"
- "github.com/stretchr/testify/assert"
)
func Test_loadRegistries(t *testing.T) {
diff --git a/config/service_config.go b/config/service_config.go
index 8b4a7d1..ce15c61 100644
--- a/config/service_config.go
+++ b/config/service_config.go
@@ -28,6 +28,7 @@
)
import (
+ "github.com/creasty/defaults"
perrors "github.com/pkg/errors"
"go.uber.org/atomic"
)
@@ -45,7 +46,7 @@
context context.Context
id string
Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"`
- Protocol string `required:"true" yaml:"protocol" json:"protocol,omitempty" property:"protocol"` //multi protocol support, split by ','
+ Protocol string `default:"dubbo" required:"true" yaml:"protocol" json:"protocol,omitempty" property:"protocol"` //multi protocol support, split by ','
InterfaceName string `required:"true" yaml:"interface" json:"interface,omitempty" property:"interface"`
Registry string `yaml:"registry" json:"registry,omitempty" property:"registry"`
Cluster string `default:"failover" yaml:"cluster" json:"cluster,omitempty" property:"cluster"`
@@ -54,12 +55,12 @@
Version string `yaml:"version" json:"version,omitempty" property:"version" `
Methods []*MethodConfig `yaml:"methods" json:"methods,omitempty" property:"methods"`
Warmup string `yaml:"warmup" json:"warmup,omitempty" property:"warmup"`
- Retries int64 `yaml:"retries" json:"retries,omitempty" property:"retries"`
+ Retries string `yaml:"retries" json:"retries,omitempty" property:"retries"`
Params map[string]string `yaml:"params" json:"params,omitempty" property:"params"`
+ Token string `yaml:"token" json:"token,omitempty" property:"token"`
unexported *atomic.Bool
exported *atomic.Bool
rpcService common.RPCService
- exporters []protocol.Exporter
cacheProtocol protocol.Protocol
cacheMutex sync.Mutex
}
@@ -68,6 +69,17 @@
return constant.ServiceConfigPrefix + c.InterfaceName + "."
}
+func (c *ServiceConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ if err := defaults.Set(c); err != nil {
+ return err
+ }
+ type plain ServiceConfig
+ if err := unmarshal((*plain)(c)); err != nil {
+ return err
+ }
+ return nil
+}
+
// The only way to get a new ServiceConfig
func NewServiceConfig(id string, context context.Context) *ServiceConfig {
@@ -111,7 +123,9 @@
common.WithPort(proto.Port),
common.WithParams(urlMap),
common.WithParamsValue(constant.BEAN_NAME_KEY, srvconfig.id),
- common.WithMethods(strings.Split(methods, ",")))
+ common.WithMethods(strings.Split(methods, ",")),
+ common.WithToken(srvconfig.Token),
+ )
if len(regUrls) > 0 {
for _, regUrl := range regUrls {
@@ -129,7 +143,6 @@
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)
@@ -137,7 +150,6 @@
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)
}
}
@@ -160,7 +172,7 @@
urlMap.Set(constant.CLUSTER_KEY, srvconfig.Cluster)
urlMap.Set(constant.LOADBALANCE_KEY, srvconfig.Loadbalance)
urlMap.Set(constant.WARMUP_KEY, srvconfig.Warmup)
- urlMap.Set(constant.RETRIES_KEY, strconv.FormatInt(srvconfig.Retries, 10))
+ urlMap.Set(constant.RETRIES_KEY, srvconfig.Retries)
urlMap.Set(constant.GROUP_KEY, srvconfig.Group)
urlMap.Set(constant.VERSION_KEY, srvconfig.Version)
urlMap.Set(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))
@@ -178,7 +190,7 @@
for _, v := range srvconfig.Methods {
urlMap.Set("methods."+v.Name+"."+constant.LOADBALANCE_KEY, v.Loadbalance)
- urlMap.Set("methods."+v.Name+"."+constant.RETRIES_KEY, strconv.FormatInt(v.Retries, 10))
+ urlMap.Set("methods."+v.Name+"."+constant.RETRIES_KEY, v.Retries)
urlMap.Set("methods."+v.Name+"."+constant.WEIGHT_KEY, strconv.FormatInt(v.Weight, 10))
}
diff --git a/config/service_config_test.go b/config/service_config_test.go
index e111c8d..8ae6753 100644
--- a/config/service_config_test.go
+++ b/config/service_config_test.go
@@ -22,14 +22,10 @@
)
import (
- "github.com/stretchr/testify/assert"
-)
-
-import (
"github.com/apache/dubbo-go/common/extension"
)
-func doinit() {
+func doInitProvider() {
providerConfig = &ProviderConfig{
ApplicationConfig: &ApplicationConfig{
Organization: "dubbo_org",
@@ -79,19 +75,69 @@
Registry: "shanghai_reg1,shanghai_reg2,hangzhou_reg1,hangzhou_reg2",
Cluster: "failover",
Loadbalance: "random",
- Retries: 3,
+ Retries: "3",
Group: "huadong_idc",
Version: "1.0.0",
Methods: []*MethodConfig{
{
Name: "GetUser",
- Retries: 2,
+ Retries: "2",
Loadbalance: "random",
Weight: 200,
},
{
Name: "GetUser1",
- Retries: 2,
+ Retries: "2",
+ Loadbalance: "random",
+ Weight: 200,
+ },
+ },
+ },
+ },
+ Protocols: map[string]*ProtocolConfig{
+ "mock": {
+ Name: "mock",
+ Ip: "127.0.0.1",
+ Port: "20000",
+ },
+ },
+ }
+}
+
+func doInitProviderWithSingleRegistry() {
+ providerConfig = &ProviderConfig{
+ ApplicationConfig: &ApplicationConfig{
+ Organization: "dubbo_org",
+ Name: "dubbo",
+ Module: "module",
+ Version: "2.6.0",
+ Owner: "dubbo",
+ Environment: "test"},
+ Registry: &RegistryConfig{
+ Address: "mock://127.0.0.1:2181",
+ Username: "user1",
+ Password: "pwd1",
+ },
+ Registries: map[string]*RegistryConfig{},
+ Services: map[string]*ServiceConfig{
+ "MockService": {
+ InterfaceName: "com.MockService",
+ Protocol: "mock",
+ 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,
},
@@ -109,16 +155,13 @@
}
func Test_Export(t *testing.T) {
- doinit()
+ doInitProvider()
extension.SetProtocol("registry", GetProtocol)
for i := range providerConfig.Services {
service := providerConfig.Services[i]
service.Implement(&MockService{})
service.Export()
- assert.Condition(t, func() bool {
- return len(service.exporters) > 0
- })
}
providerConfig = nil
}
diff --git a/config/testdata/consumer_config.yml b/config/testdata/consumer_config.yml
index 372873a..9fd50bb 100644
--- a/config/testdata/consumer_config.yml
+++ b/config/testdata/consumer_config.yml
@@ -8,7 +8,7 @@
connect_timeout : "100ms"
check: true
# application config
-application_config:
+application:
organization : "ikurento.com"
name : "BDTService"
module : "dubbogo user-info client"
@@ -43,7 +43,7 @@
cluster: "failover"
methods :
- name: "GetUser"
- retries: 3
+ retries: "3"
params:
"serviceid":
"soa.com.ikurento.user.UserProvider"
diff --git a/config/testdata/consumer_config_with_configcenter.yml b/config/testdata/consumer_config_with_configcenter.yml
index c6505e4..0550cc8 100644
--- a/config/testdata/consumer_config_with_configcenter.yml
+++ b/config/testdata/consumer_config_with_configcenter.yml
@@ -1,5 +1,7 @@
# dubbo client yaml configure file
+application:
+ name: "BDTService"
config_center:
protocol: "mock"
address: "127.0.0.1"
@@ -13,7 +15,7 @@
cluster: "failover"
methods :
- name: "GetUser"
- retries: 3
+ retries: "3"
protocol_conf:
dubbo:
diff --git a/examples/general/dubbo/go-client/profiles/release/client.yml b/config/testdata/consumer_config_withoutProtocol.yml
similarity index 62%
rename from examples/general/dubbo/go-client/profiles/release/client.yml
rename to config/testdata/consumer_config_withoutProtocol.yml
index b4d897f..5e57c7d 100644
--- a/examples/general/dubbo/go-client/profiles/release/client.yml
+++ b/config/testdata/consumer_config_withoutProtocol.yml
@@ -1,22 +1,23 @@
# dubbo client yaml configure file
+filter: ""
-check: true
# client
-request_timeout : "3s"
+request_timeout : "100ms"
# connect timeout
-connect_timeout : "3s"
-
+connect_timeout : "100ms"
+check: true
# application config
-application_config:
+application:
organization : "ikurento.com"
name : "BDTService"
module : "dubbogo user-info client"
version : "0.0.1"
owner : "ZX"
- environment : "release"
+ environment : "dev"
registries :
+
"hangzhouzk":
protocol: "zookeeper"
timeout : "3s"
@@ -32,33 +33,20 @@
references:
"UserProvider":
- # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
- registry: "hangzhouzk"
- protocol : "dubbo"
+ registry: "hangzhouzk,shanghaizk"
+ filter: ""
+ version: "1.0"
+ group: "as"
interface : "com.ikurento.user.UserProvider"
+ url: "dubbo://127.0.0.1:20000/UserProvider"
cluster: "failover"
methods :
- name: "GetUser"
retries: 3
- "UserProvider1":
- registry: "hangzhouzk"
- protocol: "dubbo"
- version: "2.0"
- interface: "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 3
- "UserProvider2":
- registry: "hangzhouzk"
- protocol: "dubbo"
- version: "2.0"
- group: "as"
- interface: "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 3
+ params:
+ "serviceid":
+ "soa.com.ikurento.user.UserProvider"
+ "forks": 5
protocol_conf:
dubbo:
@@ -68,6 +56,12 @@
session_timeout: "20s"
pool_size: 64
pool_ttl: 600
+ # gr_pool_size is recommended to be set to [cpu core number] * 100
+ gr_pool_size: 1200
+ # queue_len is recommended to be set to 64 or 128
+ queue_len: 64
+ # queue_number is recommended to be set to gr_pool_size / 20
+ queue_number: 60
getty_session_param:
compress_encoding: false
tcp_no_delay: true
@@ -79,5 +73,6 @@
tcp_read_timeout: "1s"
tcp_write_timeout: "5s"
wait_timeout: "1s"
- max_msg_len: 10240
+ max_msg_len: 1024
session_name: "client"
+
diff --git a/config/testdata/provider_config.yml b/config/testdata/provider_config.yml
index e135860..5cbefe0 100644
--- a/config/testdata/provider_config.yml
+++ b/config/testdata/provider_config.yml
@@ -2,7 +2,7 @@
filter: ""
# application config
-application_config:
+application:
organization : "ikurento.com"
name : "BDTService"
module : "dubbogo user-info server"
diff --git a/config/testdata/provider_config_withoutProtocol.yml b/config/testdata/provider_config_withoutProtocol.yml
new file mode 100644
index 0000000..2f65868
--- /dev/null
+++ b/config/testdata/provider_config_withoutProtocol.yml
@@ -0,0 +1,76 @@
+# dubbo server yaml configure file
+
+filter: ""
+# application config
+application:
+ organization : "ikurento.com"
+ name : "BDTService"
+ module : "dubbogo user-info server"
+ version : "0.0.1"
+ owner : "ZX"
+ environment : "dev"
+
+registries :
+ "hangzhouzk":
+ protocol: "zookeeper"
+ timeout : "3s"
+ address: "127.0.0.1:2181"
+ username: ""
+ password: ""
+ "shanghaizk":
+ protocol: "zookeeper"
+ timeout : "3s"
+ address: "127.0.0.1:2182"
+ username: ""
+ password: ""
+
+
+services:
+ "UserProvider":
+ registry: "hangzhouzk,shanghaizk"
+ filter: ""
+ # equivalent to interface of dubbo.xml
+ interface : "com.ikurento.user.UserProvider"
+ loadbalance: "random"
+ version: "1.0"
+ group: "as"
+ warmup: "100"
+ cluster: "failover"
+ methods:
+ - name: "GetUser"
+ retries: 1
+ loadbalance: "random"
+
+protocols:
+ "dubbo":
+ name: "dubbo"
+ # while using dubbo protocol, ip cannot is 127.0.0.1, because client of java-dubbo will get 'connection refuse'
+ ip : "127.0.0.1"
+ port : 20000
+ #- name: "jsonrpc"
+ # ip: "127.0.0.1"
+ # port: 20001
+
+protocol_conf:
+ dubbo:
+ session_number: 700
+ session_timeout: "20s"
+ # gr_pool_size is recommended to be set to [cpu core number] * 10
+ gr_pool_size: 120
+ # queue_len is recommended to be set to 64 or 128
+ queue_len: 64
+ # queue_number is recommended to be set to gr_pool_size / 20
+ queue_number: 6
+ getty_session_param:
+ compress_encoding: false
+ tcp_no_delay: true
+ tcp_keep_alive: true
+ keep_alive_period: "120s"
+ tcp_r_buf_size: 262144
+ tcp_w_buf_size: 65536
+ pkg_wq_size: 512
+ tcp_read_timeout: "1s"
+ tcp_write_timeout: "5s"
+ wait_timeout: "1s"
+ max_msg_len: 1024
+ session_name: "server"
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go b/config_center/configuration_listener.go
similarity index 64%
copy from examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go
copy to config_center/configuration_listener.go
index c613858..1419bcd 100644
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go
+++ b/config_center/configuration_listener.go
@@ -15,8 +15,26 @@
* limitations under the License.
*/
-package main
+package config_center
-var (
- Version = "2.6.0"
+import (
+ "fmt"
)
+
+import (
+ "github.com/apache/dubbo-go/remoting"
+)
+
+type ConfigurationListener interface {
+ Process(*ConfigChangeEvent)
+}
+
+type ConfigChangeEvent struct {
+ Key string
+ Value interface{}
+ ConfigType remoting.EventType
+}
+
+func (c ConfigChangeEvent) String() string {
+ return fmt.Sprintf("ConfigChangeEvent{key = %v , value = %v , changeType = %v}", c.Key, c.Value, c.ConfigType)
+}
diff --git a/config_center/configuration_parser.go b/config_center/configuration_parser.go
deleted file mode 100644
index ab02789..0000000
--- a/config_center/configuration_parser.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package config_center
-
-import (
- "github.com/magiconair/properties"
-)
-import (
- "github.com/apache/dubbo-go/common/logger"
-)
-
-type ConfigurationParser interface {
- Parse(string) (map[string]string, error)
-}
-
-//for support properties file in config center
-type DefaultConfigurationParser struct{}
-
-func (parser *DefaultConfigurationParser) Parse(content string) (map[string]string, error) {
- properties, err := properties.LoadString(content)
- if err != nil {
- logger.Errorf("Parse the content {%v} in DefaultConfigurationParser error ,error message is {%v}", content, err)
- return nil, err
- }
- return properties.Map(), nil
-}
diff --git a/config_center/configuration_parser_test.go b/config_center/configuration_parser_test.go
deleted file mode 100644
index 3c84fd7..0000000
--- a/config_center/configuration_parser_test.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package config_center
-
-import (
- "testing"
-)
-import (
- "github.com/stretchr/testify/assert"
-)
-
-func TestDefaultConfigurationParser_Parser(t *testing.T) {
- parser := &DefaultConfigurationParser{}
- m, err := parser.Parse("dubbo.registry.address=172.0.0.1\ndubbo.registry.name=test")
- assert.NoError(t, err)
- assert.Equal(t, 2, len(m))
- assert.Equal(t, "172.0.0.1", m["dubbo.registry.address"])
-}
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go b/config_center/configurator.go
similarity index 83%
copy from examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go
copy to config_center/configurator.go
index c613858..3ba293e 100644
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go
+++ b/config_center/configurator.go
@@ -15,8 +15,13 @@
* limitations under the License.
*/
-package main
+package config_center
-var (
- Version = "2.6.0"
+import (
+ "github.com/apache/dubbo-go/common"
)
+
+type Configurator interface {
+ GetUrl() *common.URL
+ Configure(url *common.URL)
+}
diff --git a/config_center/configurator/mock.go b/config_center/configurator/mock.go
new file mode 100644
index 0000000..1f03d10
--- /dev/null
+++ b/config_center/configurator/mock.go
@@ -0,0 +1,41 @@
+/*
+ * 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 configurator
+
+import (
+ "github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/common/constant"
+ "github.com/apache/dubbo-go/config_center"
+)
+
+func NewMockConfigurator(url *common.URL) config_center.Configurator {
+ return &mockConfigurator{configuratorUrl: url}
+}
+
+type mockConfigurator struct {
+ configuratorUrl *common.URL
+}
+
+func (c *mockConfigurator) GetUrl() *common.URL {
+ return c.configuratorUrl
+}
+
+func (c *mockConfigurator) Configure(url *common.URL) {
+ if cluster := c.GetUrl().GetParam(constant.CLUSTER_KEY, ""); cluster != "" {
+ url.SetParam(constant.CLUSTER_KEY, cluster)
+ }
+}
diff --git a/config_center/configurator/override.go b/config_center/configurator/override.go
new file mode 100644
index 0000000..660c6ee
--- /dev/null
+++ b/config_center/configurator/override.go
@@ -0,0 +1,131 @@
+/*
+ * 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 configurator
+
+import (
+ "strings"
+)
+
+import (
+ "github.com/dubbogo/gost/container"
+)
+
+import (
+ "github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/common/constant"
+ "github.com/apache/dubbo-go/common/extension"
+ "github.com/apache/dubbo-go/common/utils"
+ "github.com/apache/dubbo-go/config_center"
+)
+
+func init() {
+ extension.SetDefaultConfigurator(newConfigurator)
+}
+func newConfigurator(url *common.URL) config_center.Configurator {
+ return &overrideConfigurator{configuratorUrl: url}
+}
+
+type overrideConfigurator struct {
+ configuratorUrl *common.URL
+}
+
+func (c *overrideConfigurator) GetUrl() *common.URL {
+ return c.configuratorUrl
+}
+
+func (c *overrideConfigurator) Configure(url *common.URL) {
+ //remove configuratorUrl some param that can not be configured
+ if c.configuratorUrl.GetParam(constant.ENABLED_KEY, "true") == "false" || len(c.configuratorUrl.Location) == 0 {
+ return
+ }
+
+ //branch for version 2.7.x
+ apiVersion := c.configuratorUrl.GetParam(constant.CONFIG_VERSION_KEY, "")
+ if len(apiVersion) != 0 {
+ currentSide := url.GetParam(constant.SIDE_KEY, "")
+ configuratorSide := c.configuratorUrl.GetParam(constant.SIDE_KEY, "")
+ if currentSide == configuratorSide && common.DubboRole[common.CONSUMER] == currentSide && c.configuratorUrl.Port == "0" {
+ localIP, _ := utils.GetLocalIP()
+ c.configureIfMatch(localIP, url)
+ } else if currentSide == configuratorSide && common.DubboRole[common.PROVIDER] == currentSide && c.configuratorUrl.Port == url.Port {
+ c.configureIfMatch(url.Ip, url)
+ }
+ } else {
+ //branch for version 2.6.x and less
+ c.configureDeprecated(url)
+ }
+}
+
+//translate from java, compatible rules in java
+func (c *overrideConfigurator) configureIfMatch(host string, url *common.URL) {
+ if constant.ANYHOST_VALUE == c.configuratorUrl.Ip || host == c.configuratorUrl.Ip {
+ providers := c.configuratorUrl.GetParam(constant.OVERRIDE_PROVIDERS_KEY, "")
+ if len(providers) == 0 || strings.Index(providers, url.Location) >= 0 || strings.Index(providers, constant.ANYHOST_VALUE) >= 0 {
+ configApp := c.configuratorUrl.GetParam(constant.APPLICATION_KEY, c.configuratorUrl.Username)
+ currentApp := url.GetParam(constant.APPLICATION_KEY, url.Username)
+ if len(configApp) == 0 || constant.ANY_VALUE == configApp || configApp == currentApp {
+ conditionKeys := container.NewSet()
+ conditionKeys.Add(constant.CATEGORY_KEY)
+ conditionKeys.Add(constant.CHECK_KEY)
+ conditionKeys.Add(constant.ENABLED_KEY)
+ conditionKeys.Add(constant.GROUP_KEY)
+ conditionKeys.Add(constant.VERSION_KEY)
+ conditionKeys.Add(constant.APPLICATION_KEY)
+ conditionKeys.Add(constant.SIDE_KEY)
+ conditionKeys.Add(constant.CONFIG_VERSION_KEY)
+ conditionKeys.Add(constant.COMPATIBLE_CONFIG_KEY)
+ returnUrl := false
+ c.configuratorUrl.RangeParams(func(k, v string) bool {
+ value := c.configuratorUrl.GetParam(k, "")
+ if strings.HasPrefix(k, "~") || k == constant.APPLICATION_KEY || k == constant.SIDE_KEY {
+ conditionKeys.Add(k)
+ if len(value) != 0 && value != constant.ANY_VALUE && value != url.GetParam(strings.TrimPrefix(k, "~"), "") {
+ returnUrl = true
+ return false
+ }
+ }
+ return true
+ })
+ if returnUrl {
+ return
+ }
+ configUrl := c.configuratorUrl.Clone()
+ configUrl.RemoveParams(conditionKeys)
+ url.SetParams(configUrl.GetParams())
+ }
+ }
+ }
+}
+
+func (c *overrideConfigurator) configureDeprecated(url *common.URL) {
+ // If override url has port, means it is a provider address. We want to control a specific provider with this override url, it may take effect on the specific provider instance or on consumers holding this provider instance.
+ if c.configuratorUrl.Port != "0" {
+ if url.Port == c.configuratorUrl.Port {
+ c.configureIfMatch(url.Ip, url)
+ }
+ } else {
+ // override url don't have a port, means the ip override url specify is a consumer address or 0.0.0.0
+ // 1.If it is a consumer ip address, the intention is to control a specific consumer instance, it must takes effect at the consumer side, any provider received this override url should ignore;
+ // 2.If the ip is 0.0.0.0, this override url can be used on consumer, and also can be used on provider
+ if url.GetParam(constant.SIDE_KEY, "") == common.DubboRole[common.CONSUMER] {
+ localIP, _ := utils.GetLocalIP()
+ c.configureIfMatch(localIP, url)
+ } else {
+ c.configureIfMatch(constant.ANYHOST_VALUE, url)
+ }
+ }
+}
diff --git a/config_center/configurator/override_test.go b/config_center/configurator/override_test.go
new file mode 100644
index 0000000..a585f42
--- /dev/null
+++ b/config_center/configurator/override_test.go
@@ -0,0 +1,77 @@
+/*
+ * 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 configurator
+
+import (
+ "context"
+ "testing"
+)
+
+import (
+ "github.com/stretchr/testify/assert"
+)
+
+import (
+ "github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/common/constant"
+ "github.com/apache/dubbo-go/common/extension"
+)
+
+func Test_configureVerison2p6(t *testing.T) {
+ url, err := common.NewURL(context.Background(), "override://0.0.0.0:0/com.xxx.mock.userProvider?group=1&version=1&cluster=failfast&application=BDTService")
+ assert.NoError(t, err)
+ configurator := extension.GetConfigurator("default", &url)
+ assert.Equal(t, "override", configurator.GetUrl().Protocol)
+
+ providerUrl, err := common.NewURL(context.Background(), "jsonrpc://127.0.0.1:20001/com.ikurento.user.UserProvider?anyhost=true&app.version=0.0.1&application=BDTService&category=providers&cluster=failover&dubbo=dubbo-provider-golang-2.6.0&environment=dev&group=&interface=com.ikurento.user.UserProvider&ip=10.32.20.124&loadbalance=random&methods.GetUser.loadbalance=random&methods.GetUser.retries=1&methods.GetUser.weight=0&module=dubbogo+user-info+server&name=BDTService&organization=ikurento.com&owner=ZX&pid=64225&retries=0&service.filter=echo&side=provider×tamp=1562076628&version=&warmup=100")
+ configurator.Configure(&providerUrl)
+ assert.Equal(t, "failfast", providerUrl.GetParam(constant.CLUSTER_KEY, ""))
+
+}
+func Test_configureVerisonOverrideAddr(t *testing.T) {
+ url, err := common.NewURL(context.Background(), "override://0.0.0.0:0/com.xxx.mock.userProvider?group=1&version=1&cluster=failfast&application=BDTService&providerAddresses=127.0.0.2:20001|127.0.0.3:20001")
+ assert.NoError(t, err)
+ configurator := extension.GetConfigurator("default", &url)
+ assert.Equal(t, "override", configurator.GetUrl().Protocol)
+
+ providerUrl, err := common.NewURL(context.Background(), "jsonrpc://127.0.0.1:20001/com.ikurento.user.UserProvider?anyhost=true&app.version=0.0.1&application=BDTService&category=providers&cluster=failover&dubbo=dubbo-provider-golang-2.6.0&environment=dev&group=&interface=com.ikurento.user.UserProvider&ip=10.32.20.124&loadbalance=random&methods.GetUser.loadbalance=random&methods.GetUser.retries=1&methods.GetUser.weight=0&module=dubbogo+user-info+server&name=BDTService&organization=ikurento.com&owner=ZX&pid=64225&retries=0&service.filter=echo&side=provider×tamp=1562076628&version=&warmup=100")
+ configurator.Configure(&providerUrl)
+ assert.Equal(t, "failover", providerUrl.GetParam(constant.CLUSTER_KEY, ""))
+
+}
+func Test_configureVerison2p6WithIp(t *testing.T) {
+ url, err := common.NewURL(context.Background(), "override://127.0.0.1:20001/com.xxx.mock.userProvider?group=1&version=1&cluster=failfast&application=BDTService")
+ assert.NoError(t, err)
+ configurator := extension.GetConfigurator("default", &url)
+ assert.Equal(t, "override", configurator.GetUrl().Protocol)
+
+ providerUrl, err := common.NewURL(context.Background(), "jsonrpc://127.0.0.1:20001/com.ikurento.user.UserProvider?anyhost=true&app.version=0.0.1&application=BDTService&category=providers&cluster=failover&dubbo=dubbo-provider-golang-2.6.0&environment=dev&group=&interface=com.ikurento.user.UserProvider&ip=10.32.20.124&loadbalance=random&methods.GetUser.loadbalance=random&methods.GetUser.retries=1&methods.GetUser.weight=0&module=dubbogo+user-info+server&name=BDTService&organization=ikurento.com&owner=ZX&pid=64225&retries=0&service.filter=echo&side=provider×tamp=1562076628&version=&warmup=100")
+ configurator.Configure(&providerUrl)
+ assert.Equal(t, "failfast", providerUrl.GetParam(constant.CLUSTER_KEY, ""))
+
+}
+
+func Test_configureVerison2p7(t *testing.T) {
+ url, err := common.NewURL(context.Background(), "jsonrpc://0.0.0.0:20001/com.xxx.mock.userProvider?group=1&version=1&cluster=failfast&application=BDTService&configVersion=1.0&side=provider")
+ assert.NoError(t, err)
+ configurator := extension.GetConfigurator("default", &url)
+
+ providerUrl, err := common.NewURL(context.Background(), "jsonrpc://127.0.0.1:20001/com.ikurento.user.UserProvider?anyhost=true&app.version=0.0.1&application=BDTService&category=providers&cluster=failover&dubbo=dubbo-provider-golang-2.6.0&environment=dev&group=&interface=com.ikurento.user.UserProvider&ip=10.32.20.124&loadbalance=random&methods.GetUser.loadbalance=random&methods.GetUser.retries=1&methods.GetUser.weight=0&module=dubbogo+user-info+server&name=BDTService&organization=ikurento.com&owner=ZX&pid=64225&retries=0&service.filter=echo&side=provider×tamp=1562076628&version=&warmup=100")
+ configurator.Configure(&providerUrl)
+ assert.Equal(t, "failfast", providerUrl.GetParam(constant.CLUSTER_KEY, ""))
+
+}
diff --git a/config_center/dynamic_configuration.go b/config_center/dynamic_configuration.go
index 3b82950..1028b26 100644
--- a/config_center/dynamic_configuration.go
+++ b/config_center/dynamic_configuration.go
@@ -20,8 +20,9 @@
import (
"time"
)
+
import (
- "github.com/apache/dubbo-go/remoting"
+ "github.com/apache/dubbo-go/config_center/parser"
)
//////////////////////////////////////////
@@ -31,10 +32,10 @@
const DEFAULT_CONFIG_TIMEOUT = "10s"
type DynamicConfiguration interface {
- Parser() ConfigurationParser
- SetParser(ConfigurationParser)
- AddListener(string, remoting.ConfigurationListener, ...Option)
- RemoveListener(string, remoting.ConfigurationListener, ...Option)
+ Parser() parser.ConfigurationParser
+ SetParser(parser.ConfigurationParser)
+ AddListener(string, ConfigurationListener, ...Option)
+ RemoveListener(string, ConfigurationListener, ...Option)
GetConfig(string, ...Option) (string, error)
GetConfigs(string, ...Option) (string, error)
}
diff --git a/config_center/mock_dynamic_config.go b/config_center/mock_dynamic_config.go
index a6c7267..47b5092 100644
--- a/config_center/mock_dynamic_config.go
+++ b/config_center/mock_dynamic_config.go
@@ -20,23 +20,33 @@
import (
"sync"
)
+
+import (
+ "gopkg.in/yaml.v2"
+)
+
import (
"github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/common/constant"
+ "github.com/apache/dubbo-go/config_center/parser"
"github.com/apache/dubbo-go/remoting"
)
-type MockDynamicConfigurationFactory struct{}
+type MockDynamicConfigurationFactory struct {
+ Content string
+}
var (
once sync.Once
- dynamicConfiguration *mockDynamicConfiguration
+ dynamicConfiguration *MockDynamicConfiguration
)
func (f *MockDynamicConfigurationFactory) GetDynamicConfiguration(url *common.URL) (DynamicConfiguration, error) {
var err error
once.Do(func() {
- dynamicConfiguration = &mockDynamicConfiguration{}
- dynamicConfiguration.SetParser(&DefaultConfigurationParser{})
+ dynamicConfiguration = &MockDynamicConfiguration{listener: map[string]ConfigurationListener{}}
+ dynamicConfiguration.SetParser(&parser.DefaultConfigurationParser{})
+
dynamicConfiguration.content = `
dubbo.consumer.request_timeout=5s
dubbo.consumer.connect_timeout=5s
@@ -62,34 +72,81 @@
dubbo.protocols.jsonrpc1.port=20001
`
})
+ if len(f.Content) != 0 {
+ dynamicConfiguration.content = f.Content
+ }
return dynamicConfiguration, err
}
-type mockDynamicConfiguration struct {
- parser ConfigurationParser
- content string
+type MockDynamicConfiguration struct {
+ parser parser.ConfigurationParser
+ content string
+ listener map[string]ConfigurationListener
}
-func (c *mockDynamicConfiguration) AddListener(key string, listener remoting.ConfigurationListener, opions ...Option) {
+func (c *MockDynamicConfiguration) AddListener(key string, listener ConfigurationListener, opions ...Option) {
+ c.listener[key] = listener
}
-func (c *mockDynamicConfiguration) RemoveListener(key string, listener remoting.ConfigurationListener, opions ...Option) {
+func (c *MockDynamicConfiguration) RemoveListener(key string, listener ConfigurationListener, opions ...Option) {
}
-func (c *mockDynamicConfiguration) GetConfig(key string, opts ...Option) (string, error) {
+func (c *MockDynamicConfiguration) GetConfig(key string, opts ...Option) (string, error) {
return c.content, nil
}
//For zookeeper, getConfig and getConfigs have the same meaning.
-func (c *mockDynamicConfiguration) GetConfigs(key string, opts ...Option) (string, error) {
+func (c *MockDynamicConfiguration) GetConfigs(key string, opts ...Option) (string, error) {
return c.GetConfig(key, opts...)
}
-func (c *mockDynamicConfiguration) Parser() ConfigurationParser {
+func (c *MockDynamicConfiguration) Parser() parser.ConfigurationParser {
return c.parser
}
-func (c *mockDynamicConfiguration) SetParser(p ConfigurationParser) {
+func (c *MockDynamicConfiguration) SetParser(p parser.ConfigurationParser) {
c.parser = p
}
+
+func (c *MockDynamicConfiguration) MockServiceConfigEvent() {
+ config := &parser.ConfiguratorConfig{
+ ConfigVersion: "2.7.1",
+ Scope: parser.GeneralType,
+ Key: "org.apache.dubbo-go.mockService",
+ Enabled: true,
+ Configs: []parser.ConfigItem{
+ {Type: parser.GeneralType,
+ Enabled: true,
+ Addresses: []string{"0.0.0.0"},
+ Services: []string{"org.apache.dubbo-go.mockService"},
+ Side: "provider",
+ Parameters: map[string]string{"cluster": "mock1"},
+ },
+ },
+ }
+ value, _ := yaml.Marshal(config)
+ key := "group*org.apache.dubbo-go.mockService:1.0.0" + constant.CONFIGURATORS_SUFFIX
+ c.listener[key].Process(&ConfigChangeEvent{Key: key, Value: string(value), ConfigType: remoting.EventTypeAdd})
+}
+
+func (c *MockDynamicConfiguration) MockApplicationConfigEvent() {
+ config := &parser.ConfiguratorConfig{
+ ConfigVersion: "2.7.1",
+ Scope: parser.ScopeApplication,
+ Key: "org.apache.dubbo-go.mockService",
+ Enabled: true,
+ Configs: []parser.ConfigItem{
+ {Type: parser.ScopeApplication,
+ Enabled: true,
+ Addresses: []string{"0.0.0.0"},
+ Services: []string{"org.apache.dubbo-go.mockService"},
+ Side: "provider",
+ Parameters: map[string]string{"cluster": "mock1"},
+ },
+ },
+ }
+ value, _ := yaml.Marshal(config)
+ key := "test-application" + constant.CONFIGURATORS_SUFFIX
+ c.listener[key].Process(&ConfigChangeEvent{Key: key, Value: string(value), ConfigType: remoting.EventTypeAdd})
+}
diff --git a/config_center/parser/configuration_parser.go b/config_center/parser/configuration_parser.go
new file mode 100644
index 0000000..1ce6594
--- /dev/null
+++ b/config_center/parser/configuration_parser.go
@@ -0,0 +1,251 @@
+/*
+ * 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 parser
+
+import (
+ "context"
+ "strconv"
+ "strings"
+)
+
+import (
+ "github.com/magiconair/properties"
+ perrors "github.com/pkg/errors"
+ "gopkg.in/yaml.v2"
+)
+
+import (
+ "github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/common/constant"
+ "github.com/apache/dubbo-go/common/logger"
+)
+
+const (
+ ScopeApplication = "application"
+ GeneralType = "general"
+)
+
+type ConfigurationParser interface {
+ Parse(string) (map[string]string, error)
+ ParseToUrls(content string) ([]*common.URL, error)
+}
+
+//for support properties file in config center
+type DefaultConfigurationParser struct{}
+
+type ConfiguratorConfig struct {
+ ConfigVersion string `yaml:"configVersion"`
+ Scope string `yaml:"scope"`
+ Key string `yaml:"key"`
+ Enabled bool `yaml:"enabled"`
+ Configs []ConfigItem `yaml:"configs"`
+}
+
+type ConfigItem struct {
+ Type string `yaml:"type"`
+ Enabled bool `yaml:"enabled"`
+ Addresses []string `yaml:"addresses"`
+ ProviderAddresses []string `yaml:"providerAddresses"`
+ Services []string `yaml:"services"`
+ Applications []string `yaml:"applications"`
+ Parameters map[string]string `yaml:"parameters"`
+ Side string `yaml:"side"`
+}
+
+func (parser *DefaultConfigurationParser) Parse(content string) (map[string]string, error) {
+ properties, err := properties.LoadString(content)
+ if err != nil {
+ logger.Errorf("Parse the content {%v} in DefaultConfigurationParser error ,error message is {%v}", content, err)
+ return nil, err
+ }
+ return properties.Map(), nil
+}
+
+func (parser *DefaultConfigurationParser) ParseToUrls(content string) ([]*common.URL, error) {
+ config := ConfiguratorConfig{}
+ if err := yaml.Unmarshal([]byte(content), &config); err != nil {
+ return nil, err
+ }
+ scope := config.Scope
+ items := config.Configs
+ var allUrls []*common.URL
+ if scope == ScopeApplication {
+ for _, v := range items {
+ urls, err := appItemToUrls(v, config)
+ if err != nil {
+ return nil, err
+ }
+ allUrls = append(allUrls, urls...)
+ }
+ } else {
+ for _, v := range items {
+ urls, err := serviceItemToUrls(v, config)
+ if err != nil {
+ return nil, err
+ }
+ allUrls = append(allUrls, urls...)
+ }
+ }
+ return allUrls, nil
+}
+func serviceItemToUrls(item ConfigItem, config ConfiguratorConfig) ([]*common.URL, error) {
+ var addresses = item.Addresses
+ if len(addresses) == 0 {
+ addresses = append(addresses, constant.ANYHOST_VALUE)
+ }
+ var urls []*common.URL
+ for _, v := range addresses {
+ urlStr := constant.OVERRIDE_PROTOCOL + "://" + v + "/"
+ serviceStr, err := getServiceString(config.Key)
+ if err != nil {
+ return nil, perrors.WithStack(err)
+ }
+ urlStr = urlStr + serviceStr
+ paramStr, err := getParamString(item)
+ if err != nil {
+ return nil, perrors.WithStack(err)
+ }
+ urlStr = urlStr + paramStr
+ urlStr = urlStr + getEnabledString(item, config)
+ urlStr = urlStr + "&category="
+ urlStr = urlStr + constant.DYNAMIC_CONFIGURATORS_CATEGORY
+ urlStr = urlStr + "&configVersion="
+ urlStr = urlStr + config.ConfigVersion
+ apps := item.Applications
+ if len(apps) > 0 {
+ for _, v := range apps {
+ newUrlStr := urlStr
+ newUrlStr = newUrlStr + "&application"
+ newUrlStr = newUrlStr + v
+ url, err := common.NewURL(context.Background(), newUrlStr)
+ if err != nil {
+ perrors.WithStack(err)
+ }
+ urls = append(urls, &url)
+ }
+ } else {
+ url, err := common.NewURL(context.Background(), urlStr)
+ if err != nil {
+ perrors.WithStack(err)
+ }
+ urls = append(urls, &url)
+ }
+ }
+ return urls, nil
+}
+func appItemToUrls(item ConfigItem, config ConfiguratorConfig) ([]*common.URL, error) {
+ var addresses = item.Addresses
+ if len(addresses) == 0 {
+ addresses = append(addresses, constant.ANYHOST_VALUE)
+ }
+ var urls []*common.URL
+ for _, v := range addresses {
+ urlStr := constant.OVERRIDE_PROTOCOL + "://" + v + "/"
+ services := item.Services
+ if len(services) == 0 {
+ services = append(services, constant.ANY_VALUE)
+ }
+ for _, vs := range services {
+ serviceStr, err := getServiceString(vs)
+ if err != nil {
+ return nil, perrors.WithStack(err)
+ }
+ urlStr = urlStr + serviceStr
+ paramStr, err := getParamString(item)
+ if err != nil {
+ return nil, perrors.WithStack(err)
+ }
+ urlStr = urlStr + paramStr
+ urlStr = urlStr + "&application="
+ urlStr = urlStr + config.Key
+ urlStr = urlStr + getEnabledString(item, config)
+ urlStr = urlStr + "&category="
+ urlStr = urlStr + constant.APP_DYNAMIC_CONFIGURATORS_CATEGORY
+ urlStr = urlStr + "&configVersion="
+ urlStr = urlStr + config.ConfigVersion
+ url, err := common.NewURL(context.Background(), urlStr)
+ if err != nil {
+ return nil, perrors.WithStack(err)
+ }
+ urls = append(urls, &url)
+ }
+ }
+ return urls, nil
+}
+
+func getServiceString(service string) (string, error) {
+ if len(service) == 0 {
+ return "", perrors.New("service field in configuration is null.")
+ }
+ var serviceStr string
+ i := strings.Index(service, "/")
+ if i > 0 {
+ serviceStr = serviceStr + "group="
+ serviceStr = serviceStr + service[0:i]
+ serviceStr = serviceStr + "&"
+ service = service[i+1:]
+ }
+ j := strings.Index(service, ":")
+ if j > 0 {
+ serviceStr = serviceStr + "version="
+ serviceStr = serviceStr + service[j+1:]
+ serviceStr = serviceStr + "&"
+ service = service[0:j]
+ }
+ serviceStr = service + "?" + serviceStr
+ return serviceStr, nil
+}
+
+func getParamString(item ConfigItem) (string, error) {
+ var retStr string
+ retStr = retStr + "category="
+ retStr = retStr + constant.DYNAMIC_CONFIGURATORS_CATEGORY
+ if len(item.Side) > 0 {
+ retStr = retStr + "&side="
+ retStr = retStr + item.Side
+ }
+ params := item.Parameters
+ if len(params) <= 0 {
+ return "", perrors.New("Invalid configurator rule, please specify at least one parameter " +
+ "you want to change in the rule.")
+ }
+ for k, v := range params {
+ retStr = retStr + "&"
+ retStr = retStr + k
+ retStr = retStr + "="
+ retStr = retStr + v
+ }
+
+ if len(item.ProviderAddresses) >= 0 {
+ retStr = retStr + "&"
+ retStr = retStr + constant.OVERRIDE_PROVIDERS_KEY
+ retStr = retStr + "="
+ retStr = retStr + strings.Join(item.ProviderAddresses, ",")
+ }
+
+ return retStr, nil
+}
+func getEnabledString(item ConfigItem, config ConfiguratorConfig) string {
+ retStr := "&enabled="
+ if len(item.Type) == 0 || item.Type == GeneralType {
+ retStr = retStr + strconv.FormatBool(config.Enabled)
+ } else {
+ retStr = retStr + strconv.FormatBool(item.Enabled)
+ }
+ return retStr
+}
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go b/config_center/parser/configuration_parser_test.go
similarity index 67%
copy from examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go
copy to config_center/parser/configuration_parser_test.go
index c613858..7a59ea9 100644
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go
+++ b/config_center/parser/configuration_parser_test.go
@@ -15,8 +15,20 @@
* limitations under the License.
*/
-package main
+package parser
-var (
- Version = "2.6.0"
+import (
+ "testing"
)
+
+import (
+ "github.com/stretchr/testify/assert"
+)
+
+func TestDefaultConfigurationParser_Parser(t *testing.T) {
+ parser := &DefaultConfigurationParser{}
+ m, err := parser.Parse("dubbo.registry.address=172.0.0.1\ndubbo.registry.name=test")
+ assert.NoError(t, err)
+ assert.Equal(t, 2, len(m))
+ assert.Equal(t, "172.0.0.1", m["dubbo.registry.address"])
+}
diff --git a/config_center/zookeeper/factory.go b/config_center/zookeeper/factory.go
index c1c7e27..611f4b9 100644
--- a/config_center/zookeeper/factory.go
+++ b/config_center/zookeeper/factory.go
@@ -20,10 +20,12 @@
import (
"sync"
)
+
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/config_center"
+ "github.com/apache/dubbo-go/config_center/parser"
)
func init() {
@@ -44,7 +46,7 @@
if err != nil {
return nil, err
}
- dynamicConfiguration.SetParser(&config_center.DefaultConfigurationParser{})
+ dynamicConfiguration.SetParser(&parser.DefaultConfigurationParser{})
return dynamicConfiguration, err
}
diff --git a/config_center/zookeeper/impl.go b/config_center/zookeeper/impl.go
index f2827b2..84e4b54 100644
--- a/config_center/zookeeper/impl.go
+++ b/config_center/zookeeper/impl.go
@@ -22,16 +22,18 @@
"sync"
"time"
)
+
import (
perrors "github.com/pkg/errors"
"github.com/samuel/go-zookeeper/zk"
)
+
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/logger"
"github.com/apache/dubbo-go/config_center"
- "github.com/apache/dubbo-go/remoting"
+ "github.com/apache/dubbo-go/config_center/parser"
"github.com/apache/dubbo-go/remoting/zookeeper"
)
@@ -48,7 +50,7 @@
listenerLock sync.Mutex
listener *zookeeper.ZkEventListener
cacheListener *CacheListener
- parser config_center.ConfigurationParser
+ parser parser.ConfigurationParser
}
func newZookeeperDynamicConfiguration(url *common.URL) (*zookeeperDynamicConfiguration, error) {
@@ -99,11 +101,11 @@
}
-func (c *zookeeperDynamicConfiguration) AddListener(key string, listener remoting.ConfigurationListener, opions ...config_center.Option) {
+func (c *zookeeperDynamicConfiguration) AddListener(key string, listener config_center.ConfigurationListener, opions ...config_center.Option) {
c.cacheListener.AddListener(key, listener)
}
-func (c *zookeeperDynamicConfiguration) RemoveListener(key string, listener remoting.ConfigurationListener, opions ...config_center.Option) {
+func (c *zookeeperDynamicConfiguration) RemoveListener(key string, listener config_center.ConfigurationListener, opions ...config_center.Option) {
c.cacheListener.RemoveListener(key, listener)
}
@@ -143,10 +145,10 @@
return c.GetConfig(key, opts...)
}
-func (c *zookeeperDynamicConfiguration) Parser() config_center.ConfigurationParser {
+func (c *zookeeperDynamicConfiguration) Parser() parser.ConfigurationParser {
return c.parser
}
-func (c *zookeeperDynamicConfiguration) SetParser(p config_center.ConfigurationParser) {
+func (c *zookeeperDynamicConfiguration) SetParser(p parser.ConfigurationParser) {
c.parser = p
}
diff --git a/config_center/zookeeper/impl_test.go b/config_center/zookeeper/impl_test.go
index 26b899e..2f62045 100644
--- a/config_center/zookeeper/impl_test.go
+++ b/config_center/zookeeper/impl_test.go
@@ -31,13 +31,13 @@
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/config_center"
- "github.com/apache/dubbo-go/remoting"
+ "github.com/apache/dubbo-go/config_center/parser"
)
func initZkData(group string, t *testing.T) (*zk.TestCluster, *zookeeperDynamicConfiguration) {
regurl, _ := common.NewURL(context.TODO(), "registry://127.0.0.1:1111")
ts, reg, err := newMockZookeeperDynamicConfiguration(®url)
- reg.SetParser(&config_center.DefaultConfigurationParser{})
+ reg.SetParser(&parser.DefaultConfigurationParser{})
assert.NoError(t, err)
@@ -161,7 +161,7 @@
event string
}
-func (l *mockDataListener) Process(configType *remoting.ConfigChangeEvent) {
+func (l *mockDataListener) Process(configType *config_center.ConfigChangeEvent) {
fmt.Println("process!!!!!")
l.wg.Done()
l.event = configType.Key
diff --git a/config_center/zookeeper/listener.go b/config_center/zookeeper/listener.go
index c79c05c..7128b6f 100644
--- a/config_center/zookeeper/listener.go
+++ b/config_center/zookeeper/listener.go
@@ -21,7 +21,9 @@
"strings"
"sync"
)
+
import (
+ "github.com/apache/dubbo-go/config_center"
"github.com/apache/dubbo-go/remoting"
)
@@ -33,21 +35,21 @@
func NewCacheListener(rootPath string) *CacheListener {
return &CacheListener{rootPath: rootPath}
}
-func (l *CacheListener) AddListener(key string, listener remoting.ConfigurationListener) {
+func (l *CacheListener) AddListener(key string, listener config_center.ConfigurationListener) {
// reference from https://stackoverflow.com/questions/34018908/golang-why-dont-we-have-a-set-datastructure
// make a map[your type]struct{} like set in java
- listeners, loaded := l.keyListeners.LoadOrStore(key, map[remoting.ConfigurationListener]struct{}{listener: struct{}{}})
+ listeners, loaded := l.keyListeners.LoadOrStore(key, map[config_center.ConfigurationListener]struct{}{listener: struct{}{}})
if loaded {
- listeners.(map[remoting.ConfigurationListener]struct{})[listener] = struct{}{}
+ listeners.(map[config_center.ConfigurationListener]struct{})[listener] = struct{}{}
l.keyListeners.Store(key, listeners)
}
}
-func (l *CacheListener) RemoveListener(key string, listener remoting.ConfigurationListener) {
+func (l *CacheListener) RemoveListener(key string, listener config_center.ConfigurationListener) {
listeners, loaded := l.keyListeners.Load(key)
if loaded {
- delete(listeners.(map[remoting.ConfigurationListener]struct{}), listener)
+ delete(listeners.(map[config_center.ConfigurationListener]struct{}), listener)
}
}
@@ -59,8 +61,8 @@
key := l.pathToKey(event.Path)
if key != "" {
if listeners, ok := l.keyListeners.Load(key); ok {
- for listener := range listeners.(map[remoting.ConfigurationListener]struct{}) {
- listener.Process(&remoting.ConfigChangeEvent{Key: key, Value: event.Content, ConfigType: event.Action})
+ for listener := range listeners.(map[config_center.ConfigurationListener]struct{}) {
+ listener.Process(&config_center.ConfigChangeEvent{Key: key, Value: event.Content, ConfigType: event.Action})
}
return true
}
diff --git a/examples/README.md b/examples/README.md
index 497926f..d520c5c 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -1,74 +1,80 @@
# examples
-Examples of go-for-apache-dubbo
+Examples of dubbo-go
-## dubbo
+## What does this contain
-#### Build by these command
+* helloworld
+
+ A simplest example. It contain 'go-client', 'go-server', 'java-server' of dubbo protocol.
+
+* general
+
+ A general example. It had validated zookeeper registry and different parameter lists of service.
+ And it has a comprehensive testing with dubbo/jsonrpc protocol. You can refer to it to create your first complete dubbo-go project.
+
+* generic
+
+ A generic reference example. It show how to use generic reference of dubbo-go.
+
+* configcenter
+
+ Some examples of different config center. There is only one -- zookeeper at present.
+
+## How to build and run
+
+> Take `helloworld` as an example
java server
+
```bash
-cd dubbo/java-server
+cd helloworld/dubbo/java-server
sh build.sh
-```
-java client
-```bash
-cd dubbo/java-client
-sh build.sh
-```
-
-go server
-
-* sh ./assembly/\[os]/\[environment].sh
-```bash
-cd dubbo/go-server
-# $ARCH = [linux, mac, windows] and $ENV = [dev, release, test]
-sh ./assembly/$ARCH/$ENV.sh
-```
-
-go client
-```bash
-cd dubbo/go-client
-# $ARCH = [linux, mac, windows] and $ENV = [dev, release, test]
-sh ./assembly/$ARCH/$ENV.sh
-```
-
-#### Run by these command:
-
-java server
-```bash
-cd dubbo/java-server/target
+cd ./target
tar -zxvf user-info-server-0.2.0-assembly.tar.gz
cd ./user-info-server-0.2.0
sh ./bin/server.sh start
```
java client
+
```bash
-cd dubbo/java-client/target
+cd helloworld/dubbo/java-client
+sh build.sh
+
+cd ./target
tar -zxvf user-info-client-0.2.0-assembly.tar.gz
cd ./user-info-client-0.2.0
sh ./bin/server.sh start
```
go server
+
+* $ARCH = [linux, mac, windows] and $ENV = [dev, release, test]
+
```bash
-cd dubbo/go-server/target/linux/user_info_server-0.3.1-20190517-0930-release
-#conf suffix appoint config file,
-#such as server_zookeeper.yml when "sh ./bin/load.sh start is zookeeper",
-#default server.yml
-sh ./bin/load.sh start [conf suffix]
+cd helloworld/dubbo/go-server
+sh ./assembly/$ARCH/$ENV.sh
+
+cd ./target/linux/user_info_server-0.3.1-20190517-0930-release
+# $SUFFIX is a suffix of config file,
+# such as server_zookeeper.yml when $SUFFIX is "zookeeper",
+# if $SUFFIX = "", default server.yml
+sh ./bin/load.sh start $SUFFIX
```
go client
+
+* $ARCH = [linux, mac, windows] and $ENV = [dev, release, test]
+
```bash
-cd dubbo/go-client/target/linux/user_info_client-0.3.1-20190517-0921-release
+cd helloworld/dubbo/go-client
+sh ./assembly/$ARCH/$ENV.sh
+
+cd ./target/linux/user_info_client-0.3.1-20190517-0921-release
# $SUFFIX is a suffix of config file,
# such as client_zookeeper.yml when $SUFFIX = zookeeper",
# if $SUFFIX = "", config file is client.yml
sh ./bin/load_user_info_client.sh start $SUFFIX
```
-
-## jsonrpc
-Similar to dubbo
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/app/client.go b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/app/client.go
deleted file mode 100644
index d27af7a..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/app/client.go
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * 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 main
-
-import (
- "context"
- "fmt"
- "os"
- "os/signal"
- "syscall"
- "time"
-)
-
-import (
- hessian "github.com/apache/dubbo-go-hessian2"
-)
-
-import (
- "github.com/apache/dubbo-go/common/logger"
- _ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
- "github.com/apache/dubbo-go/config"
- _ "github.com/apache/dubbo-go/protocol/dubbo"
- _ "github.com/apache/dubbo-go/registry/protocol"
-
- _ "github.com/apache/dubbo-go/filter/impl"
-
- _ "github.com/apache/dubbo-go/cluster/cluster_impl"
- _ "github.com/apache/dubbo-go/cluster/loadbalance"
- _ "github.com/apache/dubbo-go/config_center/zookeeper"
- _ "github.com/apache/dubbo-go/registry/zookeeper"
-)
-
-var (
- survivalTimeout int = 10e9
-)
-
-// they are necessary:
-// export CONF_CONSUMER_FILE_PATH="xxx"
-// export APP_LOG_CONF_FILE="xxx"
-func main() {
-
- hessian.RegisterJavaEnum(Gender(MAN))
- hessian.RegisterJavaEnum(Gender(WOMAN))
- hessian.RegisterPOJO(&User{})
-
- config.Load()
-
- println("\n\n\necho")
- res, err := userProvider.Echo(context.TODO(), "OK")
- if err != nil {
- panic(err)
- }
- println("res: %v\n", res)
-
- time.Sleep(3e9)
-
- println("\n\n\nstart to test dubbo")
- user := &User{}
- err = userProvider.GetUser(context.TODO(), []interface{}{"A003"}, user)
- if err != nil {
- panic(err)
- }
- println("response result: %v", user)
-
- println("\n\n\nstart to test dubbo - GetUser0")
- ret, err := userProvider.GetUser0("A003", "Moorse")
- if err != nil {
- panic(err)
- }
- println("response result: %v", ret)
-
- println("\n\n\nstart to test dubbo - GetUsers")
- ret1, err := userProvider.GetUsers([]interface{}{[]interface{}{"A002", "A003"}})
- if err != nil {
- panic(err)
- }
- println("response result: %v", ret1)
-
- println("\n\n\nstart to test dubbo - getUser")
- user = &User{}
- var i int32 = 1
- err = userProvider.GetUser2(context.TODO(), []interface{}{i}, user)
- if err != nil {
- panic(err)
- }
- println("response result: %v", user)
-
- println("\n\n\nstart to test dubbo - GetUser3")
- err = userProvider.GetUser3()
- if err != nil {
- panic(err)
- }
- println("succ!")
-
- println("\n\n\nstart to test dubbo - getErr")
- user = &User{}
- err = userProvider.GetErr(context.TODO(), []interface{}{"A003"}, user)
- if err != nil {
- println("getErr - error: %v", err)
- }
-
- println("\n\n\nstart to test dubbo illegal method")
- err = userProvider.GetUser1(context.TODO(), []interface{}{"A003"}, user)
- if err != nil {
- panic(err)
- }
-
- initSignal()
-}
-
-func initSignal() {
- signals := make(chan os.Signal, 1)
- // It is not possible to block SIGKILL or syscall.SIGSTOP
- signal.Notify(signals, os.Interrupt, os.Kill, syscall.SIGHUP,
- syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
- for {
- sig := <-signals
- logger.Infof("get signal %s", sig.String())
- switch sig {
- case syscall.SIGHUP:
- // reload()
- default:
- go time.AfterFunc(time.Duration(survivalTimeout)*time.Second, func() {
- logger.Warnf("app exit now by force...")
- os.Exit(1)
- })
-
- // The program exits normally or timeout forcibly exits.
- fmt.Println("app exit now...")
- return
- }
- }
-}
-
-func println(format string, args ...interface{}) {
- fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...)
-}
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/dev/client.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/dev/client.yml
index c8e7bd0..48b7b0c 100644
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/dev/client.yml
+++ b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/dev/client.yml
@@ -13,7 +13,7 @@
cluster: "failover"
methods :
- name: "GetUser"
- retries: 3
+ retries: "3"
protocol_conf:
dubbo:
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/release/client.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/release/client.yml
deleted file mode 100644
index c8e7bd0..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/release/client.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-# dubbo client yaml configure file
-
-config_center:
- protocol: "zookeeper"
- address: "127.0.0.1:2181"
- group: "dubbo"
- config_file: "dubbo.client.properties"
-
-references:
- "UserProvider":
- protocol : "dubbo"
- interface : "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods :
- - name: "GetUser"
- retries: 3
-
-protocol_conf:
- dubbo:
- reconnect_interval: 0
- connection_number: 2
- heartbeat_period: "5s"
- session_timeout: "20s"
- pool_size: 64
- pool_ttl: 600
- getty_session_param:
- compress_encoding: false
- tcp_no_delay: true
- tcp_keep_alive: true
- keep_alive_period: "120s"
- tcp_r_buf_size: 262144
- tcp_w_buf_size: 65536
- pkg_wq_size: 512
- tcp_read_timeout: "1s"
- tcp_write_timeout: "5s"
- wait_timeout: "1s"
- max_msg_len: 10240
- session_name: "client"
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/release/log.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/release/log.yml
deleted file mode 100644
index e0514be..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/release/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "warn"
-development: true
-disableCaller: true
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/test/client.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/test/client.yml
deleted file mode 100644
index c8e7bd0..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/test/client.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-# dubbo client yaml configure file
-
-config_center:
- protocol: "zookeeper"
- address: "127.0.0.1:2181"
- group: "dubbo"
- config_file: "dubbo.client.properties"
-
-references:
- "UserProvider":
- protocol : "dubbo"
- interface : "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods :
- - name: "GetUser"
- retries: 3
-
-protocol_conf:
- dubbo:
- reconnect_interval: 0
- connection_number: 2
- heartbeat_period: "5s"
- session_timeout: "20s"
- pool_size: 64
- pool_ttl: 600
- getty_session_param:
- compress_encoding: false
- tcp_no_delay: true
- tcp_keep_alive: true
- keep_alive_period: "120s"
- tcp_r_buf_size: 262144
- tcp_w_buf_size: 65536
- pkg_wq_size: 512
- tcp_read_timeout: "1s"
- tcp_write_timeout: "5s"
- wait_timeout: "1s"
- max_msg_len: 10240
- session_name: "client"
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/test/log.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/test/log.yml
deleted file mode 100644
index baee0b7..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/test/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "info"
-development: false
-disableCaller: false
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/server.go b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/server.go
deleted file mode 100644
index cd98299..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/server.go
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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 main
-
-import (
- "fmt"
- "os"
- "os/signal"
- "syscall"
- "time"
-)
-
-import (
- hessian "github.com/apache/dubbo-go-hessian2"
-)
-
-import (
- _ "github.com/apache/dubbo-go/cluster/cluster_impl"
- _ "github.com/apache/dubbo-go/cluster/loadbalance"
- "github.com/apache/dubbo-go/common/logger"
- _ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
- "github.com/apache/dubbo-go/config"
- _ "github.com/apache/dubbo-go/config_center/zookeeper"
- _ "github.com/apache/dubbo-go/filter/impl"
- _ "github.com/apache/dubbo-go/protocol/dubbo"
- _ "github.com/apache/dubbo-go/registry/protocol"
- _ "github.com/apache/dubbo-go/registry/zookeeper"
-)
-
-var (
- survivalTimeout = int(3e9)
-)
-
-// they are necessary:
-// export CONF_PROVIDER_FILE_PATH="xxx"
-// export APP_LOG_CONF_FILE="xxx"
-func main() {
-
- // ------for hessian2------
- hessian.RegisterJavaEnum(Gender(MAN))
- hessian.RegisterJavaEnum(Gender(WOMAN))
- hessian.RegisterPOJO(&User{})
- // ------------
-
- config.Load()
-
- initSignal()
-}
-
-func initSignal() {
- signals := make(chan os.Signal, 1)
- // It is not possible to block SIGKILL or syscall.SIGSTOP
- signal.Notify(signals, os.Interrupt, os.Kill, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
- for {
- sig := <-signals
- logger.Infof("get signal %s", sig.String())
- switch sig {
- case syscall.SIGHUP:
- // reload()
- default:
- go time.AfterFunc(time.Duration(float64(survivalTimeout)*float64(time.Second)), func() {
- logger.Warnf("app exit now by force...")
- os.Exit(1)
- })
-
- // The program exits normally or timeout forcibly exits.
- fmt.Println("provider app exit now...")
- return
- }
- }
-}
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/user.go b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/user.go
deleted file mode 100644
index 0e4d057..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/user.go
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * 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 main
-
-import (
- "context"
- "fmt"
- "strconv"
- "time"
-)
-
-import (
- hessian "github.com/apache/dubbo-go-hessian2"
- "github.com/apache/dubbo-go-hessian2/java_exception"
- perrors "github.com/pkg/errors"
-)
-
-import (
- "github.com/apache/dubbo-go/config"
-)
-
-type Gender hessian.JavaEnum
-
-func init() {
- config.SetProviderService(new(UserProvider))
-}
-
-const (
- MAN hessian.JavaEnum = iota
- WOMAN
-)
-
-var genderName = map[hessian.JavaEnum]string{
- MAN: "MAN",
- WOMAN: "WOMAN",
-}
-
-var genderValue = map[string]hessian.JavaEnum{
- "MAN": MAN,
- "WOMAN": WOMAN,
-}
-
-func (g Gender) JavaClassName() string {
- return "com.ikurento.user.Gender"
-}
-
-func (g Gender) String() string {
- s, ok := genderName[hessian.JavaEnum(g)]
- if ok {
- return s
- }
-
- return strconv.Itoa(int(g))
-}
-
-func (g Gender) EnumValue(s string) hessian.JavaEnum {
- v, ok := genderValue[s]
- if ok {
- return v
- }
-
- return hessian.InvalidJavaEnum
-}
-
-type (
- User struct {
- // !!! Cannot define lowercase names of variable
- Id string
- Name string
- Age int32
- Time time.Time
- Sex Gender // notice: java enum Object <--> go string
- }
-
- UserProvider struct {
- user map[string]User
- }
-)
-
-var (
- DefaultUser = User{
- Id: "0", Name: "Alex Stocks", Age: 31,
- Sex: Gender(MAN),
- }
-
- userMap = UserProvider{user: make(map[string]User)}
-)
-
-func init() {
- userMap.user["A000"] = DefaultUser
- userMap.user["A001"] = User{Id: "001", Name: "ZhangSheng", Age: 18, Sex: Gender(MAN)}
- userMap.user["A002"] = User{Id: "002", Name: "Lily", Age: 20, Sex: Gender(WOMAN)}
- userMap.user["A003"] = User{Id: "113", Name: "Moorse", Age: 30, Sex: Gender(WOMAN)}
- for k, v := range userMap.user {
- v.Time = time.Now()
- userMap.user[k] = v
- }
-}
-
-func (u User) String() string {
- return fmt.Sprintf(
- "User{Id:%s, Name:%s, Age:%d, Time:%s, Sex:%s}",
- u.Id, u.Name, u.Age, u.Time, u.Sex,
- )
-}
-
-func (u User) JavaClassName() string {
- return "com.ikurento.user.User"
-}
-
-func (u *UserProvider) getUser(userId string) (*User, error) {
- if user, ok := userMap.user[userId]; ok {
- return &user, nil
- }
-
- return nil, fmt.Errorf("invalid user id:%s", userId)
-}
-
-func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User) error {
- var (
- err error
- user *User
- )
-
- println("req:%#v", req)
- user, err = u.getUser(req[0].(string))
- if err == nil {
- *rsp = *user
- println("rsp:%#v", rsp)
- }
- return err
-}
-
-func (u *UserProvider) GetErr(ctx context.Context, req []interface{}, rsp *User) error {
- return java_exception.NewThrowable("exception")
-}
-
-func (u *UserProvider) GetUser0(id string, name string) (User, error) {
- var err error
-
- println("id:%s, name:%s", id, name)
- user, err := u.getUser(id)
- if err != nil {
- return User{}, err
- }
- if user.Name != name {
- return User{}, perrors.New("name is not " + user.Name)
- }
- return *user, err
-}
-
-func (u *UserProvider) GetUsers(req []interface{}) ([]interface{}, error) {
- var err error
-
- println("req:%s", req)
- t := req[0].([]interface{})
- user, err := u.getUser(t[0].(string))
- if err != nil {
- return nil, err
- }
- println("user:%v", user)
- user1, err := u.getUser(t[1].(string))
- if err != nil {
- return nil, err
- }
- println("user1:%v", user1)
-
- return []interface{}{user, user1}, err
-}
-
-func (u *UserProvider) Reference() string {
- return "UserProvider"
-}
-
-func println(format string, args ...interface{}) {
- fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...)
-}
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/bin/load.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/bin/load.sh
deleted file mode 100644
index 90077c2..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/bin/load.sh
+++ /dev/null
@@ -1,151 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-APP_NAME="APPLICATION_NAME"
-APP_ARGS=""
-
-
-PROJECT_HOME=""
-OS_NAME=`uname`
-if [[ ${OS_NAME} != "Windows" ]]; then
- PROJECT_HOME=`pwd`
- PROJECT_HOME=${PROJECT_HOME}"/"
-fi
-
-export CONF_PROVIDER_FILE_PATH=${PROJECT_HOME}"TARGET_CONF_FILE"
-export APP_LOG_CONF_FILE=${PROJECT_HOME}"TARGET_LOG_CONF_FILE"
-
-usage() {
- echo "Usage: $0 start [conf suffix]"
- echo " $0 stop"
- echo " $0 term"
- echo " $0 restart"
- echo " $0 list"
- echo " $0 monitor"
- echo " $0 crontab"
- exit
-}
-
-start() {
- arg=$1
- if [ "$arg" = "" ];then
- echo "No registry type! Default server.yml!"
- else
- export CONF_PROVIDER_FILE_PATH=${CONF_PROVIDER_FILE_PATH//\.yml/\_$arg\.yml}
- fi
- if [ ! -f "${CONF_PROVIDER_FILE_PATH}" ];then
- echo $CONF_PROVIDER_FILE_PATH" is not existing!"
- return
- fi
- APP_LOG_PATH="${PROJECT_HOME}logs/"
- mkdir -p ${APP_LOG_PATH}
- APP_BIN=${PROJECT_HOME}sbin/${APP_NAME}
- chmod u+x ${APP_BIN}
- # CMD="nohup ${APP_BIN} ${APP_ARGS} >>${APP_NAME}.nohup.out 2>&1 &"
- CMD="${APP_BIN}"
- eval ${CMD}
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
- if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
- fi
- CUR=`date +%FT%T`
- if [ "${PID}" != "" ]; then
- for p in ${PID}
- do
- echo "start ${APP_NAME} ( pid =" ${p} ") at " ${CUR}
- done
- fi
-}
-
-stop() {
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
- if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
- fi
- if [ "${PID}" != "" ];
- then
- for ps in ${PID}
- do
- echo "kill -SIGINT ${APP_NAME} ( pid =" ${ps} ")"
- kill -2 ${ps}
- done
- fi
-}
-
-
-term() {
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
- if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
- fi
- if [ "${PID}" != "" ];
- then
- for ps in ${PID}
- do
- echo "kill -9 ${APP_NAME} ( pid =" ${ps} ")"
- kill -9 ${ps}
- done
- fi
-}
-
-list() {
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s\n", $1, $2, $9, $10)}'`
- if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s,%s\n", $1, $4, $6, $7, $8)}'`
- fi
-
- if [ "${PID}" != "" ]; then
- echo "list ${APP_NAME}"
-
- if [[ ${OS_NAME} == "Linux" || ${OS_NAME} == "Darwin" ]]; then
- echo "index: user, pid, start, duration"
- else
- echo "index: PID, WINPID, UID, STIME, COMMAND"
- fi
- idx=0
- for ps in ${PID}
- do
- echo "${idx}: ${ps}"
- ((idx ++))
- done
- fi
-}
-
-opt=$1
-case C"$opt" in
- Cstart)
- start $2
- ;;
- Cstop)
- stop
- ;;
- Cterm)
- term
- ;;
- Crestart)
- term
- start $2
- ;;
- Clist)
- list
- ;;
- C*)
- usage
- ;;
-esac
-
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/common/app.properties b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/common/app.properties
deleted file mode 100644
index 1f0827e..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/common/app.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# 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.
-
-
-TARGET_EXEC_NAME="user_info_server"
-# BUILD_PACKAGE="dubbogo-examples/user-info/server/app"
-BUILD_PACKAGE="app"
-
-TARGET_CONF_FILE="conf/server.yml"
-TARGET_LOG_CONF_FILE="conf/log.yml"
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/common/build.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/common/build.sh
deleted file mode 100644
index 89a95ce..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/common/build.sh
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-rm -rf target/
-
-PROJECT_HOME=`pwd`
-TARGET_FOLDER=${PROJECT_HOME}/target/${GOOS}
-
-TARGET_SBIN_NAME=${TARGET_EXEC_NAME}
-version=`cat app/version.go | grep Version | grep -v "Apache" | awk -F '=' '{print $2}' | awk -F '"' '{print $2}'`
-if [[ ${GOOS} == "windows" ]]; then
- TARGET_SBIN_NAME=${TARGET_SBIN_NAME}.exe
-fi
-TARGET_NAME=${TARGET_FOLDER}/${TARGET_SBIN_NAME}
-if [[ $PROFILE = "test" ]]; then
- # GFLAGS=-gcflags "-N -l" -race -x -v # -x会把go build的详细过程输出
- # GFLAGS=-gcflags "-N -l" -race -v
- # GFLAGS="-gcflags \"-N -l\" -v"
- cd ${BUILD_PACKAGE} && go build -gcflags "-N -l" -x -v -i -o ${TARGET_NAME} && cd -
-else
- # -s去掉符号表(然后panic时候的stack trace就没有任何文件名/行号信息了,这个等价于普通C/C++程序被strip的效果),
- # -w去掉DWARF调试信息,得到的程序就不能用gdb调试了。-s和-w也可以分开使用,一般来说如果不打算用gdb调试,
- # -w基本没啥损失。-s的损失就有点大了。
- cd ${BUILD_PACKAGE} && go build -ldflags "-w" -x -v -i -o ${TARGET_NAME} && cd -
-fi
-
-TAR_NAME=${TARGET_EXEC_NAME}-${version}-`date "+%Y%m%d-%H%M"`-${PROFILE}
-
-mkdir -p ${TARGET_FOLDER}/${TAR_NAME}
-
-SBIN_DIR=${TARGET_FOLDER}/${TAR_NAME}/sbin
-BIN_DIR=${TARGET_FOLDER}/${TAR_NAME}
-CONF_DIR=${TARGET_FOLDER}/${TAR_NAME}/conf
-
-mkdir -p ${SBIN_DIR}
-mkdir -p ${CONF_DIR}
-
-mv ${TARGET_NAME} ${SBIN_DIR}
-cp -r assembly/bin ${BIN_DIR}
-# modify APPLICATION_NAME
-# OS=`uname`
-# if [[ $OS=="Darwin" ]]; then
-if [ "$(uname)" == "Darwin" ]; then
- sed -i "" "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/*
-else
- sed -i "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/*
-fi
-# modify TARGET_CONF_FILE
-if [ "$(uname)" == "Darwin" ]; then
- sed -i "" "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/*
-else
- sed -i "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/*
-fi
-# modify TARGET_LOG_CONF_FILE
-if [ "$(uname)" == "Darwin" ]; then
- sed -i "" "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/*
-else
- sed -i "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/*
-fi
-
-cp -r profiles/${PROFILE}/* ${CONF_DIR}
-
-cd ${TARGET_FOLDER}
-
-tar czf ${TAR_NAME}.tar.gz ${TAR_NAME}/*
-
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/linux/dev.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/linux/dev.sh
deleted file mode 100644
index d830ac9..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/linux/dev.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=linux
-export GOARCH=amd64
-
-PROFILE=dev
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/linux/release.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/linux/release.sh
deleted file mode 100644
index 9930380..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/linux/release.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=linux
-export GOARCH=amd64
-
-PROFILE=release
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/linux/test.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/linux/test.sh
deleted file mode 100644
index 87144bb..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/linux/test.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=linux
-export GOARCH=amd64
-
-PROFILE=test
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/mac/dev.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/mac/dev.sh
deleted file mode 100644
index 3a7659b..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/mac/dev.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=darwin
-export GOARCH=amd64
-
-PROFILE=dev
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/mac/release.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/mac/release.sh
deleted file mode 100644
index 1c4bce4..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/mac/release.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=darwin
-export GOARCH=amd64
-
-PROFILE=release
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/mac/test.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/mac/test.sh
deleted file mode 100644
index 69206e3..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/mac/test.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-set -e
-
-export GOOS=darwin
-export GOARCH=amd64
-
-PROFILE=test
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
-
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/windows/dev.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/windows/dev.sh
deleted file mode 100644
index 011fb41..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/windows/dev.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=windows
-export GOARCH=amd64
-
-PROFILE=dev
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/windows/release.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/windows/release.sh
deleted file mode 100644
index 679a26a..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/windows/release.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=windows
-export GOARCH=amd64
-
-PROFILE=release
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/windows/test.sh b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/windows/test.sh
deleted file mode 100644
index 4a36de0..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/assembly/windows/test.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=windows
-export GOARCH=amd64
-
-PROFILE=test
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/dev/log.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/dev/log.yml
deleted file mode 100644
index 59fa427..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/dev/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "debug"
-development: true
-disableCaller: false
-disableStacktrace: false
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/dev/server.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/dev/server.yml
index cdaaca4..219b92a 100644
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/dev/server.yml
+++ b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/dev/server.yml
@@ -17,7 +17,7 @@
cluster: "failover"
methods:
- name: "GetUser"
- retries: 1
+ retries: "1"
loadbalance: "random"
protocol_conf:
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/release/log.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/release/log.yml
deleted file mode 100644
index e0514be..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/release/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "warn"
-development: true
-disableCaller: true
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/release/server.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/release/server.yml
deleted file mode 100644
index cdaaca4..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/release/server.yml
+++ /dev/null
@@ -1,39 +0,0 @@
-# dubbo server yaml configure file
-
-
-config_center:
- protocol: "zookeeper"
- address: "127.0.0.1:2181"
- group: "dubbo"
- config_file: "dubbo.properties"
-
-services:
- "UserProvider":
- protocol : "dubbo"
- # 相当于dubbo.xml中的interface
- interface : "com.ikurento.user.UserProvider"
- loadbalance: "random"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
-
-protocol_conf:
- dubbo:
- session_number: 700
- session_timeout: "20s"
- getty_session_param:
- compress_encoding: false
- tcp_no_delay: true
- tcp_keep_alive: true
- keep_alive_period: "120s"
- tcp_r_buf_size: 262144
- tcp_w_buf_size: 65536
- pkg_wq_size: 512
- tcp_read_timeout: "1s"
- tcp_write_timeout: "5s"
- wait_timeout: "1s"
- max_msg_len: 1024
- session_name: "server"
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/test/log.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/test/log.yml
deleted file mode 100644
index baee0b7..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/test/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "info"
-development: false
-disableCaller: false
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/test/server.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/test/server.yml
deleted file mode 100644
index cdaaca4..0000000
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/test/server.yml
+++ /dev/null
@@ -1,39 +0,0 @@
-# dubbo server yaml configure file
-
-
-config_center:
- protocol: "zookeeper"
- address: "127.0.0.1:2181"
- group: "dubbo"
- config_file: "dubbo.properties"
-
-services:
- "UserProvider":
- protocol : "dubbo"
- # 相当于dubbo.xml中的interface
- interface : "com.ikurento.user.UserProvider"
- loadbalance: "random"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
-
-protocol_conf:
- dubbo:
- session_number: 700
- session_timeout: "20s"
- getty_session_param:
- compress_encoding: false
- tcp_no_delay: true
- tcp_keep_alive: true
- keep_alive_period: "120s"
- tcp_r_buf_size: 262144
- tcp_w_buf_size: 65536
- pkg_wq_size: 512
- tcp_read_timeout: "1s"
- tcp_write_timeout: "5s"
- wait_timeout: "1s"
- max_msg_len: 1024
- session_name: "server"
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/client.go b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/client.go
deleted file mode 100644
index 5b16347..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/client.go
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * 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 main
-
-import (
- "context"
- "fmt"
- "os"
- "os/signal"
- "syscall"
- "time"
-)
-
-import (
- "github.com/apache/dubbo-go/common/logger"
- _ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
- "github.com/apache/dubbo-go/config"
- _ "github.com/apache/dubbo-go/protocol/jsonrpc"
- _ "github.com/apache/dubbo-go/registry/protocol"
-
- _ "github.com/apache/dubbo-go/filter/impl"
-
- _ "github.com/apache/dubbo-go/cluster/cluster_impl"
- _ "github.com/apache/dubbo-go/cluster/loadbalance"
- _ "github.com/apache/dubbo-go/config_center/zookeeper"
- _ "github.com/apache/dubbo-go/registry/zookeeper"
-)
-
-var (
- survivalTimeout int = 10e9
-)
-
-// they are necessary:
-// export CONF_CONSUMER_FILE_PATH="xxx"
-// export APP_LOG_CONF_FILE="xxx"
-func main() {
-
- config.Load()
-
- println("\n\n\necho")
- res, err := userProvider.Echo(context.TODO(), "OK")
- if err != nil {
- println("echo - error: %v", err)
- } else {
- println("res: %v", res)
- }
-
- time.Sleep(3e9)
-
- println("\n\n\nstart to test jsonrpc")
- user := &JsonRPCUser{}
- err = userProvider.GetUser(context.TODO(), []interface{}{"A003"}, user)
- if err != nil {
- panic(err)
- }
- println("response result: %v", user)
-
- println("\n\n\nstart to test jsonrpc - GetUser0")
- ret, err := userProvider.GetUser0("A003", "Moorse")
- if err != nil {
- panic(err)
- }
- println("response result: %v", ret)
-
- println("\n\n\nstart to test jsonrpc - GetUsers")
- ret1, err := userProvider.GetUsers([]interface{}{[]interface{}{"A002", "A003"}})
- if err != nil {
- panic(err)
- }
- println("response result: %v", ret1)
-
- println("\n\n\nstart to test jsonrpc - getUser")
- user = &JsonRPCUser{}
- err = userProvider.GetUser2(context.TODO(), []interface{}{1}, user)
- if err != nil {
- panic(err)
- }
- println("response result: %v", user)
-
- println("\n\n\nstart to test jsonrpc - GetUser3")
- err = userProvider.GetUser3()
- if err != nil {
- panic(err)
- }
- println("succ!")
-
- println("\n\n\nstart to test jsonrpc illegal method")
- err = userProvider.GetUser1(context.TODO(), []interface{}{"A003"}, user)
- if err != nil {
- panic(err)
- }
-
- initSignal()
-}
-
-func initSignal() {
- signals := make(chan os.Signal, 1)
- // It is not possible to block SIGKILL or syscall.SIGSTOP
- signal.Notify(signals, os.Interrupt, os.Kill, syscall.SIGHUP,
- syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
- for {
- sig := <-signals
- logger.Infof("get signal %s", sig.String())
- switch sig {
- case syscall.SIGHUP:
- // reload()
- default:
- go time.AfterFunc(time.Duration(survivalTimeout)*time.Second, func() {
- logger.Warnf("app exit now by force...")
- os.Exit(1)
- })
-
- // The program exits normally or timeout forcibly exits.
- fmt.Println("app exit now...")
- return
- }
- }
-}
-
-func println(format string, args ...interface{}) {
- fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...)
-}
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/user.go b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/user.go
deleted file mode 100644
index fef665b..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/user.go
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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 main
-
-import (
- "context"
- "fmt"
- "time"
-)
-
-import (
- "github.com/apache/dubbo-go/config"
-)
-
-var userProvider = new(UserProvider)
-
-func init() {
- config.SetConsumerService(userProvider)
-}
-
-type JsonRPCUser struct {
- ID string `json:"id"`
- Name string `json:"name"`
- Age int64 `json:"age"`
- Time int64 `json:"time"`
- Sex string `json:"sex"`
-}
-
-func (u JsonRPCUser) String() string {
- return fmt.Sprintf(
- "User{ID:%s, Name:%s, Age:%d, Time:%s, Sex:%s}",
- u.ID, u.Name, u.Age, time.Unix(u.Time, 0).Format("2006-01-02 15:04:05.99999"), u.Sex,
- )
-}
-
-type UserProvider struct {
- GetUsers func(req []interface{}) ([]JsonRPCUser, error)
- GetUser func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error
- GetUser0 func(id string, name string) (JsonRPCUser, error)
- GetUser1 func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error
- GetUser2 func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error `dubbo:"getUser"`
- GetUser3 func() error
- Echo func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used
-}
-
-func (u *UserProvider) Reference() string {
- return "UserProvider"
-}
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/version.go b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/version.go
deleted file mode 100644
index c613858..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/version.go
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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 main
-
-var (
- Version = "2.6.0"
-)
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/bin/load.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/bin/load.sh
deleted file mode 100644
index ffa240b..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/bin/load.sh
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-APP_NAME="APPLICATION_NAME"
-APP_ARGS=""
-SLEEP_INTERVAL=5
-MAX_LIFETIME=4000
-
-PROJECT_HOME=""
-OS_NAME=`uname`
-if [[ ${OS_NAME} != "Windows" ]]; then
- PROJECT_HOME=`pwd`
- PROJECT_HOME=${PROJECT_HOME}"/"
-else
- APP_NAME="APPLICATION_NAME.exe"
-fi
-
-export CONF_CONSUMER_FILE_PATH=${PROJECT_HOME}"TARGET_CONF_FILE"
-export APP_LOG_CONF_FILE=${PROJECT_HOME}"TARGET_LOG_CONF_FILE"
-# export GOTRACEBACK=system
-# export GODEBUG=gctrace=1
-
-usage() {
- echo "Usage: $0 start [conf suffix]"
- echo " $0 stop"
- echo " $0 term"
- echo " $0 restart"
- echo " $0 list"
- echo " $0 monitor"
- echo " $0 crontab"
- exit
-}
-
-start() {
- arg=$1
- if [ "$arg" = "" ];then
- echo "No registry type! Default client.yml!"
- else
- export CONF_CONSUMER_FILE_PATH=${CONF_CONSUMER_FILE_PATH//\.yml/\_$arg\.yml}
- fi
- if [ ! -f "${CONF_CONSUMER_FILE_PATH}" ];then
- echo $CONF_CONSUMER_FILE_PATH" is not existing!"
- return
- fi
- APP_LOG_PATH=${PROJECT_HOME}"logs/"
- mkdir -p ${APP_LOG_PATH}
- APP_BIN=${PROJECT_HOME}sbin/${APP_NAME}
- chmod u+x ${APP_BIN}
- # CMD="nohup ${APP_BIN} ${APP_ARGS} >>${APP_NAME}.nohup.out 2>&1 &"
- CMD="${APP_BIN}"
- eval ${CMD}
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
- if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
- fi
- CUR=`date +%FT%T`
- if [ "${PID}" != "" ]; then
- for p in ${PID}
- do
- echo "start ${APP_NAME} ( pid =" ${p} ") at " ${CUR}
- done
- fi
-}
-
-stop() {
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
- if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
- fi
- if [ "${PID}" != "" ];
- then
- for ps in ${PID}
- do
- echo "kill -SIGINT ${APP_NAME} ( pid =" ${ps} ")"
- kill -2 ${ps}
- done
- fi
-}
-
-
-term() {
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
- if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
- fi
- if [ "${PID}" != "" ];
- then
- for ps in ${PID}
- do
- echo "kill -9 ${APP_NAME} ( pid =" ${ps} ")"
- kill -9 ${ps}
- done
- fi
-}
-
-list() {
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s\n", $1, $2, $9, $10)}'`
- if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s,%s\n", $1, $4, $6, $7, $8)}'`
- fi
-
- if [ "${PID}" != "" ]; then
- echo "list ${APP_NAME}"
-
- if [[ ${OS_NAME} == "Linux" || ${OS_NAME} == "Darwin" ]]; then
- echo "index: user, pid, start, duration"
- else
- echo "index: PID, WINPID, UID, STIME, COMMAND"
- fi
- idx=0
- for ps in ${PID}
- do
- echo "${idx}: ${ps}"
- ((idx ++))
- done
- fi
-}
-
-monitor() {
- idx=0
- while true; do
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
- if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
- fi
- if [[ "${PID}" == "" ]]; then
- start
- idx=0
- fi
-
- ((LIFE=idx*${SLEEP_INTERVAL}))
- echo "${APP_NAME} ( pid = " ${PID} ") has been working in normal state for " $LIFE " seconds."
- ((idx ++))
- sleep ${SLEEP_INTERVAL}
- done
-}
-
-crontab() {
- idx=0
- while true; do
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
- if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
- fi
- if [[ "${PID}" == "" ]]; then
- start
- idx=0
- fi
-
- ((LIFE=idx*${SLEEP_INTERVAL}))
- echo "${APP_NAME} ( pid = " ${PID} ") has been working in normal state for " $LIFE " seconds."
- ((idx ++))
- sleep ${SLEEP_INTERVAL}
- if [[ ${LIFE} -gt ${MAX_LIFETIME} ]]; then
- kill -9 ${PID}
- fi
- done
-}
-
-opt=$1
-case C"$opt" in
- Cstart)
- start $2
- ;;
- Cstop)
- stop
- ;;
- Cterm)
- term
- ;;
- Crestart)
- term
- start $2
- ;;
- Clist)
- list
- ;;
- Cmonitor)
- monitor
- ;;
- Ccrontab)
- crontab
- ;;
- C*)
- usage
- ;;
-esac
-
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/common/app.properties b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/common/app.properties
deleted file mode 100644
index e10868f..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/common/app.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# 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.
-
-
-export TARGET_EXEC_NAME="user_info_client"
-# BUILD_PACKAGE="dubbogo-examples/user-info/client/app"
-export BUILD_PACKAGE="app"
-
-export TARGET_CONF_FILE="conf/client.yml"
-export TARGET_LOG_CONF_FILE="conf/log.yml"
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/common/build.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/common/build.sh
deleted file mode 100644
index c9a9e87..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/common/build.sh
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-rm -rf target/
-
-PROJECT_HOME=`pwd`
-TARGET_FOLDER=${PROJECT_HOME}/target/${GOOS}
-
-TARGET_SBIN_NAME=${TARGET_EXEC_NAME}
-version=`cat app/version.go | grep Version | grep -v "Apache" | awk -F '=' '{print $2}' | awk -F '"' '{print $2}'`
-if [[ ${GOOS} == "windows" ]]; then
- TARGET_SBIN_NAME=${TARGET_SBIN_NAME}.exe
-fi
-TARGET_NAME=${TARGET_FOLDER}/${TARGET_SBIN_NAME}
-if [[ $PROFILE == "dev" || $PROFILE == "test" ]]; then
- # GFLAGS=-gcflags "-N -l" -race -x -v # -x会把go build的详细过程输出
- # GFLAGS=-gcflags "-N -l" -race -v
- # GFLAGS="-gcflags \"-N -l\" -v"
- cd ${BUILD_PACKAGE} && GOOS=$GOOS GOARCH=$GOARCH go build -gcflags "-N -l" -x -v -i -o ${TARGET_NAME} && cd -
-else
- # -s去掉符号表(然后panic时候的stack trace就没有任何文件名/行号信息了,这个等价于普通C/C++程序被strip的效果),
- # -w去掉DWARF调试信息,得到的程序就不能用gdb调试了。-s和-w也可以分开使用,一般来说如果不打算用gdb调试,
- # -w基本没啥损失。-s的损失就有点大了。
- cd ${BUILD_PACKAGE} && GOOS=$GOOS GOARCH=$GOARCH go build -ldflags "-w" -x -v -i -o ${TARGET_NAME} && cd -
-fi
-
-TAR_NAME=${TARGET_EXEC_NAME}-${version}-`date "+%Y%m%d-%H%M"`-${PROFILE}
-
-mkdir -p ${TARGET_FOLDER}/${TAR_NAME}
-
-SBIN_DIR=${TARGET_FOLDER}/${TAR_NAME}/sbin
-BIN_DIR=${TARGET_FOLDER}/${TAR_NAME}
-CONF_DIR=${TARGET_FOLDER}/${TAR_NAME}/conf
-
-mkdir -p ${SBIN_DIR}
-mkdir -p ${CONF_DIR}
-
-mv ${TARGET_NAME} ${SBIN_DIR}
-cp -r assembly/bin ${BIN_DIR}
-cd ${BIN_DIR}/bin/ && mv load.sh load_${TARGET_EXEC_NAME}.sh && cd -
-
-platform=$(uname)
-# modify APPLICATION_NAME
-if [ ${platform} == "Darwin" ]; then
- sed -i "" "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/*
-else
- sed -i "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/*
-fi
-
-# modify TARGET_CONF_FILE
-if [ ${platform} == "Darwin" ]; then
- sed -i "" "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/*
-else
- sed -i "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/*
-fi
-
-# modify TARGET_LOG_CONF_FILE
-if [ ${platform} == "Darwin" ]; then
- sed -i "" "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/*
-else
- sed -i "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/*
-fi
-
-cp -r profiles/${PROFILE}/* ${CONF_DIR}
-
-cd ${TARGET_FOLDER}
-
-tar czf ${TAR_NAME}.tar.gz ${TAR_NAME}/*
-
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/linux/dev.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/linux/dev.sh
deleted file mode 100644
index eada737..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/linux/dev.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=linux
-export GOARCH=amd64
-
-export PROFILE="dev"
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
- . ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
- sh ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/linux/release.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/linux/release.sh
deleted file mode 100644
index 10eb3d7..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/linux/release.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=linux
-export GOARCH=amd64
-
-export PROFILE="release"
-export PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
- . ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
- sh ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/linux/test.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/linux/test.sh
deleted file mode 100644
index 78b650c..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/linux/test.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=linux
-export GOARCH=amd64
-
-export PROFILE="test"
-export PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
- . ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
- sh ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/mac/dev.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/mac/dev.sh
deleted file mode 100644
index c828476..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/mac/dev.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=darwin
-export GOARCH=amd64
-
-export PROFILE="dev"
-
-export PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
- . ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
- sh ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/mac/release.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/mac/release.sh
deleted file mode 100644
index 91c2dfe..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/mac/release.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=darwin
-export GOARCH=amd64
-
-export PROFILE="release"
-export PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
- . ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
- sh ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/mac/test.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/mac/test.sh
deleted file mode 100644
index a7853f5..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/mac/test.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-set -e
-
-export GOOS=darwin
-export GOARCH=amd64
-
-export PROFILE="test"
-export PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
- . ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
- sh ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/windows/dev.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/windows/dev.sh
deleted file mode 100644
index 10a3866..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/windows/dev.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=linux
-export GOARCH=amd64
-
-export PROFILE="dev"
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
- . ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
- sh ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/windows/release.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/windows/release.sh
deleted file mode 100644
index 21af573..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/windows/release.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=windows
-export GOARCH=amd64
-
-export PROFILE="release"
-export PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
- . ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
- sh ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/windows/test.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/windows/test.sh
deleted file mode 100644
index 2104da8..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/windows/test.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=windows
-export GOARCH=amd64
-
-export PROFILE="test"
-export PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
- . ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
- sh ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/dev/client.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/dev/client.yml
deleted file mode 100644
index 3770f52..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/dev/client.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-# dubbo client yaml configure file
-
-config_center:
- protocol: "zookeeper"
- address: "127.0.0.1:2181"
- group: "dubbo"
- config_file: "dubbo.client.properties"
-
-references:
- "UserProvider":
- protocol : "jsonrpc"
- interface : "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods :
- - name: "GetUser"
- retries: 3
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/dev/log.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/dev/log.yml
deleted file mode 100644
index 59fa427..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/dev/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "debug"
-development: true
-disableCaller: false
-disableStacktrace: false
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/release/client.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/release/client.yml
deleted file mode 100644
index 3770f52..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/release/client.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-# dubbo client yaml configure file
-
-config_center:
- protocol: "zookeeper"
- address: "127.0.0.1:2181"
- group: "dubbo"
- config_file: "dubbo.client.properties"
-
-references:
- "UserProvider":
- protocol : "jsonrpc"
- interface : "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods :
- - name: "GetUser"
- retries: 3
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/release/log.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/release/log.yml
deleted file mode 100644
index e0514be..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/release/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "warn"
-development: true
-disableCaller: true
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/test/client.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/test/client.yml
deleted file mode 100644
index 3770f52..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/test/client.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-# dubbo client yaml configure file
-
-config_center:
- protocol: "zookeeper"
- address: "127.0.0.1:2181"
- group: "dubbo"
- config_file: "dubbo.client.properties"
-
-references:
- "UserProvider":
- protocol : "jsonrpc"
- interface : "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods :
- - name: "GetUser"
- retries: 3
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/test/log.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/test/log.yml
deleted file mode 100644
index baee0b7..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/test/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "info"
-development: false
-disableCaller: false
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/user.go b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/user.go
deleted file mode 100644
index 9ab9e58..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/user.go
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * 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 main
-
-import (
- "context"
- "fmt"
- "time"
-)
-
-import (
- perrors "github.com/pkg/errors"
-)
-
-import (
- "github.com/apache/dubbo-go/config"
-)
-
-type Gender int
-
-func init() {
- config.SetProviderService(new(UserProvider))
-}
-
-const (
- MAN = iota
- WOMAN
-)
-
-var genderStrings = [...]string{
- "MAN",
- "WOMAN",
-}
-
-func (g Gender) String() string {
- return genderStrings[g]
-}
-
-type (
- User struct {
- Id string `json:"id"`
- Name string `json:"name"`
- Age int `json:"age"`
- sex Gender
- Birth int `json:"time"`
- Sex string `json:"sex"`
- }
-
- UserProvider struct {
- user map[string]User
- }
-)
-
-var (
- DefaultUser = User{
- Id: "0", Name: "Alex Stocks", Age: 31,
- // Birth: int(time.Date(1985, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
- Birth: int(time.Date(1985, 11, 24, 15, 15, 0, 0, time.Local).Unix()),
- sex: Gender(MAN),
- }
-
- userMap = UserProvider{user: make(map[string]User)}
-)
-
-func init() {
- DefaultUser.Sex = DefaultUser.sex.String()
- userMap.user["A000"] = DefaultUser
- userMap.user["A001"] = User{Id: "001", Name: "ZhangSheng", Age: 18, sex: MAN}
- userMap.user["A002"] = User{Id: "002", Name: "Lily", Age: 20, sex: WOMAN}
- userMap.user["A003"] = User{Id: "113", Name: "Moorse", Age: 30, sex: MAN}
- for k, v := range userMap.user {
- v.Birth = int(time.Now().AddDate(-1*v.Age, 0, 0).Unix())
- v.Sex = userMap.user[k].sex.String()
- userMap.user[k] = v
- }
-}
-
-func (u *UserProvider) getUser(userId string) (*User, error) {
- if user, ok := userMap.user[userId]; ok {
- return &user, nil
- }
-
- return nil, fmt.Errorf("invalid user id:%s", userId)
-}
-
-func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User) error {
- var (
- err error
- user *User
- )
-
- println("req:%#v", req)
- user, err = u.getUser(req[0].(string))
- if err == nil {
- *rsp = *user
- println("rsp:%#v", rsp)
- }
- return err
-}
-
-func (u *UserProvider) GetUser0(id string, name string) (User, error) {
- var err error
-
- println("id:%s, name:%s", id, name)
- user, err := u.getUser(id)
- if err != nil {
- return User{}, err
- }
- if user.Name != name {
- return User{}, perrors.New("name is not " + user.Name)
- }
- return *user, err
-}
-
-func (u *UserProvider) GetUsers(req []interface{}) ([]User, error) {
- var err error
-
- println("req:%s", req)
- t := req[0].([]interface{})
- user, err := u.getUser(t[0].(string))
- if err != nil {
- return nil, err
- }
- println("user:%v", user)
- user1, err := u.getUser(t[1].(string))
- if err != nil {
- return nil, err
- }
- println("user1:%v", user1)
-
- return []User{*user, *user1}, err
-}
-
-func (u *UserProvider) Reference() string {
- return "UserProvider"
-}
-
-func println(format string, args ...interface{}) {
- fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...)
-}
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/version.go b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/version.go
deleted file mode 100644
index c613858..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/version.go
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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 main
-
-var (
- Version = "2.6.0"
-)
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/bin/load.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/bin/load.sh
deleted file mode 100644
index 90077c2..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/bin/load.sh
+++ /dev/null
@@ -1,151 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-APP_NAME="APPLICATION_NAME"
-APP_ARGS=""
-
-
-PROJECT_HOME=""
-OS_NAME=`uname`
-if [[ ${OS_NAME} != "Windows" ]]; then
- PROJECT_HOME=`pwd`
- PROJECT_HOME=${PROJECT_HOME}"/"
-fi
-
-export CONF_PROVIDER_FILE_PATH=${PROJECT_HOME}"TARGET_CONF_FILE"
-export APP_LOG_CONF_FILE=${PROJECT_HOME}"TARGET_LOG_CONF_FILE"
-
-usage() {
- echo "Usage: $0 start [conf suffix]"
- echo " $0 stop"
- echo " $0 term"
- echo " $0 restart"
- echo " $0 list"
- echo " $0 monitor"
- echo " $0 crontab"
- exit
-}
-
-start() {
- arg=$1
- if [ "$arg" = "" ];then
- echo "No registry type! Default server.yml!"
- else
- export CONF_PROVIDER_FILE_PATH=${CONF_PROVIDER_FILE_PATH//\.yml/\_$arg\.yml}
- fi
- if [ ! -f "${CONF_PROVIDER_FILE_PATH}" ];then
- echo $CONF_PROVIDER_FILE_PATH" is not existing!"
- return
- fi
- APP_LOG_PATH="${PROJECT_HOME}logs/"
- mkdir -p ${APP_LOG_PATH}
- APP_BIN=${PROJECT_HOME}sbin/${APP_NAME}
- chmod u+x ${APP_BIN}
- # CMD="nohup ${APP_BIN} ${APP_ARGS} >>${APP_NAME}.nohup.out 2>&1 &"
- CMD="${APP_BIN}"
- eval ${CMD}
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
- if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
- fi
- CUR=`date +%FT%T`
- if [ "${PID}" != "" ]; then
- for p in ${PID}
- do
- echo "start ${APP_NAME} ( pid =" ${p} ") at " ${CUR}
- done
- fi
-}
-
-stop() {
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
- if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
- fi
- if [ "${PID}" != "" ];
- then
- for ps in ${PID}
- do
- echo "kill -SIGINT ${APP_NAME} ( pid =" ${ps} ")"
- kill -2 ${ps}
- done
- fi
-}
-
-
-term() {
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
- if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
- fi
- if [ "${PID}" != "" ];
- then
- for ps in ${PID}
- do
- echo "kill -9 ${APP_NAME} ( pid =" ${ps} ")"
- kill -9 ${ps}
- done
- fi
-}
-
-list() {
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s\n", $1, $2, $9, $10)}'`
- if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
- PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s,%s\n", $1, $4, $6, $7, $8)}'`
- fi
-
- if [ "${PID}" != "" ]; then
- echo "list ${APP_NAME}"
-
- if [[ ${OS_NAME} == "Linux" || ${OS_NAME} == "Darwin" ]]; then
- echo "index: user, pid, start, duration"
- else
- echo "index: PID, WINPID, UID, STIME, COMMAND"
- fi
- idx=0
- for ps in ${PID}
- do
- echo "${idx}: ${ps}"
- ((idx ++))
- done
- fi
-}
-
-opt=$1
-case C"$opt" in
- Cstart)
- start $2
- ;;
- Cstop)
- stop
- ;;
- Cterm)
- term
- ;;
- Crestart)
- term
- start $2
- ;;
- Clist)
- list
- ;;
- C*)
- usage
- ;;
-esac
-
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/common/app.properties b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/common/app.properties
deleted file mode 100644
index 1f0827e..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/common/app.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# 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.
-
-
-TARGET_EXEC_NAME="user_info_server"
-# BUILD_PACKAGE="dubbogo-examples/user-info/server/app"
-BUILD_PACKAGE="app"
-
-TARGET_CONF_FILE="conf/server.yml"
-TARGET_LOG_CONF_FILE="conf/log.yml"
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/common/build.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/common/build.sh
deleted file mode 100644
index 89a95ce..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/common/build.sh
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-rm -rf target/
-
-PROJECT_HOME=`pwd`
-TARGET_FOLDER=${PROJECT_HOME}/target/${GOOS}
-
-TARGET_SBIN_NAME=${TARGET_EXEC_NAME}
-version=`cat app/version.go | grep Version | grep -v "Apache" | awk -F '=' '{print $2}' | awk -F '"' '{print $2}'`
-if [[ ${GOOS} == "windows" ]]; then
- TARGET_SBIN_NAME=${TARGET_SBIN_NAME}.exe
-fi
-TARGET_NAME=${TARGET_FOLDER}/${TARGET_SBIN_NAME}
-if [[ $PROFILE = "test" ]]; then
- # GFLAGS=-gcflags "-N -l" -race -x -v # -x会把go build的详细过程输出
- # GFLAGS=-gcflags "-N -l" -race -v
- # GFLAGS="-gcflags \"-N -l\" -v"
- cd ${BUILD_PACKAGE} && go build -gcflags "-N -l" -x -v -i -o ${TARGET_NAME} && cd -
-else
- # -s去掉符号表(然后panic时候的stack trace就没有任何文件名/行号信息了,这个等价于普通C/C++程序被strip的效果),
- # -w去掉DWARF调试信息,得到的程序就不能用gdb调试了。-s和-w也可以分开使用,一般来说如果不打算用gdb调试,
- # -w基本没啥损失。-s的损失就有点大了。
- cd ${BUILD_PACKAGE} && go build -ldflags "-w" -x -v -i -o ${TARGET_NAME} && cd -
-fi
-
-TAR_NAME=${TARGET_EXEC_NAME}-${version}-`date "+%Y%m%d-%H%M"`-${PROFILE}
-
-mkdir -p ${TARGET_FOLDER}/${TAR_NAME}
-
-SBIN_DIR=${TARGET_FOLDER}/${TAR_NAME}/sbin
-BIN_DIR=${TARGET_FOLDER}/${TAR_NAME}
-CONF_DIR=${TARGET_FOLDER}/${TAR_NAME}/conf
-
-mkdir -p ${SBIN_DIR}
-mkdir -p ${CONF_DIR}
-
-mv ${TARGET_NAME} ${SBIN_DIR}
-cp -r assembly/bin ${BIN_DIR}
-# modify APPLICATION_NAME
-# OS=`uname`
-# if [[ $OS=="Darwin" ]]; then
-if [ "$(uname)" == "Darwin" ]; then
- sed -i "" "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/*
-else
- sed -i "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/*
-fi
-# modify TARGET_CONF_FILE
-if [ "$(uname)" == "Darwin" ]; then
- sed -i "" "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/*
-else
- sed -i "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/*
-fi
-# modify TARGET_LOG_CONF_FILE
-if [ "$(uname)" == "Darwin" ]; then
- sed -i "" "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/*
-else
- sed -i "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/*
-fi
-
-cp -r profiles/${PROFILE}/* ${CONF_DIR}
-
-cd ${TARGET_FOLDER}
-
-tar czf ${TAR_NAME}.tar.gz ${TAR_NAME}/*
-
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/linux/dev.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/linux/dev.sh
deleted file mode 100644
index d830ac9..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/linux/dev.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=linux
-export GOARCH=amd64
-
-PROFILE=dev
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/linux/release.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/linux/release.sh
deleted file mode 100644
index 9930380..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/linux/release.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=linux
-export GOARCH=amd64
-
-PROFILE=release
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/linux/test.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/linux/test.sh
deleted file mode 100644
index 87144bb..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/linux/test.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=linux
-export GOARCH=amd64
-
-PROFILE=test
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/mac/dev.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/mac/dev.sh
deleted file mode 100644
index 3a7659b..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/mac/dev.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=darwin
-export GOARCH=amd64
-
-PROFILE=dev
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/mac/release.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/mac/release.sh
deleted file mode 100644
index 1c4bce4..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/mac/release.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=darwin
-export GOARCH=amd64
-
-PROFILE=release
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/mac/test.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/mac/test.sh
deleted file mode 100644
index 69206e3..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/mac/test.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-set -e
-
-export GOOS=darwin
-export GOARCH=amd64
-
-PROFILE=test
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
-
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/windows/dev.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/windows/dev.sh
deleted file mode 100644
index 011fb41..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/windows/dev.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=windows
-export GOARCH=amd64
-
-PROFILE=dev
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/windows/release.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/windows/release.sh
deleted file mode 100644
index 679a26a..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/windows/release.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=windows
-export GOARCH=amd64
-
-PROFILE=release
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/windows/test.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/windows/test.sh
deleted file mode 100644
index 4a36de0..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/windows/test.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-
-
-set -e
-
-export GOOS=windows
-export GOARCH=amd64
-
-PROFILE=test
-
-PROJECT_HOME=`pwd`
-
-if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
-. ${PROJECT_HOME}/assembly/common/app.properties
-fi
-
-
-if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
-. ${PROJECT_HOME}/assembly/common/build.sh
-fi
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/dev/log.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/dev/log.yml
deleted file mode 100644
index 59fa427..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/dev/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "debug"
-development: true
-disableCaller: false
-disableStacktrace: false
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/dev/server.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/dev/server.yml
deleted file mode 100644
index 5c2a2fe..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/dev/server.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-# dubbo server yaml configure file
-
-# application config
-
-services:
- "UserProvider":
- protocol : "jsonrpc"
- # 相当于dubbo.xml中的interface
- interface : "com.ikurento.user.UserProvider"
- loadbalance: "random"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
-
-config_center:
- protocol: "zookeeper"
- address: "127.0.0.1:2181"
- group: "dubbo"
- config_file: "dubbo.properties"
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/release/log.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/release/log.yml
deleted file mode 100644
index e0514be..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/release/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "warn"
-development: true
-disableCaller: true
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/release/server.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/release/server.yml
deleted file mode 100644
index 82c9fa6..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/release/server.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-# dubbo server yaml configure file
-
-# application config
-
-services:
- "UserProvider":
- protocol : "jsonrpc"
- # 相当于dubbo.xml中的interface
- interface : "com.ikurento.user.UserProvider"
- loadbalance: "random"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
-
-config_center:
- protocol: "zookeeper"
- address: "127.0.0.1:2181"
- group: "dubbo"
- config_file: "dubbo.properties"
-
-
-
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/test/log.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/test/log.yml
deleted file mode 100644
index baee0b7..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/test/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "info"
-development: false
-disableCaller: false
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/test/server.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/test/server.yml
deleted file mode 100644
index 82c9fa6..0000000
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/profiles/test/server.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-# dubbo server yaml configure file
-
-# application config
-
-services:
- "UserProvider":
- protocol : "jsonrpc"
- # 相当于dubbo.xml中的interface
- interface : "com.ikurento.user.UserProvider"
- loadbalance: "random"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
-
-config_center:
- protocol: "zookeeper"
- address: "127.0.0.1:2181"
- group: "dubbo"
- config_file: "dubbo.properties"
-
-
-
diff --git a/examples/consul/README.md b/examples/consul/README.md
new file mode 100644
index 0000000..bb47552
--- /dev/null
+++ b/examples/consul/README.md
@@ -0,0 +1,44 @@
+# consul
+
+Examples for consul registry. Before running examples below, make sure that consul has been started.
+
+## requirement
+
+- consul
+- go 1.12
+- java 8
+- maven 3.6.1
+
+## go-server
+
+```
+$ cd examples/consul/go-server
+$ export CONF_PROVIDER_FILE_PATH="config/server.yml"
+$ export APP_LOG_CONF_FILE="config/log.yml"
+$ go run .
+```
+
+## go-client
+
+```
+$ cd examples/consul/go-client
+$ export CONF_CONSUMER_FILE_PATH="config/client.yml"
+$ export APP_LOG_CONF_FILE="config/log.yml"
+$ go run .
+```
+
+## java-server
+
+```
+$ cd examples/consul/java-server
+$ mvn clean package
+$ java -jar target/java-server-1.0.0.jar
+```
+
+## java-client
+
+```
+$ cd examples/consul/java-client
+$ mvn clean package
+$ java -jar target/java-client-1.0.0.jar
+```
\ No newline at end of file
diff --git a/examples/consul/go-client/client.go b/examples/consul/go-client/client.go
new file mode 100644
index 0000000..73a9bc9
--- /dev/null
+++ b/examples/consul/go-client/client.go
@@ -0,0 +1,43 @@
+/*
+ * 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 main
+
+import (
+ "fmt"
+)
+
+import (
+ _ "github.com/apache/dubbo-go/cluster/cluster_impl"
+ _ "github.com/apache/dubbo-go/cluster/loadbalance"
+ _ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
+ "github.com/apache/dubbo-go/config"
+ _ "github.com/apache/dubbo-go/filter/impl"
+ _ "github.com/apache/dubbo-go/protocol/dubbo"
+ _ "github.com/apache/dubbo-go/registry/consul"
+ _ "github.com/apache/dubbo-go/registry/protocol"
+)
+
+func main() {
+ config.Load()
+
+ message, err := dubboService.SayHello([]interface{}{"world"})
+ if err != nil {
+ panic(err)
+ }
+ fmt.Println(message)
+}
diff --git a/examples/generic/go-client/profiles/test/client.yml b/examples/consul/go-client/config/client.yml
similarity index 72%
rename from examples/generic/go-client/profiles/test/client.yml
rename to examples/consul/go-client/config/client.yml
index 7442c64..556ac2b 100644
--- a/examples/generic/go-client/profiles/test/client.yml
+++ b/examples/consul/go-client/config/client.yml
@@ -1,14 +1,4 @@
-# dubbo client yaml configure file
-
-
-check: true
-# client
-request_timeout : "3s"
-# connect timeout
-connect_timeout : "3s"
-
-# application config
-application_config:
+application:
organization : "ikurento.com"
name : "BDTService"
module : "dubbogo user-info client"
@@ -17,20 +7,21 @@
environment : "test"
registries :
- "hangzhouzk":
- protocol: "zookeeper"
+ "consul":
+ protocol: "consul"
timeout : "3s"
- address: "127.0.0.1:2181"
- username: ""
- password: ""
- "shanghaizk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2182"
+ address: "127.0.0.1:8500"
username: ""
password: ""
references:
+ "DubboService":
+ protocol : "dubbo"
+ interface : "dubbo.DubboService"
+ cluster: "failover"
+ methods :
+ - name: "SayHello"
+ retries: "3"
protocol_conf:
dubbo:
@@ -38,6 +29,7 @@
connection_number: 2
heartbeat_period: "5s"
session_timeout: "20s"
+ fail_fast_timeout: "5s"
pool_size: 64
pool_ttl: 600
getty_session_param:
@@ -47,9 +39,14 @@
keep_alive_period: "120s"
tcp_r_buf_size: 262144
tcp_w_buf_size: 65536
+ pkg_rq_size: 1024
pkg_wq_size: 512
tcp_read_timeout: "1s"
tcp_write_timeout: "5s"
wait_timeout: "1s"
max_msg_len: 10240
session_name: "client"
+
+check: true
+request_timeout : "3s"
+connect_timeout : "3s"
diff --git a/examples/general/dubbo/go-client/profiles/test/log.yml b/examples/consul/go-client/config/log.yml
similarity index 100%
rename from examples/general/dubbo/go-client/profiles/test/log.yml
rename to examples/consul/go-client/config/log.yml
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go b/examples/consul/go-client/service.go
similarity index 73%
copy from examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go
copy to examples/consul/go-client/service.go
index c613858..0f7cca5 100644
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go
+++ b/examples/consul/go-client/service.go
@@ -17,6 +17,20 @@
package main
-var (
- Version = "2.6.0"
+import (
+ "github.com/apache/dubbo-go/config"
)
+
+var dubboService = new(DubboService)
+
+func init() {
+ config.SetConsumerService(dubboService)
+}
+
+type DubboService struct {
+ SayHello func(req interface{}) (string, error)
+}
+
+func (s *DubboService) Reference() string {
+ return "DubboService"
+}
diff --git a/examples/general/dubbo/go-client/profiles/test/log.yml b/examples/consul/go-server/config/log.yml
similarity index 100%
copy from examples/general/dubbo/go-client/profiles/test/log.yml
copy to examples/consul/go-server/config/log.yml
diff --git a/examples/helloworld/dubbo/go-server/profiles/release/server.yml b/examples/consul/go-server/config/server.yml
similarity index 64%
rename from examples/helloworld/dubbo/go-server/profiles/release/server.yml
rename to examples/consul/go-server/config/server.yml
index 4786e83..f3c169a 100644
--- a/examples/helloworld/dubbo/go-server/profiles/release/server.yml
+++ b/examples/consul/go-server/config/server.yml
@@ -1,50 +1,40 @@
-# dubbo server yaml configure file
-
-
-# application config
-application_config:
+application:
organization : "ikurento.com"
name : "BDTService"
module : "dubbogo user-info server"
version : "0.0.1"
owner : "ZX"
- environment : "release"
+ environment : "test"
registries :
- "hangzhouzk":
- protocol: "zookeeper"
+ "consul":
+ protocol: "consul"
timeout : "3s"
- address: "127.0.0.1:2181"
+ address: "127.0.0.1:8500"
username: ""
password: ""
-
services:
- "UserProvider":
- # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
- registry: "hangzhouzk"
+ "DubboService":
protocol : "dubbo"
- # 相当于dubbo.xml中的interface
- interface : "com.ikurento.user.UserProvider"
+ interface : "dubbo.DubboService"
loadbalance: "random"
warmup: "100"
cluster: "failover"
methods:
- - name: "GetUser"
- retries: 1
+ - name: "SayHello"
+ retries: "1"
loadbalance: "random"
-
protocols:
"dubbo1":
name: "dubbo"
- # ip : "127.0.0.1"
port: 20000
-
protocol_conf:
dubbo:
session_number: 700
+ fail_fast_timeout: "5s"
session_timeout: "20s"
getty_session_param:
compress_encoding: false
diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/server.go b/examples/consul/go-server/server.go
similarity index 83%
rename from examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/server.go
rename to examples/consul/go-server/server.go
index 0a0e729..0e1e1f6 100644
--- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/server.go
+++ b/examples/consul/go-server/server.go
@@ -31,23 +31,18 @@
"github.com/apache/dubbo-go/common/logger"
_ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
"github.com/apache/dubbo-go/config"
- _ "github.com/apache/dubbo-go/config_center/zookeeper"
_ "github.com/apache/dubbo-go/filter/impl"
- _ "github.com/apache/dubbo-go/protocol/jsonrpc"
+ _ "github.com/apache/dubbo-go/protocol/dubbo"
+ _ "github.com/apache/dubbo-go/registry/consul"
_ "github.com/apache/dubbo-go/registry/protocol"
- _ "github.com/apache/dubbo-go/registry/zookeeper"
)
var (
survivalTimeout = int(3e9)
)
-// they are necessary:
-// export CONF_PROVIDER_FILE_PATH="xxx"
-// export APP_LOG_CONF_FILE="xxx"
func main() {
config.Load()
-
initSignal()
}
@@ -60,9 +55,9 @@
logger.Infof("get signal %s", sig.String())
switch sig {
case syscall.SIGHUP:
- // reload()
+ // reload()
default:
- go time.AfterFunc(time.Duration(float64(survivalTimeout)*float64(time.Second)), func() {
+ time.AfterFunc(time.Duration(float64(survivalTimeout)*float64(time.Second)), func() {
logger.Warnf("app exit now by force...")
os.Exit(1)
})
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go b/examples/consul/go-server/service.go
similarity index 72%
copy from examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go
copy to examples/consul/go-server/service.go
index c613858..7c08ec9 100644
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go
+++ b/examples/consul/go-server/service.go
@@ -17,6 +17,20 @@
package main
-var (
- Version = "2.6.0"
+import (
+ "github.com/apache/dubbo-go/config"
)
+
+func init() {
+ config.SetProviderService(new(DubboService))
+}
+
+type DubboService struct{}
+
+func (s *DubboService) SayHello(message string) (string, error) {
+ return "hello " + message, nil
+}
+
+func (s *DubboService) Reference() string {
+ return "DubboService"
+}
diff --git a/examples/consul/java-client/.gitignore b/examples/consul/java-client/.gitignore
new file mode 100644
index 0000000..0bbcf41
--- /dev/null
+++ b/examples/consul/java-client/.gitignore
@@ -0,0 +1,7 @@
+.idea
+.gradle
+*.iml
+dependency-reduced-pom.xml
+out/
+build/
+target/
\ No newline at end of file
diff --git a/examples/consul/java-client/pom.xml b/examples/consul/java-client/pom.xml
new file mode 100644
index 0000000..3e54e77
--- /dev/null
+++ b/examples/consul/java-client/pom.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>consul</groupId>
+ <artifactId>java-client</artifactId>
+ <version>1.0.0</version>
+
+ <properties>
+ <maven.compiler.source>1.8</maven.compiler.source>
+ <maven.compiler.target>1.8</maven.compiler.target>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.17</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo</artifactId>
+ <version>2.7.1</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.ecwid.consul</groupId>
+ <artifactId>consul-api</artifactId>
+ <version>1.4.2</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.2</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>3.1.1</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <transformers>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>dubbo.client.Main</mainClass>
+ </transformer>
+ </transformers>
+ <filters>
+ <filter>
+ <artifact>*:*</artifact>
+ <excludes>
+ <exclude>META-INF/*.SF</exclude>
+ <exclude>META-INF/*.DSA</exclude>
+ <exclude>META-INF/*.RSA</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go b/examples/consul/java-client/src/main/java/dubbo/DubboService.java
similarity index 89%
rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go
rename to examples/consul/java-client/src/main/java/dubbo/DubboService.java
index c613858..4eb2d8c 100644
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go
+++ b/examples/consul/java-client/src/main/java/dubbo/DubboService.java
@@ -1,22 +1,22 @@
-/*
- * 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 main
-
-var (
- Version = "2.6.0"
-)
+/*
+ * 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 dubbo;
+
+public interface DubboService {
+ String SayHello(String message);
+}
diff --git a/examples/consul/java-client/src/main/java/dubbo/client/Main.java b/examples/consul/java-client/src/main/java/dubbo/client/Main.java
new file mode 100644
index 0000000..d9880bf
--- /dev/null
+++ b/examples/consul/java-client/src/main/java/dubbo/client/Main.java
@@ -0,0 +1,43 @@
+/*
+ * 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 dubbo.client;
+
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ReferenceConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import dubbo.DubboService;
+
+public class Main {
+ public static void main(String[] args) {
+ ApplicationConfig applicationConfig = new ApplicationConfig();
+ applicationConfig.setName("java-client");
+ applicationConfig.setQosPort(33333);
+
+ RegistryConfig registryConfig = new RegistryConfig();
+ registryConfig.setAddress("consul://127.0.0.1:8500");
+
+ ReferenceConfig<DubboService> referenceConfig = new ReferenceConfig<>();
+ referenceConfig.setApplication(applicationConfig);
+ referenceConfig.setRegistry(registryConfig);
+ referenceConfig.setInterface(DubboService.class);
+
+ DubboService dubboService = referenceConfig.get();
+ System.out.println(dubboService.SayHello("world"));
+ }
+}
diff --git a/examples/consul/java-client/src/main/resources/log4j.properties b/examples/consul/java-client/src/main/resources/log4j.properties
new file mode 100644
index 0000000..097fa43
--- /dev/null
+++ b/examples/consul/java-client/src/main/resources/log4j.properties
@@ -0,0 +1,4 @@
+log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.Stdout.layout.conversionPattern=[%p] %c | %m\n
+log4j.rootLogger=INFO,Stdout
\ No newline at end of file
diff --git a/examples/consul/java-server/.gitignore b/examples/consul/java-server/.gitignore
new file mode 100644
index 0000000..0bbcf41
--- /dev/null
+++ b/examples/consul/java-server/.gitignore
@@ -0,0 +1,7 @@
+.idea
+.gradle
+*.iml
+dependency-reduced-pom.xml
+out/
+build/
+target/
\ No newline at end of file
diff --git a/examples/consul/java-server/pom.xml b/examples/consul/java-server/pom.xml
new file mode 100644
index 0000000..07a1e5b
--- /dev/null
+++ b/examples/consul/java-server/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed 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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>consul</groupId>
+ <artifactId>java-server</artifactId>
+ <version>1.0.0</version>
+
+ <properties>
+ <maven.compiler.source>1.8</maven.compiler.source>
+ <maven.compiler.target>1.8</maven.compiler.target>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.17</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo</artifactId>
+ <version>2.7.1</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.ecwid.consul</groupId>
+ <artifactId>consul-api</artifactId>
+ <version>1.4.2</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.2</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>3.1.1</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <transformers>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>dubbo.server.Main</mainClass>
+ </transformer>
+ </transformers>
+ <filters>
+ <filter>
+ <artifact>*:*</artifact>
+ <excludes>
+ <exclude>META-INF/*.SF</exclude>
+ <exclude>META-INF/*.DSA</exclude>
+ <exclude>META-INF/*.RSA</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
diff --git a/examples/consul/java-server/src/main/java/dubbo/DubboService.java b/examples/consul/java-server/src/main/java/dubbo/DubboService.java
new file mode 100644
index 0000000..de6b5b5
--- /dev/null
+++ b/examples/consul/java-server/src/main/java/dubbo/DubboService.java
@@ -0,0 +1,5 @@
+package dubbo;
+
+public interface DubboService {
+ String SayHello(String message);
+}
diff --git a/examples/consul/java-server/src/main/java/dubbo/server/Impl/DubboServiceImpl.java b/examples/consul/java-server/src/main/java/dubbo/server/Impl/DubboServiceImpl.java
new file mode 100644
index 0000000..61c5e90
--- /dev/null
+++ b/examples/consul/java-server/src/main/java/dubbo/server/Impl/DubboServiceImpl.java
@@ -0,0 +1,11 @@
+package dubbo.server.Impl;
+
+import dubbo.DubboService;
+
+public class DubboServiceImpl implements DubboService {
+
+ @Override
+ public String SayHello(String message) {
+ return "hello " + message;
+ }
+}
diff --git a/examples/consul/java-server/src/main/java/dubbo/server/Main.java b/examples/consul/java-server/src/main/java/dubbo/server/Main.java
new file mode 100644
index 0000000..91c7b0b
--- /dev/null
+++ b/examples/consul/java-server/src/main/java/dubbo/server/Main.java
@@ -0,0 +1,53 @@
+/*
+ * 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 dubbo.server;
+
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import dubbo.DubboService;
+import dubbo.server.Impl.DubboServiceImpl;
+
+import java.io.IOException;
+
+public class Main {
+ public static void main(String[] args) throws IOException {
+ ApplicationConfig applicationConfig = new ApplicationConfig();
+ applicationConfig.setName("java-server");
+
+ RegistryConfig registryConfig = new RegistryConfig();
+ registryConfig.setAddress("consul://127.0.0.1:8500");
+
+ ProtocolConfig protocolConfig = new ProtocolConfig();
+ protocolConfig.setName("dubbo");
+ protocolConfig.setHost("127.0.0.1");
+ protocolConfig.setPort(12345);
+
+ ServiceConfig<DubboService> serviceConfig = new ServiceConfig<>();
+ serviceConfig.setApplication(applicationConfig);
+ serviceConfig.setRegistry(registryConfig);
+ serviceConfig.setProtocol(protocolConfig);
+ serviceConfig.setInterface(DubboService.class);
+ serviceConfig.setRef(new DubboServiceImpl());
+ serviceConfig.export();
+
+ System.in.read();
+ }
+}
diff --git a/examples/consul/java-server/src/main/resources/log4j.properties b/examples/consul/java-server/src/main/resources/log4j.properties
new file mode 100644
index 0000000..097fa43
--- /dev/null
+++ b/examples/consul/java-server/src/main/resources/log4j.properties
@@ -0,0 +1,4 @@
+log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.Stdout.layout.conversionPattern=[%p] %c | %m\n
+log4j.rootLogger=INFO,Stdout
\ No newline at end of file
diff --git a/examples/general/dubbo/go-client/app/client.go b/examples/general/dubbo/go-client/app/client.go
index e839b0b..f3ac4b9 100644
--- a/examples/general/dubbo/go-client/app/client.go
+++ b/examples/general/dubbo/go-client/app/client.go
@@ -33,9 +33,9 @@
"github.com/apache/dubbo-go/common/logger"
_ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
"github.com/apache/dubbo-go/config"
- _ "github.com/apache/dubbo-go/registry/protocol"
-
_ "github.com/apache/dubbo-go/filter/impl"
+ _ "github.com/apache/dubbo-go/protocol/dubbo"
+ _ "github.com/apache/dubbo-go/registry/protocol"
_ "github.com/apache/dubbo-go/cluster/cluster_impl"
_ "github.com/apache/dubbo-go/cluster/loadbalance"
@@ -78,7 +78,7 @@
case syscall.SIGHUP:
// reload()
default:
- go time.AfterFunc(time.Duration(survivalTimeout), func() {
+ time.AfterFunc(time.Duration(survivalTimeout), func() {
logger.Warnf("app exit now by force...")
os.Exit(1)
})
@@ -168,7 +168,7 @@
time.Sleep(3e9)
- println("\n\n\nstart to test dubbo")
+ println("\n\n\nstart to test1 dubbo")
user := &User{}
err = userProvider1.GetUser(context.TODO(), []interface{}{"A003"}, user)
if err != nil {
@@ -176,7 +176,7 @@
}
println("response result: %v", user)
- println("\n\n\nstart to test dubbo - GetUser0")
+ println("\n\n\nstart to test1 dubbo - GetUser0")
ret, err := userProvider1.GetUser0("A003", "Moorse")
if err != nil {
panic(err)
@@ -190,7 +190,7 @@
}
println("response result: %v", ret1)
- println("\n\n\nstart to test dubbo - getUser")
+ println("\n\n\nstart to test1 dubbo - getUser")
user = &User{}
var i int32 = 1
err = userProvider1.GetUser2(context.TODO(), []interface{}{i}, user)
@@ -206,7 +206,7 @@
}
println("succ!")
- println("\n\n\nstart to test dubbo - getErr")
+ println("\n\n\nstart to test1 dubbo - getErr")
user = &User{}
err = userProvider1.GetErr(context.TODO(), []interface{}{"A003"}, user)
if err == nil {
@@ -214,7 +214,7 @@
}
println("getErr - error: %v", err)
- println("\n\n\nstart to test dubbo illegal method")
+ println("\n\n\nstart to test1 dubbo illegal method")
err = userProvider1.GetUser1(context.TODO(), []interface{}{"A003"}, user)
if err == nil {
panic("err is nil")
@@ -232,7 +232,7 @@
time.Sleep(3e9)
- println("\n\n\nstart to test dubbo")
+ println("\n\n\nstart to test2 dubbo")
user := &User{}
err = userProvider2.GetUser(context.TODO(), []interface{}{"A003"}, user)
if err != nil {
@@ -240,21 +240,21 @@
}
println("response result: %v", user)
- println("\n\n\nstart to test dubbo - GetUser0")
+ println("\n\n\nstart to test2 dubbo - GetUser0")
ret, err := userProvider2.GetUser0("A003", "Moorse")
if err != nil {
panic(err)
}
println("response result: %v", ret)
- println("\n\n\nstart to test dubbo - GetUsers")
+ println("\n\n\nstart to test2 dubbo - GetUsers")
ret1, err := userProvider2.GetUsers([]interface{}{[]interface{}{"A002", "A003"}})
if err != nil {
panic(err)
}
println("response result: %v", ret1)
- println("\n\n\nstart to test dubbo - getUser")
+ println("\n\n\nstart to test2 dubbo - getUser")
user = &User{}
var i int32 = 1
err = userProvider2.GetUser2(context.TODO(), []interface{}{i}, user)
@@ -263,14 +263,14 @@
}
println("response result: %v", user)
- println("\n\n\nstart to test dubbo - GetUser3")
+ println("\n\n\nstart to test2 dubbo - GetUser3")
err = userProvider2.GetUser3()
if err != nil {
panic(err)
}
println("succ!")
- println("\n\n\nstart to test dubbo - getErr")
+ println("\n\n\nstart to test2 dubbo - getErr")
user = &User{}
err = userProvider2.GetErr(context.TODO(), []interface{}{"A003"}, user)
if err == nil {
@@ -278,7 +278,7 @@
}
println("getErr - error: %v", err)
- println("\n\n\nstart to test dubbo illegal method")
+ println("\n\n\nstart to test2 dubbo illegal method")
err = userProvider2.GetUser1(context.TODO(), []interface{}{"A003"}, user)
if err == nil {
panic("err is nil")
diff --git a/examples/general/dubbo/go-client/profiles/dev/client.yml b/examples/general/dubbo/go-client/profiles/dev/client.yml
index ff69668..002da1d 100644
--- a/examples/general/dubbo/go-client/profiles/dev/client.yml
+++ b/examples/general/dubbo/go-client/profiles/dev/client.yml
@@ -8,7 +8,7 @@
connect_timeout : "3s"
# application config
-application_config:
+application:
organization : "ikurento.com"
name : "BDTService"
module : "dubbogo user-info client"
@@ -39,7 +39,7 @@
cluster: "failover"
methods :
- name: "GetUser"
- retries: 3
+ retries: "3"
"UserProvider1":
registry: "hangzhouzk"
protocol: "dubbo"
@@ -48,7 +48,7 @@
cluster: "failover"
methods:
- name: "GetUser"
- retries: 3
+ retries: "3"
"UserProvider2":
registry: "hangzhouzk"
protocol: "dubbo"
@@ -58,7 +58,7 @@
cluster: "failover"
methods:
- name: "GetUser"
- retries: 3
+ retries: "3"
protocol_conf:
dubbo:
diff --git a/examples/general/dubbo/go-client/profiles/release/log.yml b/examples/general/dubbo/go-client/profiles/release/log.yml
deleted file mode 100644
index e0514be..0000000
--- a/examples/general/dubbo/go-client/profiles/release/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "warn"
-development: true
-disableCaller: true
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/general/dubbo/go-client/profiles/test/client.yml b/examples/general/dubbo/go-client/profiles/test/client.yml
deleted file mode 100644
index c8b5c58..0000000
--- a/examples/general/dubbo/go-client/profiles/test/client.yml
+++ /dev/null
@@ -1,83 +0,0 @@
-# dubbo client yaml configure file
-
-
-check: true
-# client
-request_timeout : "3s"
-# connect timeout
-connect_timeout : "3s"
-
-# application config
-application_config:
- organization : "ikurento.com"
- name : "BDTService"
- module : "dubbogo user-info client"
- version : "0.0.1"
- owner : "ZX"
- environment : "test"
-
-registries :
- "hangzhouzk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2181"
- username: ""
- password: ""
- "shanghaizk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2182"
- username: ""
- password: ""
-
-references:
- "UserProvider":
- # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
- registry: "hangzhouzk"
- protocol : "dubbo"
- interface : "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods :
- - name: "GetUser"
- retries: 3
- "UserProvider1":
- registry: "hangzhouzk"
- protocol: "dubbo"
- version: "2.0"
- interface: "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 3
- "UserProvider2":
- registry: "hangzhouzk"
- protocol: "dubbo"
- version: "2.0"
- group: "as"
- interface: "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 3
-
-protocol_conf:
- dubbo:
- reconnect_interval: 0
- connection_number: 2
- heartbeat_period: "5s"
- session_timeout: "20s"
- pool_size: 64
- pool_ttl: 600
- getty_session_param:
- compress_encoding: false
- tcp_no_delay: true
- tcp_keep_alive: true
- keep_alive_period: "120s"
- tcp_r_buf_size: 262144
- tcp_w_buf_size: 65536
- pkg_wq_size: 512
- tcp_read_timeout: "1s"
- tcp_write_timeout: "5s"
- wait_timeout: "1s"
- max_msg_len: 10240
- session_name: "client"
diff --git a/examples/general/dubbo/go-server/app/server.go b/examples/general/dubbo/go-server/app/server.go
index ac92b87..0ffd630 100644
--- a/examples/general/dubbo/go-server/app/server.go
+++ b/examples/general/dubbo/go-server/app/server.go
@@ -74,7 +74,7 @@
case syscall.SIGHUP:
// reload()
default:
- go time.AfterFunc(time.Duration(survivalTimeout), func() {
+ time.AfterFunc(time.Duration(survivalTimeout), func() {
logger.Warnf("app exit now by force...")
os.Exit(1)
})
diff --git a/examples/general/dubbo/go-server/profiles/dev/server.yml b/examples/general/dubbo/go-server/profiles/dev/server.yml
index 79c2cb2..c936e12 100644
--- a/examples/general/dubbo/go-server/profiles/dev/server.yml
+++ b/examples/general/dubbo/go-server/profiles/dev/server.yml
@@ -2,7 +2,7 @@
# application config
-application_config:
+application:
organization : "ikurento.com"
name : "BDTService"
module : "dubbogo user-info server"
@@ -38,7 +38,7 @@
cluster: "failover"
methods:
- name: "GetUser"
- retries: 1
+ retries: "1"
loadbalance: "random"
"UserProvider1":
registry: "hangzhouzk"
@@ -50,7 +50,7 @@
cluster: "failover"
methods:
- name: "GetUser"
- retries: 1
+ retries: "1"
loadbalance: "random"
"UserProvider2":
registry: "hangzhouzk"
@@ -63,7 +63,7 @@
cluster: "failover"
methods:
- name: "GetUser"
- retries: 1
+ retries: "1"
loadbalance: "random"
protocols:
diff --git a/examples/general/dubbo/go-server/profiles/release/log.yml b/examples/general/dubbo/go-server/profiles/release/log.yml
deleted file mode 100644
index e0514be..0000000
--- a/examples/general/dubbo/go-server/profiles/release/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "warn"
-development: true
-disableCaller: true
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/general/dubbo/go-server/profiles/release/server.yml b/examples/general/dubbo/go-server/profiles/release/server.yml
deleted file mode 100644
index 6890ed3..0000000
--- a/examples/general/dubbo/go-server/profiles/release/server.yml
+++ /dev/null
@@ -1,91 +0,0 @@
-# dubbo server yaml configure file
-
-
-# application config
-application_config:
- organization : "ikurento.com"
- name : "BDTService"
- module : "dubbogo user-info server"
- version : "0.0.1"
- owner : "ZX"
- environment : "release"
-
-registries :
- "hangzhouzk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2181"
- username: ""
- password: ""
- "shanghaizk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2182"
- username: ""
- password: ""
-
-
-services:
- "UserProvider":
- # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
- registry: "hangzhouzk"
- protocol : "dubbo"
- # 相当于dubbo.xml中的interface
- interface : "com.ikurento.user.UserProvider"
- loadbalance: "random"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
- "UserProvider1":
- registry: "hangzhouzk"
- protocol: "dubbo"
- version: "2.0"
- interface: "com.ikurento.user.UserProvider"
- loadbalance: "random"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
- "UserProvider2":
- registry: "hangzhouzk"
- protocol: "dubbo"
- version: "2.0"
- group: "as"
- interface: "com.ikurento.user.UserProvider"
- loadbalance: "random"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
-
-protocols:
- "dubbo1":
- name: "dubbo"
- # ip : "127.0.0.1"
- port: 20000
-
-
-protocol_conf:
- dubbo:
- session_number: 700
- session_timeout: "20s"
- getty_session_param:
- compress_encoding: false
- tcp_no_delay: true
- tcp_keep_alive: true
- keep_alive_period: "120s"
- tcp_r_buf_size: 262144
- tcp_w_buf_size: 65536
- pkg_wq_size: 512
- tcp_read_timeout: "1s"
- tcp_write_timeout: "5s"
- wait_timeout: "1s"
- max_msg_len: 1024
- session_name: "server"
diff --git a/examples/general/dubbo/go-server/profiles/test/log.yml b/examples/general/dubbo/go-server/profiles/test/log.yml
deleted file mode 100644
index baee0b7..0000000
--- a/examples/general/dubbo/go-server/profiles/test/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "info"
-development: false
-disableCaller: false
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/general/dubbo/go-server/profiles/test/server.yml b/examples/general/dubbo/go-server/profiles/test/server.yml
deleted file mode 100644
index b6dd41d..0000000
--- a/examples/general/dubbo/go-server/profiles/test/server.yml
+++ /dev/null
@@ -1,91 +0,0 @@
-# dubbo server yaml configure file
-
-
-# application config
-application_config:
- organization : "ikurento.com"
- name : "BDTService"
- module : "dubbogo user-info server"
- version : "0.0.1"
- owner : "ZX"
- environment : "test"
-
-registries :
- "hangzhouzk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2181"
- username: ""
- password: ""
- "shanghaizk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2182"
- username: ""
- password: ""
-
-
-services:
- "UserProvider":
- # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
- registry: "hangzhouzk"
- protocol : "dubbo"
- # 相当于dubbo.xml中的interface
- interface : "com.ikurento.user.UserProvider"
- loadbalance: "random"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
- "UserProvider1":
- registry: "hangzhouzk"
- protocol: "dubbo"
- version: "2.0"
- interface: "com.ikurento.user.UserProvider"
- loadbalance: "random"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
- "UserProvider2":
- registry: "hangzhouzk"
- protocol: "dubbo"
- version: "2.0"
- group: "as"
- interface: "com.ikurento.user.UserProvider"
- loadbalance: "random"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
-
-protocols:
- "dubbo1":
- name: "dubbo"
- # ip : "127.0.0.1"
- port: 20000
-
-
-protocol_conf:
- dubbo:
- session_number: 700
- session_timeout: "20s"
- getty_session_param:
- compress_encoding: false
- tcp_no_delay: true
- tcp_keep_alive: true
- keep_alive_period: "120s"
- tcp_r_buf_size: 262144
- tcp_w_buf_size: 65536
- pkg_wq_size: 512
- tcp_read_timeout: "1s"
- tcp_write_timeout: "5s"
- wait_timeout: "1s"
- max_msg_len: 1024
- session_name: "server"
diff --git a/examples/general/dubbo/java-client/src/main/java/com/ikurento/user/UserProvider.java b/examples/general/dubbo/java-client/src/main/java/com/ikurento/user/UserProvider.java
index 140dff0..a330d98 100644
--- a/examples/general/dubbo/java-client/src/main/java/com/ikurento/user/UserProvider.java
+++ b/examples/general/dubbo/java-client/src/main/java/com/ikurento/user/UserProvider.java
@@ -11,6 +11,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.ikurento.user;
import java.util.List;
diff --git a/examples/general/dubbo/java-client/src/main/resources/META-INF/spring/dubbo.consumer.xml b/examples/general/dubbo/java-client/src/main/resources/META-INF/spring/dubbo.consumer.xml
index 9dfd685..67c6264 100644
--- a/examples/general/dubbo/java-client/src/main/resources/META-INF/spring/dubbo.consumer.xml
+++ b/examples/general/dubbo/java-client/src/main/resources/META-INF/spring/dubbo.consumer.xml
@@ -12,6 +12,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+
+
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
diff --git a/examples/general/dubbo/java-client/src/main/resources/META-INF/spring/service.xml b/examples/general/dubbo/java-client/src/main/resources/META-INF/spring/service.xml
index 854d513..041d7c3 100644
--- a/examples/general/dubbo/java-client/src/main/resources/META-INF/spring/service.xml
+++ b/examples/general/dubbo/java-client/src/main/resources/META-INF/spring/service.xml
@@ -12,6 +12,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
diff --git a/examples/general/dubbo/java-server/pom.xml b/examples/general/dubbo/java-server/pom.xml
index 8c13228..9b811e9 100644
--- a/examples/general/dubbo/java-server/pom.xml
+++ b/examples/general/dubbo/java-server/pom.xml
@@ -13,7 +13,6 @@
limitations under the License.
-->
-
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
diff --git a/examples/general/dubbo/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java b/examples/general/dubbo/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java
index 6efa582..e2068f9 100644
--- a/examples/general/dubbo/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java
+++ b/examples/general/dubbo/java-server/src/main/java/com/ikurento/user/UserProviderImpl.java
@@ -17,7 +17,6 @@
package com.ikurento.user;
-
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
diff --git a/examples/general/jsonrpc/go-client/app/client.go b/examples/general/jsonrpc/go-client/app/client.go
index abbe586..0248af7 100644
--- a/examples/general/jsonrpc/go-client/app/client.go
+++ b/examples/general/jsonrpc/go-client/app/client.go
@@ -73,7 +73,7 @@
case syscall.SIGHUP:
// reload()
default:
- go time.AfterFunc(time.Duration(survivalTimeout), func() {
+ time.AfterFunc(time.Duration(survivalTimeout), func() {
logger.Warnf("app exit now by force...")
os.Exit(1)
})
@@ -98,7 +98,7 @@
println("res: %v", res)
}
- time.Sleep(3e9)
+ time.Sleep(10e9)
println("\n\n\nstart to test jsonrpc")
user := &JsonRPCUser{}
diff --git a/examples/general/jsonrpc/go-client/profiles/dev/client.yml b/examples/general/jsonrpc/go-client/profiles/dev/client.yml
index 788e06e..98c5c82 100644
--- a/examples/general/jsonrpc/go-client/profiles/dev/client.yml
+++ b/examples/general/jsonrpc/go-client/profiles/dev/client.yml
@@ -7,7 +7,7 @@
connect_timeout : "3s"
# application config
-application_config:
+application:
organization : "ikurento.com"
name : "BDTService"
module : "dubbogo user-info client"
@@ -38,7 +38,7 @@
cluster: "failover"
methods :
- name: "GetUser"
- retries: 3
+ retries: "3"
"UserProvider1":
registry: "hangzhouzk"
protocol: "jsonrpc"
@@ -47,7 +47,7 @@
cluster: "failover"
methods:
- name: "GetUser"
- retries: 3
+ retries: "3"
"UserProvider2":
registry: "hangzhouzk"
protocol: "jsonrpc"
@@ -57,4 +57,4 @@
cluster: "failover"
methods:
- name: "GetUser"
- retries: 3
+ retries: "3"
diff --git a/examples/general/jsonrpc/go-client/profiles/release/client.yml b/examples/general/jsonrpc/go-client/profiles/release/client.yml
deleted file mode 100644
index 0084e5b..0000000
--- a/examples/general/jsonrpc/go-client/profiles/release/client.yml
+++ /dev/null
@@ -1,60 +0,0 @@
-# dubbo client yaml configure file
-
-check: true
-# client
-request_timeout : "3s"
-# connect timeout
-connect_timeout : "3s"
-
-# application config
-application_config:
- organization : "ikurento.com"
- name : "BDTService"
- module : "dubbogo user-info client"
- version : "0.0.1"
- owner : "ZX"
- environment : "release"
-
-registries :
- "hangzhouzk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2181"
- username: ""
- password: ""
- "shanghaizk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2182"
- username: ""
- password: ""
-
-references:
- "UserProvider":
- # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
- registry: "hangzhouzk"
- protocol : "jsonrpc"
- interface : "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods :
- - name: "GetUser"
- retries: 3
- "UserProvider1":
- registry: "hangzhouzk"
- protocol: "jsonrpc"
- version : "2.0"
- interface: "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 3
- "UserProvider2":
- registry: "hangzhouzk"
- protocol: "jsonrpc"
- version : "2.0"
- group: "as"
- interface: "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 3
diff --git a/examples/general/jsonrpc/go-client/profiles/release/log.yml b/examples/general/jsonrpc/go-client/profiles/release/log.yml
deleted file mode 100644
index e0514be..0000000
--- a/examples/general/jsonrpc/go-client/profiles/release/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "warn"
-development: true
-disableCaller: true
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/general/jsonrpc/go-client/profiles/test/client.yml b/examples/general/jsonrpc/go-client/profiles/test/client.yml
deleted file mode 100644
index 3efdeda..0000000
--- a/examples/general/jsonrpc/go-client/profiles/test/client.yml
+++ /dev/null
@@ -1,60 +0,0 @@
-# dubbo client yaml configure file
-
-check: true
-# client
-request_timeout : "3s"
-# connect timeout
-connect_timeout : "3s"
-
-# application config
-application_config:
- organization : "ikurento.com"
- name : "BDTService"
- module : "dubbogo user-info client"
- version : "0.0.1"
- owner : "ZX"
- environment : "test"
-
-registries :
- "hangzhouzk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2181"
- username: ""
- password: ""
- "shanghaizk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2182"
- username: ""
- password: ""
-
-references:
- "UserProvider":
- # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
- registry: "hangzhouzk"
- protocol : "jsonrpc"
- interface : "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods :
- - name: "GetUser"
- retries: 3
- "UserProvider1":
- registry: "hangzhouzk"
- protocol: "jsonrpc"
- version : "2.0"
- interface: "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 3
- "UserProvider2":
- registry: "hangzhouzk"
- protocol: "jsonrpc"
- version : "2.0"
- group: "as"
- interface: "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 3
diff --git a/examples/general/jsonrpc/go-client/profiles/test/log.yml b/examples/general/jsonrpc/go-client/profiles/test/log.yml
deleted file mode 100644
index baee0b7..0000000
--- a/examples/general/jsonrpc/go-client/profiles/test/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "info"
-development: false
-disableCaller: false
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/general/jsonrpc/go-server/app/server.go b/examples/general/jsonrpc/go-server/app/server.go
index e36b6ef..de4aaed 100644
--- a/examples/general/jsonrpc/go-server/app/server.go
+++ b/examples/general/jsonrpc/go-server/app/server.go
@@ -64,7 +64,7 @@
case syscall.SIGHUP:
// reload()
default:
- go time.AfterFunc(time.Duration(survivalTimeout), func() {
+ time.AfterFunc(time.Duration(survivalTimeout), func() {
logger.Warnf("app exit now by force...")
os.Exit(1)
})
diff --git a/examples/general/jsonrpc/go-server/profiles/dev/server.yml b/examples/general/jsonrpc/go-server/profiles/dev/server.yml
index 4d74d2e..f4a2766 100644
--- a/examples/general/jsonrpc/go-server/profiles/dev/server.yml
+++ b/examples/general/jsonrpc/go-server/profiles/dev/server.yml
@@ -1,7 +1,7 @@
# dubbo server yaml configure file
# application config
-application_config:
+application:
organization : "ikurento.com"
name : "BDTService"
module : "dubbogo user-info server"
@@ -36,7 +36,7 @@
cluster: "failover"
methods:
- name: "GetUser"
- retries: 1
+ retries: "1"
loadbalance: "random"
"UserProvider1":
registry: "hangzhouzk"
@@ -48,7 +48,7 @@
cluster: "failover"
methods:
- name: "GetUser"
- retries: 1
+ retries: "1"
loadbalance: "random"
"UserProvider2":
registry: "hangzhouzk"
@@ -61,7 +61,7 @@
cluster: "failover"
methods:
- name: "GetUser"
- retries: 1
+ retries: "1"
loadbalance: "random"
protocols:
diff --git a/examples/general/jsonrpc/go-server/profiles/release/log.yml b/examples/general/jsonrpc/go-server/profiles/release/log.yml
deleted file mode 100644
index e0514be..0000000
--- a/examples/general/jsonrpc/go-server/profiles/release/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "warn"
-development: true
-disableCaller: true
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/general/jsonrpc/go-server/profiles/release/server.yml b/examples/general/jsonrpc/go-server/profiles/release/server.yml
deleted file mode 100644
index 3f7d2fd..0000000
--- a/examples/general/jsonrpc/go-server/profiles/release/server.yml
+++ /dev/null
@@ -1,75 +0,0 @@
-# dubbo server yaml configure file
-
-# application config
-application_config:
- organization : "ikurento.com"
- name : "BDTService"
- module : "dubbogo user-info server"
- version : "0.0.1"
- owner : "ZX"
- environment : "release"
-
-registries :
- "hangzhouzk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2181"
- username: ""
- password: ""
- "shanghaizk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2182"
- username: ""
- password: ""
-
-
-services:
- "UserProvider":
- # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
- registry: "hangzhouzk"
- protocol : "jsonrpc"
- # 相当于dubbo.xml中的interface
- interface : "com.ikurento.user.UserProvider"
- loadbalance: "random"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
- "UserProvider1":
- registry: "hangzhouzk"
- protocol: "jsonrpc"
- interface: "com.ikurento.user.UserProvider"
- loadbalance: "random"
- version: "2.0"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
- "UserProvider2":
- registry: "hangzhouzk"
- protocol: "jsonrpc"
- interface: "com.ikurento.user.UserProvider"
- loadbalance: "random"
- version: "2.0"
- group: "as"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
-
-protocols:
- #- name: "dubbo"
- # ip : "127.0.0.1"
- # port : 20000
- "jsonrpc1":
- name: "jsonrpc"
- ip: "127.0.0.1"
- port: 20001
-
diff --git a/examples/general/jsonrpc/go-server/profiles/test/log.yml b/examples/general/jsonrpc/go-server/profiles/test/log.yml
deleted file mode 100644
index baee0b7..0000000
--- a/examples/general/jsonrpc/go-server/profiles/test/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "info"
-development: false
-disableCaller: false
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/general/jsonrpc/go-server/profiles/test/server.yml b/examples/general/jsonrpc/go-server/profiles/test/server.yml
deleted file mode 100644
index dd0637e..0000000
--- a/examples/general/jsonrpc/go-server/profiles/test/server.yml
+++ /dev/null
@@ -1,75 +0,0 @@
-# dubbo server yaml configure file
-
-# application config
-application_config:
- organization : "ikurento.com"
- name : "BDTService"
- module : "dubbogo user-info server"
- version : "0.0.1"
- owner : "ZX"
- environment : "test"
-
-registries :
- "hangzhouzk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2181"
- username: ""
- password: ""
- "shanghaizk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2182"
- username: ""
- password: ""
-
-
-services:
- "UserProvider":
- # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
- registry: "hangzhouzk"
- protocol : "jsonrpc"
- # 相当于dubbo.xml中的interface
- interface : "com.ikurento.user.UserProvider"
- loadbalance: "random"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
- "UserProvider1":
- registry: "hangzhouzk"
- protocol: "jsonrpc"
- interface: "com.ikurento.user.UserProvider"
- loadbalance: "random"
- version: "2.0"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
- "UserProvider2":
- registry: "hangzhouzk"
- protocol: "jsonrpc"
- interface: "com.ikurento.user.UserProvider"
- loadbalance: "random"
- version: "2.0"
- group: "as"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
-
-protocols:
- #- name: "dubbo"
- # ip : "127.0.0.1"
- # port : 20000
- "jsonrpc1":
- name: "jsonrpc"
- ip: "127.0.0.1"
- port: 20001
-
diff --git a/examples/generic/go-client/app/client.go b/examples/generic/go-client/app/client.go
index 8d5a1bc..dbd4665 100644
--- a/examples/generic/go-client/app/client.go
+++ b/examples/generic/go-client/app/client.go
@@ -35,10 +35,6 @@
_ "github.com/apache/dubbo-go/registry/zookeeper"
)
-var (
- survivalTimeout int = 10e9
-)
-
// they are necessary:
// export CONF_CONSUMER_FILE_PATH="xxx"
// export APP_LOG_CONF_FILE="xxx"
diff --git a/examples/generic/go-client/app/user.go b/examples/generic/go-client/app/user.go
index 963a67f..9b226e2 100644
--- a/examples/generic/go-client/app/user.go
+++ b/examples/generic/go-client/app/user.go
@@ -1,20 +1,3 @@
-/*
- * 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 main
import (
diff --git a/examples/generic/go-client/assembly/bin/load.sh b/examples/generic/go-client/assembly/bin/load.sh
index ffa240b..176a202 100644
--- a/examples/generic/go-client/assembly/bin/load.sh
+++ b/examples/generic/go-client/assembly/bin/load.sh
@@ -15,7 +15,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
APP_NAME="APPLICATION_NAME"
APP_ARGS=""
SLEEP_INTERVAL=5
diff --git a/examples/generic/go-client/assembly/common/app.properties b/examples/generic/go-client/assembly/common/app.properties
index e10868f..97eee47 100644
--- a/examples/generic/go-client/assembly/common/app.properties
+++ b/examples/generic/go-client/assembly/common/app.properties
@@ -1,3 +1,4 @@
+#!/usr/bin/env bash
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
diff --git a/examples/generic/go-client/assembly/common/build.sh b/examples/generic/go-client/assembly/common/build.sh
index c9a9e87..0f0b22f 100644
--- a/examples/generic/go-client/assembly/common/build.sh
+++ b/examples/generic/go-client/assembly/common/build.sh
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+
rm -rf target/
PROJECT_HOME=`pwd`
diff --git a/examples/generic/go-client/assembly/linux/dev.sh b/examples/generic/go-client/assembly/linux/dev.sh
index eada737..4f659a7 100644
--- a/examples/generic/go-client/assembly/linux/dev.sh
+++ b/examples/generic/go-client/assembly/linux/dev.sh
@@ -16,7 +16,6 @@
# limitations under the License.
-
set -e
export GOOS=linux
diff --git a/examples/generic/go-client/assembly/mac/dev.sh b/examples/generic/go-client/assembly/mac/dev.sh
index c828476..0d21ec4 100644
--- a/examples/generic/go-client/assembly/mac/dev.sh
+++ b/examples/generic/go-client/assembly/mac/dev.sh
@@ -16,7 +16,6 @@
# limitations under the License.
-
set -e
export GOOS=darwin
diff --git a/examples/generic/go-client/assembly/mac/test.sh b/examples/generic/go-client/assembly/mac/test.sh
index a7853f5..2fac89d 100644
--- a/examples/generic/go-client/assembly/mac/test.sh
+++ b/examples/generic/go-client/assembly/mac/test.sh
@@ -16,6 +16,7 @@
# limitations under the License.
+
set -e
export GOOS=darwin
diff --git a/examples/generic/go-client/profiles/dev/client.yml b/examples/generic/go-client/profiles/dev/client.yml
index f4e3180..26752fb 100644
--- a/examples/generic/go-client/profiles/dev/client.yml
+++ b/examples/generic/go-client/profiles/dev/client.yml
@@ -8,7 +8,7 @@
connect_timeout : "3s"
# application config
-application_config:
+application:
organization : "ikurento.com"
name : "BDTService"
module : "dubbogo genric client"
diff --git a/examples/generic/go-client/profiles/release/client.yml b/examples/generic/go-client/profiles/release/client.yml
deleted file mode 100644
index 5a21bca..0000000
--- a/examples/generic/go-client/profiles/release/client.yml
+++ /dev/null
@@ -1,55 +0,0 @@
-# dubbo client yaml configure file
-
-
-check: true
-# client
-request_timeout : "3s"
-# connect timeout
-connect_timeout : "3s"
-
-# application config
-application_config:
- organization : "ikurento.com"
- name : "BDTService"
- module : "dubbogo generic client"
- version : "0.0.1"
- owner : "ZX"
- environment : "release"
-
-registries :
- "hangzhouzk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2181"
- username: ""
- password: ""
- "shanghaizk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2182"
- username: ""
- password: ""
-
-references:
-
-protocol_conf:
- dubbo:
- reconnect_interval: 0
- connection_number: 2
- heartbeat_period: "5s"
- session_timeout: "20s"
- pool_size: 64
- pool_ttl: 600
- getty_session_param:
- compress_encoding: false
- tcp_no_delay: true
- tcp_keep_alive: true
- keep_alive_period: "120s"
- tcp_r_buf_size: 262144
- tcp_w_buf_size: 65536
- pkg_wq_size: 512
- tcp_read_timeout: "1s"
- tcp_write_timeout: "5s"
- wait_timeout: "1s"
- max_msg_len: 10240
- session_name: "client"
diff --git a/examples/generic/go-client/profiles/release/log.yml b/examples/generic/go-client/profiles/release/log.yml
deleted file mode 100644
index e0514be..0000000
--- a/examples/generic/go-client/profiles/release/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "warn"
-development: true
-disableCaller: true
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/generic/go-client/profiles/test/log.yml b/examples/generic/go-client/profiles/test/log.yml
deleted file mode 100644
index baee0b7..0000000
--- a/examples/generic/go-client/profiles/test/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "info"
-development: false
-disableCaller: false
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/generic/java-server/script/debug.sh b/examples/generic/java-server/script/debug.sh
index 851957a..1038cd7 100644
--- a/examples/generic/java-server/script/debug.sh
+++ b/examples/generic/java-server/script/debug.sh
@@ -15,7 +15,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
# jdb -classpath /Users/alex/tmp/us/conf:/Users/alex/tmp/us/lib/*:/Users/alex/test/java/dubbo/2.5.4/dubbo-remoting/dubbo-remoting-api/src/main/java/ com.alibaba.dubbo.container.Main
jdb -classpath /Users/alex/tmp/us/conf:/Users/alex/tmp/us/lib/* -sourcepath /Users/alex/test/java/dubbo/2.5.4/dubbo-remoting/dubbo-remoting-api/src/main/java/:/Users/alex/tmp/java-server/src/main/java com.alibaba.dubbo.container.Main
# jdb stop at com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec:76
diff --git a/examples/generic/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml b/examples/generic/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml
index b3c3bbf..4ebe64b 100644
--- a/examples/generic/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml
+++ b/examples/generic/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml
@@ -12,6 +12,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
diff --git a/examples/helloworld/dubbo/go-client/assembly/bin/load.sh b/examples/helloworld/dubbo/go-client/assembly/bin/load.sh
index ffa240b..176a202 100644
--- a/examples/helloworld/dubbo/go-client/assembly/bin/load.sh
+++ b/examples/helloworld/dubbo/go-client/assembly/bin/load.sh
@@ -15,7 +15,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
APP_NAME="APPLICATION_NAME"
APP_ARGS=""
SLEEP_INTERVAL=5
diff --git a/examples/helloworld/dubbo/go-client/assembly/common/app.properties b/examples/helloworld/dubbo/go-client/assembly/common/app.properties
index e10868f..97eee47 100644
--- a/examples/helloworld/dubbo/go-client/assembly/common/app.properties
+++ b/examples/helloworld/dubbo/go-client/assembly/common/app.properties
@@ -1,3 +1,4 @@
+#!/usr/bin/env bash
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
diff --git a/examples/helloworld/dubbo/go-client/assembly/common/build.sh b/examples/helloworld/dubbo/go-client/assembly/common/build.sh
index c9a9e87..0f0b22f 100644
--- a/examples/helloworld/dubbo/go-client/assembly/common/build.sh
+++ b/examples/helloworld/dubbo/go-client/assembly/common/build.sh
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+
rm -rf target/
PROJECT_HOME=`pwd`
diff --git a/examples/helloworld/dubbo/go-client/assembly/linux/release.sh b/examples/helloworld/dubbo/go-client/assembly/linux/release.sh
index 10eb3d7..13b19f4 100644
--- a/examples/helloworld/dubbo/go-client/assembly/linux/release.sh
+++ b/examples/helloworld/dubbo/go-client/assembly/linux/release.sh
@@ -16,7 +16,6 @@
# limitations under the License.
-
set -e
export GOOS=linux
diff --git a/examples/helloworld/dubbo/go-client/assembly/linux/test.sh b/examples/helloworld/dubbo/go-client/assembly/linux/test.sh
index 78b650c..c6c31b3 100644
--- a/examples/helloworld/dubbo/go-client/assembly/linux/test.sh
+++ b/examples/helloworld/dubbo/go-client/assembly/linux/test.sh
@@ -16,7 +16,6 @@
# limitations under the License.
-
set -e
export GOOS=linux
diff --git a/examples/helloworld/dubbo/go-client/assembly/windows/dev.sh b/examples/helloworld/dubbo/go-client/assembly/windows/dev.sh
index 10a3866..6487b30 100644
--- a/examples/helloworld/dubbo/go-client/assembly/windows/dev.sh
+++ b/examples/helloworld/dubbo/go-client/assembly/windows/dev.sh
@@ -19,7 +19,7 @@
set -e
-export GOOS=linux
+export GOOS=windows
export GOARCH=amd64
export PROFILE="dev"
diff --git a/examples/helloworld/dubbo/go-client/profiles/dev/client.yml b/examples/helloworld/dubbo/go-client/profiles/dev/client.yml
index fed05b0..6fcc678 100644
--- a/examples/helloworld/dubbo/go-client/profiles/dev/client.yml
+++ b/examples/helloworld/dubbo/go-client/profiles/dev/client.yml
@@ -8,7 +8,7 @@
connect_timeout : "3s"
# application config
-application_config:
+application:
organization : "ikurento.com"
name : "BDTService"
module : "dubbogo user-info client"
@@ -34,7 +34,7 @@
cluster: "failover"
methods :
- name: "GetUser"
- retries: 3
+ retries: "3"
protocol_conf:
diff --git a/examples/helloworld/dubbo/go-client/profiles/release/client.yml b/examples/helloworld/dubbo/go-client/profiles/release/client.yml
deleted file mode 100644
index 02bf722..0000000
--- a/examples/helloworld/dubbo/go-client/profiles/release/client.yml
+++ /dev/null
@@ -1,60 +0,0 @@
-# dubbo client yaml configure file
-
-
-check: true
-# client
-request_timeout : "3s"
-# connect timeout
-connect_timeout : "3s"
-
-# application config
-application_config:
- organization : "ikurento.com"
- name : "BDTService"
- module : "dubbogo user-info client"
- version : "0.0.1"
- owner : "ZX"
- environment : "release"
-
-registries :
- "hangzhouzk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2181"
- username: ""
- password: ""
-
-
-references:
- "UserProvider":
- # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
- registry: "hangzhouzk"
- protocol : "dubbo"
- interface : "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods :
- - name: "GetUser"
- retries: 3
-
-protocol_conf:
- dubbo:
- reconnect_interval: 0
- connection_number: 2
- heartbeat_period: "5s"
- session_timeout: "20s"
- pool_size: 64
- pool_ttl: 600
- getty_session_param:
- compress_encoding: false
- tcp_no_delay: true
- tcp_keep_alive: true
- keep_alive_period: "120s"
- tcp_r_buf_size: 262144
- tcp_w_buf_size: 65536
- pkg_rq_size: 1024
- pkg_wq_size: 512
- tcp_read_timeout: "1s"
- tcp_write_timeout: "5s"
- wait_timeout: "1s"
- max_msg_len: 10240
- session_name: "client"
diff --git a/examples/helloworld/dubbo/go-client/profiles/release/log.yml b/examples/helloworld/dubbo/go-client/profiles/release/log.yml
deleted file mode 100644
index e0514be..0000000
--- a/examples/helloworld/dubbo/go-client/profiles/release/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "warn"
-development: true
-disableCaller: true
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/helloworld/dubbo/go-client/profiles/test/client.yml b/examples/helloworld/dubbo/go-client/profiles/test/client.yml
deleted file mode 100644
index 417a388..0000000
--- a/examples/helloworld/dubbo/go-client/profiles/test/client.yml
+++ /dev/null
@@ -1,59 +0,0 @@
-# dubbo client yaml configure file
-
-
-check: true
-# client
-request_timeout : "3s"
-# connect timeout
-connect_timeout : "3s"
-
-# application config
-application_config:
- organization : "ikurento.com"
- name : "BDTService"
- module : "dubbogo user-info client"
- version : "0.0.1"
- owner : "ZX"
- environment : "test"
-
-registries :
- "hangzhouzk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2181"
- username: ""
- password: ""
-
-references:
- "UserProvider":
- # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
- registry: "hangzhouzk"
- protocol : "dubbo"
- interface : "com.ikurento.user.UserProvider"
- cluster: "failover"
- methods :
- - name: "GetUser"
- retries: 3
-
-protocol_conf:
- dubbo:
- reconnect_interval: 0
- connection_number: 2
- heartbeat_period: "5s"
- session_timeout: "20s"
- pool_size: 64
- pool_ttl: 600
- getty_session_param:
- compress_encoding: false
- tcp_no_delay: true
- tcp_keep_alive: true
- keep_alive_period: "120s"
- tcp_r_buf_size: 262144
- tcp_w_buf_size: 65536
- pkg_rq_size: 1024
- pkg_wq_size: 512
- tcp_read_timeout: "1s"
- tcp_write_timeout: "5s"
- wait_timeout: "1s"
- max_msg_len: 10240
- session_name: "client"
diff --git a/examples/helloworld/dubbo/go-client/profiles/test/log.yml b/examples/helloworld/dubbo/go-client/profiles/test/log.yml
deleted file mode 100644
index baee0b7..0000000
--- a/examples/helloworld/dubbo/go-client/profiles/test/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "info"
-development: false
-disableCaller: false
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/helloworld/dubbo/go-server/app/server.go b/examples/helloworld/dubbo/go-server/app/server.go
index f02a6ba..dc3a40f 100644
--- a/examples/helloworld/dubbo/go-server/app/server.go
+++ b/examples/helloworld/dubbo/go-server/app/server.go
@@ -64,7 +64,7 @@
case syscall.SIGHUP:
// reload()
default:
- go time.AfterFunc(time.Duration(survivalTimeout), func() {
+ time.AfterFunc(time.Duration(survivalTimeout), func() {
logger.Warnf("app exit now by force...")
os.Exit(1)
})
diff --git a/examples/helloworld/dubbo/go-server/assembly/bin/load.sh b/examples/helloworld/dubbo/go-server/assembly/bin/load.sh
index 90077c2..2e127ac 100644
--- a/examples/helloworld/dubbo/go-server/assembly/bin/load.sh
+++ b/examples/helloworld/dubbo/go-server/assembly/bin/load.sh
@@ -15,7 +15,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
APP_NAME="APPLICATION_NAME"
APP_ARGS=""
diff --git a/examples/helloworld/dubbo/go-server/profiles/dev/server.yml b/examples/helloworld/dubbo/go-server/profiles/dev/server.yml
index be7eede..8e8594a 100644
--- a/examples/helloworld/dubbo/go-server/profiles/dev/server.yml
+++ b/examples/helloworld/dubbo/go-server/profiles/dev/server.yml
@@ -2,7 +2,7 @@
# application config
-application_config:
+application:
organization : "ikurento.com"
name : "BDTService"
module : "dubbogo user-info server"
@@ -28,8 +28,9 @@
cluster: "failover"
methods:
- name: "GetUser"
- retries: 1
+ retries: "1"
loadbalance: "random"
+ token: "true"
protocols:
"dubbo":
diff --git a/examples/helloworld/dubbo/go-server/profiles/release/log.yml b/examples/helloworld/dubbo/go-server/profiles/release/log.yml
deleted file mode 100644
index e0514be..0000000
--- a/examples/helloworld/dubbo/go-server/profiles/release/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "warn"
-development: true
-disableCaller: true
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/helloworld/dubbo/go-server/profiles/test/log.yml b/examples/helloworld/dubbo/go-server/profiles/test/log.yml
deleted file mode 100644
index baee0b7..0000000
--- a/examples/helloworld/dubbo/go-server/profiles/test/log.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-level: "info"
-development: false
-disableCaller: false
-disableStacktrace: true
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
diff --git a/examples/helloworld/dubbo/go-server/profiles/test/server.yml b/examples/helloworld/dubbo/go-server/profiles/test/server.yml
deleted file mode 100644
index ba6eb2b..0000000
--- a/examples/helloworld/dubbo/go-server/profiles/test/server.yml
+++ /dev/null
@@ -1,62 +0,0 @@
-# dubbo server yaml configure file
-
-
-# application config
-application_config:
- organization : "ikurento.com"
- name : "BDTService"
- module : "dubbogo user-info server"
- version : "0.0.1"
- owner : "ZX"
- environment : "test"
-
-registries :
- "hangzhouzk":
- protocol: "zookeeper"
- timeout : "3s"
- address: "127.0.0.1:2181"
- username: ""
- password: ""
-
-
-
-services:
- "UserProvider":
- # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
- registry: "hangzhouzk"
- protocol : "dubbo"
- # 相当于dubbo.xml中的interface
- interface : "com.ikurento.user.UserProvider"
- loadbalance: "random"
- warmup: "100"
- cluster: "failover"
- methods:
- - name: "GetUser"
- retries: 1
- loadbalance: "random"
-
-protocols:
- "dubbo1":
- name: "dubbo"
- # ip : "127.0.0.1"
- port: 20000
-
-
-protocol_conf:
- dubbo:
- session_number: 700
- session_timeout: "20s"
- getty_session_param:
- compress_encoding: false
- tcp_no_delay: true
- tcp_keep_alive: true
- keep_alive_period: "120s"
- tcp_r_buf_size: 262144
- tcp_w_buf_size: 65536
- pkg_rq_size: 1024
- pkg_wq_size: 512
- tcp_read_timeout: "1s"
- tcp_write_timeout: "5s"
- wait_timeout: "1s"
- max_msg_len: 1024
- session_name: "server"
diff --git a/examples/helloworld/dubbo/java-server/src/main/assembly/assembly.xml b/examples/helloworld/dubbo/java-server/src/main/assembly/assembly.xml
index 00c9fdd..98a2e10 100644
--- a/examples/helloworld/dubbo/java-server/src/main/assembly/assembly.xml
+++ b/examples/helloworld/dubbo/java-server/src/main/assembly/assembly.xml
@@ -12,6 +12,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+
<assembly>
<id>assembly</id>
<formats>
diff --git a/examples/helloworld/dubbo/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml b/examples/helloworld/dubbo/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml
index 3fca067..edd01dc 100644
--- a/examples/helloworld/dubbo/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml
+++ b/examples/helloworld/dubbo/java-server/src/main/resources/META-INF/spring/dubbo.provider.xml
@@ -12,6 +12,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/client.go b/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/client.go
new file mode 100644
index 0000000..e759465
--- /dev/null
+++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/client.go
@@ -0,0 +1,98 @@
+/*
+ * 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 main
+
+import (
+ "context"
+ "fmt"
+ "time"
+)
+
+import (
+ "github.com/apache/dubbo-go-hessian2"
+)
+
+import (
+ "github.com/apache/dubbo-go/common/logger"
+ _ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
+ "github.com/apache/dubbo-go/config"
+ _ "github.com/apache/dubbo-go/protocol/dubbo"
+ _ "github.com/apache/dubbo-go/registry/protocol"
+
+ _ "github.com/apache/dubbo-go/filter/impl"
+
+ _ "github.com/apache/dubbo-go/cluster/cluster_impl"
+ _ "github.com/apache/dubbo-go/cluster/loadbalance"
+ _ "github.com/apache/dubbo-go/registry/zookeeper"
+)
+
+// they are necessary:
+// export CONF_CONSUMER_FILE_PATH="xxx"
+// export APP_LOG_CONF_FILE="xxx"
+func main() {
+
+ hessian.RegisterJavaEnum(Gender(MAN))
+ hessian.RegisterJavaEnum(Gender(WOMAN))
+ hessian.RegisterPOJO(&User{})
+ getUserChan := make(chan string, 32)
+ getErrChan := make(chan string, 32)
+ getUser1Chan := make(chan string, 32)
+
+ config.Load()
+ logger.Debugf("[Start to test GetUser]")
+ for i := 0; i < 32; i++ {
+ go func() {
+ user := &User{}
+ err := userProvider.GetUser(context.TODO(), []interface{}{"A003"}, user)
+ getUserChan <- fmt.Sprintf("Result: %s ; Error: %v", user.Name, err)
+ }()
+ }
+ time.Sleep(time.Second * 4)
+
+ logger.Debugf("[Start to test GetErr, without error whitelist]")
+ for i := 0; i < 32; i++ {
+ go func() {
+ user := &User{}
+ err := userProvider.GetErr(context.TODO(), []interface{}{"A003"}, user)
+ getErrChan <- fmt.Sprintf("Result: %s ; Error: %v", user.Name, err)
+ }()
+ }
+ time.Sleep(time.Second * 4)
+
+ logger.Debugf("[Start to test illegal method GetUser1, with error whitelist]")
+ for i := 0; i < 32; i++ {
+ go func() {
+ user := &User{}
+ err := userProvider.GetUser1(context.TODO(), []interface{}{"A003"}, user)
+ getUser1Chan <- fmt.Sprintf("Result: %s ; Error: %v", user.Name, err)
+ }()
+ }
+ time.Sleep(time.Second * 4)
+ for i := 1; i < 32; i++ {
+ resGot := <-getUserChan
+ logger.Infof("[GetUser] %v", resGot)
+ }
+ for i := 1; i < 32; i++ {
+ resGot := <-getErrChan
+ logger.Infof("[GetErr] %v", resGot)
+ }
+ for i := 1; i < 32; i++ {
+ resGot := <-getUser1Chan
+ logger.Infof("[GetUser1] %v", resGot)
+ }
+}
diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/example_fallback_filter.go b/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/example_fallback_filter.go
new file mode 100644
index 0000000..0e86988
--- /dev/null
+++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/example_fallback_filter.go
@@ -0,0 +1,80 @@
+/*
+ * 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 main
+
+import (
+ "time"
+)
+
+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/filter/impl"
+ "github.com/apache/dubbo-go/protocol"
+)
+
+const (
+ EXAMPLE_FALLBACK_FILTER = "example_fallback"
+)
+
+//This is an example filter that handles result from hystrix filter
+//Define your filters and write your service downgrade strategy like this
+//TODO: Maybe a base fallback filter can be offered
+type ExampleFallbackFilter struct {
+}
+
+func GetExampleFallbackFilter() filter.Filter {
+ return &ExampleFallbackFilter{}
+}
+
+//The name should be the same as in your config
+//Put the filter in front of hystrix filter
+func init() {
+ extension.SetFilter(EXAMPLE_FALLBACK_FILTER, GetExampleFallbackFilter)
+}
+
+func (ff *ExampleFallbackFilter) Invoke(invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
+ return invoker.Invoke(invocation)
+
+}
+func (ff *ExampleFallbackFilter) OnResponse(result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
+ if err := result.Error(); err != nil {
+ hystrixError, ok := err.(*impl.HystrixFilterError)
+ if ok {
+ if hystrixError.FailByHystrix() {
+ logger.Debugf("[Example fallback filter]%s get error caused by %s", invocation.MethodName(), hystrixError.Error())
+ //Handle the error caused by Hystrix, including circuit breaking, concurrency limit and timeout
+ //The detailed error source can be got through hystrixError.Error()
+ //In this example we return a mock result under this circumstance
+ res := User{
+ "MockID",
+ "MockName",
+ 55,
+ time.Now(),
+ Gender(MAN),
+ }
+ *(invocation.Reply().(*User)) = res
+ result.SetResult(&res)
+ result.SetError(nil)
+ }
+ }
+ }
+ //If the error is not caused by hystrix, the result doesn't come from hystrix filter or there's no error,
+ //we just return it here.
+ return result
+}
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/app/user.go b/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/user.go
similarity index 62%
rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/app/user.go
rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/app/user.go
index 5bddf1e..affa541 100644
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/app/user.go
+++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/user.go
@@ -34,10 +34,16 @@
type Gender hessian.JavaEnum
-var userProvider = new(UserProvider)
+var (
+ userProvider = new(UserProvider)
+ userProvider1 = new(UserProvider1)
+ userProvider2 = new(UserProvider2)
+)
func init() {
config.SetConsumerService(userProvider)
+ config.SetConsumerService(userProvider1)
+ config.SetConsumerService(userProvider2)
}
const (
@@ -83,7 +89,7 @@
Name string
Age int32
Time time.Time
- Sex Gender // notice: java enum Object <--> go string
+ Sex Gender // 注意此处,java enum Object <--> go string
}
func (u User) String() string {
@@ -111,3 +117,33 @@
func (u *UserProvider) Reference() string {
return "UserProvider"
}
+
+type UserProvider1 struct {
+ GetUsers func(req []interface{}) ([]interface{}, error)
+ GetErr func(ctx context.Context, req []interface{}, rsp *User) error
+ GetUser func(ctx context.Context, req []interface{}, rsp *User) error
+ GetUser0 func(id string, name string) (User, error)
+ GetUser1 func(ctx context.Context, req []interface{}, rsp *User) error
+ GetUser2 func(ctx context.Context, req []interface{}, rsp *User) error `dubbo:"getUser"`
+ GetUser3 func() error
+ Echo func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used
+}
+
+func (u *UserProvider1) Reference() string {
+ return "UserProvider1"
+}
+
+type UserProvider2 struct {
+ GetUsers func(req []interface{}) ([]interface{}, error)
+ GetErr func(ctx context.Context, req []interface{}, rsp *User) error
+ GetUser func(ctx context.Context, req []interface{}, rsp *User) error
+ GetUser0 func(id string, name string) (User, error)
+ GetUser1 func(ctx context.Context, req []interface{}, rsp *User) error
+ GetUser2 func(ctx context.Context, req []interface{}, rsp *User) error `dubbo:"getUser"`
+ GetUser3 func() error
+ Echo func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used
+}
+
+func (u *UserProvider2) Reference() string {
+ return "UserProvider2"
+}
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/app/version.go b/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/version.go
similarity index 100%
rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/app/version.go
rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/app/version.go
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/bin/load.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/bin/load.sh
similarity index 100%
rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/bin/load.sh
rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/bin/load.sh
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/common/app.properties b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/common/app.properties
similarity index 100%
rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/common/app.properties
rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/common/app.properties
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/common/build.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/common/build.sh
similarity index 100%
rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/common/build.sh
rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/common/build.sh
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/linux/dev.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/linux/dev.sh
similarity index 100%
rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/linux/dev.sh
rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/linux/dev.sh
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/linux/release.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/linux/release.sh
similarity index 100%
rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/linux/release.sh
rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/linux/release.sh
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/linux/test.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/linux/test.sh
similarity index 100%
rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/linux/test.sh
rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/linux/test.sh
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/mac/dev.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/mac/dev.sh
similarity index 100%
rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/mac/dev.sh
rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/mac/dev.sh
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/mac/release.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/mac/release.sh
similarity index 100%
rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/mac/release.sh
rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/mac/release.sh
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/mac/test.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/mac/test.sh
similarity index 100%
rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/mac/test.sh
rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/mac/test.sh
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/windows/dev.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/windows/dev.sh
similarity index 100%
rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/windows/dev.sh
rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/windows/dev.sh
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/windows/release.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/windows/release.sh
similarity index 100%
rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/windows/release.sh
rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/windows/release.sh
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/windows/test.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/windows/test.sh
similarity index 100%
rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/assembly/windows/test.sh
rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/windows/test.sh
diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/dev/client.yml b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/dev/client.yml
new file mode 100644
index 0000000..8602b3a
--- /dev/null
+++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/dev/client.yml
@@ -0,0 +1,98 @@
+# dubbo client yaml configure file
+
+
+check: true
+# client
+request_timeout : "3s"
+# connect timeout
+connect_timeout : "3s"
+
+# application config
+application:
+ organization : "ikurento.com"
+ name : "BDTService"
+ module : "dubbogo user-info client"
+ version : "0.0.1"
+ owner : "ZX"
+ environment : "dev"
+
+registries :
+ "hangzhouzk":
+ # 对应java配置中address属性的zookeeper <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
+ protocol: "zookeeper"
+ timeout : "3s"
+ address: "127.0.0.1:2181"
+ username: ""
+ password: ""
+ "shanghaizk":
+ protocol: "zookeeper"
+ timeout : "3s"
+ address: "127.0.0.1:2182"
+ username: ""
+ password: ""
+
+references:
+ "UserProvider":
+ # 可以指定多个registry,使用逗号隔开;不指定默认向所有注册中心注册
+ registry: "hangzhouzk"
+ filter: "example_fallback,hystrix_consumer"
+ protocol : "dubbo"
+ interface : "com.ikurento.user.UserProvider"
+ cluster: "failover"
+ methods :
+ - name: "GetUser"
+ retries: "3"
+
+protocol_conf:
+ dubbo:
+ reconnect_interval: 0
+ connection_number: 2
+ heartbeat_period: "5s"
+ session_timeout: "20s"
+ fail_fast_timeout: "5s"
+ pool_size: 64
+ pool_ttl: 600
+ getty_session_param:
+ compress_encoding: false
+ tcp_no_delay: true
+ tcp_keep_alive: true
+ keep_alive_period: "120s"
+ tcp_r_buf_size: 262144
+ tcp_w_buf_size: 65536
+ pkg_rq_size: 1024
+ pkg_wq_size: 512
+ tcp_read_timeout: "1s"
+ tcp_write_timeout: "5s"
+ wait_timeout: "1s"
+ max_msg_len: 10240
+ session_name: "client"
+
+filter_conf:
+ hystrix:
+ configs:
+ "Default":
+ timeout : 1000
+ max_concurrent_requests : 25
+ sleep_window : 5000
+ error_percent_threshold : 50
+ request_volume_threshold: 20
+ "userp":
+ timeout: 2000
+ max_concurrent_requests: 512
+ sleep_window: 4000
+ error_percent_threshold: 35
+ request_volume_threshold: 6
+ "userp_m":
+ timeout : 1200
+ max_concurrent_requests : 512
+ sleep_window : 6000
+ error_percent_threshold : 60
+ request_volume_threshold: 16
+ error_whitelist: [".*exception.*"]
+ default: "Default"
+ services:
+ "com.ikurento.user.UserProvider":
+ service_config: "userp"
+ methods:
+ "GetUser": "userp_m"
+ "GetUser1": "userp_m"
\ No newline at end of file
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/dev/log.yml b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/dev/log.yml
similarity index 99%
rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/dev/log.yml
rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/dev/log.yml
index 59fa427..3ed242d 100644
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/dev/log.yml
+++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/dev/log.yml
@@ -1,28 +1,28 @@
-
-level: "debug"
-development: true
-disableCaller: false
-disableStacktrace: false
-sampling:
-encoding: "console"
-
-# encoder
-encoderConfig:
- messageKey: "message"
- levelKey: "level"
- timeKey: "time"
- nameKey: "logger"
- callerKey: "caller"
- stacktraceKey: "stacktrace"
- lineEnding: ""
- levelEncoder: "capitalColor"
- timeEncoder: "iso8601"
- durationEncoder: "seconds"
- callerEncoder: "short"
- nameEncoder: ""
-
-outputPaths:
- - "stderr"
-errorOutputPaths:
- - "stderr"
-initialFields:
+
+level: "debug"
+development: true
+disableCaller: false
+disableStacktrace: false
+sampling:
+encoding: "console"
+
+# encoder
+encoderConfig:
+ messageKey: "message"
+ levelKey: "level"
+ timeKey: "time"
+ nameKey: "logger"
+ callerKey: "caller"
+ stacktraceKey: "stacktrace"
+ lineEnding: ""
+ levelEncoder: "capitalColor"
+ timeEncoder: "iso8601"
+ durationEncoder: "seconds"
+ callerEncoder: "short"
+ nameEncoder: ""
+
+outputPaths:
+ - "stderr"
+errorOutputPaths:
+ - "stderr"
+initialFields:
diff --git a/filter/impl/active_filter.go b/filter/impl/active_filter.go
index d7dad74..36a4e1a 100644
--- a/filter/impl/active_filter.go
+++ b/filter/impl/active_filter.go
@@ -15,7 +15,6 @@
* limitations under the License.
*/
-// @author yiji@apache.org
package impl
import (
diff --git a/filter/impl/echo_filter.go b/filter/impl/echo_filter.go
index 5eb5a37..18e42c8 100644
--- a/filter/impl/echo_filter.go
+++ b/filter/impl/echo_filter.go
@@ -43,7 +43,8 @@
logger.Debugf("%v,%v", invocation.MethodName(), len(invocation.Arguments()))
if invocation.MethodName() == constant.ECHO && len(invocation.Arguments()) == 1 {
return &protocol.RPCResult{
- Rest: invocation.Arguments()[0],
+ Rest: invocation.Arguments()[0],
+ Attrs: invocation.Attachments(),
}
}
diff --git a/filter/impl/generic_filter.go b/filter/impl/generic_filter.go
index 12cb4c7..35aadb1 100644
--- a/filter/impl/generic_filter.go
+++ b/filter/impl/generic_filter.go
@@ -83,11 +83,7 @@
if t.Kind() == reflect.Struct {
result := make(map[string]interface{}, t.NumField())
for i := 0; i < t.NumField(); i++ {
- if v.Field(i).Kind() == reflect.Struct {
- if v.Field(i).CanInterface() {
- setInMap(result, t.Field(i), struct2MapAll(v.Field(i).Interface()))
- }
- } else if v.Field(i).Kind() == reflect.Slice {
+ if v.Field(i).Kind() == reflect.Struct || v.Field(i).Kind() == reflect.Slice || v.Field(i).Kind() == reflect.Map {
if v.Field(i).CanInterface() {
setInMap(result, t.Field(i), struct2MapAll(v.Field(i).Interface()))
}
@@ -106,6 +102,18 @@
newTemps = append(newTemps, newTemp)
}
return newTemps
+ } else if t.Kind() == reflect.Map {
+ var newTempMap = make(map[string]interface{}, v.Len())
+ iter := v.MapRange()
+ for iter.Next() {
+ mapK := iter.Key().String()
+ if !iter.Value().CanInterface() {
+ continue
+ }
+ mapV := iter.Value().Interface()
+ newTempMap[mapK] = struct2MapAll(mapV)
+ }
+ return newTempMap
} else {
return obj
}
diff --git a/filter/impl/generic_filter_test.go b/filter/impl/generic_filter_test.go
index a71a9db..9797c40 100644
--- a/filter/impl/generic_filter_test.go
+++ b/filter/impl/generic_filter_test.go
@@ -87,3 +87,35 @@
assert.Equal(t, reflect.Slice, reflect.TypeOf(m["caCa"]).Kind())
assert.Equal(t, reflect.Map, reflect.TypeOf(m["caCa"].([]interface{})[0].(map[string]interface{})["xxYy"]).Kind())
}
+func Test_struct2MapAll_Map(t *testing.T) {
+ var testData struct {
+ AaAa string
+ Baba map[string]interface{}
+ CaCa map[string]string
+ DdDd map[string]interface{}
+ }
+ testData.AaAa = "aaaa"
+ testData.Baba = make(map[string]interface{})
+ testData.CaCa = make(map[string]string)
+ testData.DdDd = nil
+
+ testData.Baba["kk"] = 1
+ var structData struct {
+ Str string
+ }
+ structData.Str = "str"
+ testData.Baba["struct"] = structData
+ testData.Baba["nil"] = nil
+ testData.CaCa["k1"] = "v1"
+ testData.CaCa["kv2"] = "v2"
+ m := struct2MapAll(testData)
+
+ assert.Equal(t, reflect.Map, reflect.TypeOf(m).Kind())
+ assert.Equal(t, reflect.String, reflect.TypeOf(m.(map[string]interface{})["aaAa"]).Kind())
+ assert.Equal(t, reflect.Map, reflect.TypeOf(m.(map[string]interface{})["baba"]).Kind())
+ assert.Equal(t, reflect.Map, reflect.TypeOf(m.(map[string]interface{})["baba"].(map[string]interface{})["struct"]).Kind())
+ assert.Equal(t, "str", m.(map[string]interface{})["baba"].(map[string]interface{})["struct"].(map[string]interface{})["str"])
+ assert.Equal(t, nil, m.(map[string]interface{})["baba"].(map[string]interface{})["nil"])
+ assert.Equal(t, reflect.Map, reflect.TypeOf(m.(map[string]interface{})["caCa"]).Kind())
+ assert.Equal(t, reflect.Map, reflect.TypeOf(m.(map[string]interface{})["ddDd"]).Kind())
+}
diff --git a/filter/impl/hystrix_filter.go b/filter/impl/hystrix_filter.go
new file mode 100644
index 0000000..3fd9f87
--- /dev/null
+++ b/filter/impl/hystrix_filter.go
@@ -0,0 +1,269 @@
+/*
+ * 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 impl
+
+import (
+ "fmt"
+ "regexp"
+ "sync"
+)
+import (
+ "github.com/afex/hystrix-go/hystrix"
+ perrors "github.com/pkg/errors"
+ "gopkg.in/yaml.v2"
+)
+import (
+ "github.com/apache/dubbo-go/common/extension"
+ "github.com/apache/dubbo-go/common/logger"
+ "github.com/apache/dubbo-go/config"
+ "github.com/apache/dubbo-go/filter"
+ "github.com/apache/dubbo-go/protocol"
+)
+
+const (
+ HYSTRIX_CONSUMER = "hystrix_consumer"
+ HYSTRIX_PROVIDER = "hystrix_provider"
+ HYSTRIX = "hystrix"
+)
+
+var (
+ confConsumer = &HystrixFilterConfig{}
+ confProvider = &HystrixFilterConfig{}
+ configLoadMutex = sync.RWMutex{}
+ consumerConfigOnce sync.Once
+ providerConfigOnce sync.Once
+)
+
+//The filter in the server end of dubbo-go can't get the invoke result for now,
+//this filter ONLY works in CLIENT end (consumer side) temporarily
+//Only after the callService logic is integrated into the filter chain of server end can this filter be used,
+//which will be done soon
+func init() {
+ extension.SetFilter(HYSTRIX_CONSUMER, GetHystrixFilterConsumer)
+ extension.SetFilter(HYSTRIX_PROVIDER, GetHystrixFilterProvider)
+}
+
+type HystrixFilterError struct {
+ err error
+ failByHystrix bool
+}
+
+func (hfError *HystrixFilterError) Error() string {
+ return hfError.err.Error()
+}
+
+func (hfError *HystrixFilterError) FailByHystrix() bool {
+ return hfError.failByHystrix
+}
+func NewHystrixFilterError(err error, failByHystrix bool) error {
+ return &HystrixFilterError{
+ err: err,
+ failByHystrix: failByHystrix,
+ }
+}
+
+type HystrixFilter struct {
+ COrP bool //true for consumer
+ res map[string][]*regexp.Regexp
+ ifNewMap sync.Map
+}
+
+func (hf *HystrixFilter) Invoke(invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
+
+ cmdName := fmt.Sprintf("%s&method=%s", invoker.GetUrl().Key(), invocation.MethodName())
+
+ // Do the configuration if the circuit breaker is created for the first time
+ if _, load := hf.ifNewMap.LoadOrStore(cmdName, true); !load {
+ configLoadMutex.Lock()
+ filterConf := getConfig(invoker.GetUrl().Service(), invocation.MethodName(), hf.COrP)
+ for _, ptn := range filterConf.Error {
+ reg, err := regexp.Compile(ptn)
+ if err != nil {
+ logger.Warnf("[Hystrix Filter]Errors occurred parsing error omit regexp: %s, %v", ptn, err)
+ } else {
+ if hf.res == nil {
+ hf.res = make(map[string][]*regexp.Regexp)
+ }
+ hf.res[invocation.MethodName()] = append(hf.res[invocation.MethodName()], reg)
+ }
+ }
+ hystrix.ConfigureCommand(cmdName, hystrix.CommandConfig{
+ Timeout: filterConf.Timeout,
+ MaxConcurrentRequests: filterConf.MaxConcurrentRequests,
+ SleepWindow: filterConf.SleepWindow,
+ ErrorPercentThreshold: filterConf.ErrorPercentThreshold,
+ RequestVolumeThreshold: filterConf.RequestVolumeThreshold,
+ })
+ configLoadMutex.Unlock()
+ }
+ configLoadMutex.RLock()
+ _, _, err := hystrix.GetCircuit(cmdName)
+ configLoadMutex.RUnlock()
+ if err != nil {
+ logger.Errorf("[Hystrix Filter]Errors occurred getting circuit for %s , will invoke without hystrix, error is: ", cmdName, err)
+ return invoker.Invoke(invocation)
+ }
+ logger.Infof("[Hystrix Filter]Using hystrix filter: %s", cmdName)
+ var result protocol.Result
+ _ = hystrix.Do(cmdName, func() error {
+ result = invoker.Invoke(invocation)
+ err := result.Error()
+ if err != nil {
+ result.SetError(NewHystrixFilterError(err, false))
+ for _, reg := range hf.res[invocation.MethodName()] {
+ if reg.MatchString(err.Error()) {
+ logger.Debugf("[Hystrix Filter]Error in invocation but omitted in circuit breaker: %v; %s", err, cmdName)
+ return nil
+ }
+ }
+ }
+ return err
+ }, func(err error) error {
+ //Return error and if it is caused by hystrix logic, so that it can be handled by previous filters.
+ _, ok := err.(hystrix.CircuitError)
+ logger.Debugf("[Hystrix Filter]Hystrix health check counted, error is: %v, failed by hystrix: %v; %s", err, ok, cmdName)
+ result = &protocol.RPCResult{}
+ result.SetResult(nil)
+ result.SetError(NewHystrixFilterError(err, ok))
+ return err
+ })
+ return result
+}
+
+func (hf *HystrixFilter) OnResponse(result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
+ return result
+}
+func GetHystrixFilterConsumer() filter.Filter {
+ //When first called, load the config in
+ consumerConfigOnce.Do(func() {
+ if err := initHystrixConfigConsumer(); err != nil {
+ logger.Warnf("[Hystrix Filter]Config load failed for consumer, error is: %v , will use default", err)
+ }
+ })
+ return &HystrixFilter{COrP: true}
+}
+
+func GetHystrixFilterProvider() filter.Filter {
+ providerConfigOnce.Do(func() {
+ if err := initHystrixConfigProvider(); err != nil {
+ logger.Warnf("[Hystrix Filter]Config load failed for provider, error is: %v , will use default", err)
+ }
+ })
+ return &HystrixFilter{COrP: false}
+}
+
+func getConfig(service string, method string, cOrP bool) CommandConfigWithError {
+ //Find method level config
+ var conf *HystrixFilterConfig
+ if cOrP {
+ conf = confConsumer
+ } else {
+ conf = confProvider
+ }
+ getConf := conf.Configs[conf.Services[service].Methods[method]]
+ if getConf != nil {
+ logger.Infof("[Hystrix Filter]Found method-level config for %s - %s", service, method)
+ return *getConf
+ }
+ //Find service level config
+ getConf = conf.Configs[conf.Services[service].ServiceConfig]
+ if getConf != nil {
+ logger.Infof("[Hystrix Filter]Found service-level config for %s - %s", service, method)
+ return *getConf
+ }
+ //Find default config
+ getConf = conf.Configs[conf.Default]
+ if getConf != nil {
+ logger.Infof("[Hystrix Filter]Found global default config for %s - %s", service, method)
+ return *getConf
+ }
+ getConf = &CommandConfigWithError{}
+ logger.Infof("[Hystrix Filter]No config found for %s - %s, using default", service, method)
+ return *getConf
+
+}
+
+func initHystrixConfigConsumer() error {
+ if config.GetConsumerConfig().FilterConf == nil {
+ return perrors.Errorf("no config for hystrix")
+ }
+ filterConfig := config.GetConsumerConfig().FilterConf.(map[interface{}]interface{})[HYSTRIX]
+ if filterConfig == nil {
+ return perrors.Errorf("no config for hystrix")
+ }
+ hystrixConfByte, err := yaml.Marshal(filterConfig)
+ if err != nil {
+ return err
+ }
+ err = yaml.Unmarshal(hystrixConfByte, confConsumer)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+func initHystrixConfigProvider() error {
+ if config.GetProviderConfig().FilterConf == nil {
+ return perrors.Errorf("no config for hystrix")
+ }
+ filterConfig := config.GetConsumerConfig().FilterConf.(map[interface{}]interface{})[HYSTRIX]
+ if filterConfig == nil {
+ return perrors.Errorf("no config for hystrix")
+ }
+ hystrixConfByte, err := yaml.Marshal(filterConfig)
+ if err != nil {
+ return err
+ }
+ err = yaml.Unmarshal(hystrixConfByte, confProvider)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+//For sake of dynamic config
+//func RefreshHystrix() error {
+// conf = &HystrixFilterConfig{}
+// hystrix.Flush()
+// return initHystrixConfig()
+//}
+
+type CommandConfigWithError struct {
+ Timeout int `yaml:"timeout"`
+ MaxConcurrentRequests int `yaml:"max_concurrent_requests"`
+ RequestVolumeThreshold int `yaml:"request_volume_threshold"`
+ SleepWindow int `yaml:"sleep_window"`
+ ErrorPercentThreshold int `yaml:"error_percent_threshold"`
+ Error []string `yaml:"error_whitelist"`
+}
+
+//Config:
+//- Timeout: how long to wait for command to complete, in milliseconds
+//- MaxConcurrentRequests: how many commands of the same type can run at the same time
+//- RequestVolumeThreshold: the minimum number of requests needed before a circuit can be tripped due to health
+//- SleepWindow: how long, in milliseconds, to wait after a circuit opens before testing for recovery
+//- ErrorPercentThreshold: it causes circuits to open once the rolling measure of errors exceeds this percent of requests
+//See hystrix doc
+
+type HystrixFilterConfig struct {
+ Configs map[string]*CommandConfigWithError
+ Default string
+ Services map[string]ServiceHystrixConfig
+}
+type ServiceHystrixConfig struct {
+ ServiceConfig string `yaml:"service_config"`
+ Methods map[string]string
+}
diff --git a/filter/impl/hystrix_filter_test.go b/filter/impl/hystrix_filter_test.go
new file mode 100644
index 0000000..d3a5183
--- /dev/null
+++ b/filter/impl/hystrix_filter_test.go
@@ -0,0 +1,217 @@
+/*
+ * 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 impl
+
+import (
+ "regexp"
+ "testing"
+)
+import (
+ "github.com/afex/hystrix-go/hystrix"
+ "github.com/pkg/errors"
+ "github.com/stretchr/testify/assert"
+)
+import (
+ "github.com/apache/dubbo-go/protocol"
+ "github.com/apache/dubbo-go/protocol/invocation"
+)
+
+func init() {
+ mockInitHystrixConfig()
+}
+
+func TestNewHystrixFilterError(t *testing.T) {
+ get := NewHystrixFilterError(errors.New("test"), true)
+ assert.True(t, get.(*HystrixFilterError).FailByHystrix())
+ assert.Equal(t, "test", get.Error())
+}
+
+func mockInitHystrixConfig() {
+ //Mock config
+ confConsumer = &HystrixFilterConfig{
+ make(map[string]*CommandConfigWithError),
+ "Default",
+ make(map[string]ServiceHystrixConfig),
+ }
+ confConsumer.Configs["Default"] = &CommandConfigWithError{
+ Timeout: 1000,
+ MaxConcurrentRequests: 600,
+ RequestVolumeThreshold: 5,
+ SleepWindow: 5000,
+ ErrorPercentThreshold: 5,
+ Error: nil,
+ }
+ confConsumer.Configs["userp"] = &CommandConfigWithError{
+ Timeout: 2000,
+ MaxConcurrentRequests: 64,
+ RequestVolumeThreshold: 15,
+ SleepWindow: 4000,
+ ErrorPercentThreshold: 45,
+ Error: nil,
+ }
+ confConsumer.Configs["userp_m"] = &CommandConfigWithError{
+ Timeout: 1200,
+ MaxConcurrentRequests: 64,
+ RequestVolumeThreshold: 5,
+ SleepWindow: 6000,
+ ErrorPercentThreshold: 60,
+ Error: []string{
+ "exception",
+ },
+ }
+ confConsumer.Services["com.ikurento.user.UserProvider"] = ServiceHystrixConfig{
+ "userp",
+ map[string]string{
+ "GetUser": "userp_m",
+ },
+ }
+
+}
+
+func TestGetHystrixFilter(t *testing.T) {
+ filterGot := GetHystrixFilterConsumer()
+ assert.NotNil(t, filterGot)
+}
+
+func TestGetConfig_1(t *testing.T) {
+ mockInitHystrixConfig()
+ configGot := getConfig("com.ikurento.user.UserProvider", "GetUser", true)
+ assert.NotNil(t, configGot)
+ assert.Equal(t, 1200, configGot.Timeout)
+ assert.Equal(t, 64, configGot.MaxConcurrentRequests)
+ assert.Equal(t, 6000, configGot.SleepWindow)
+ assert.Equal(t, 60, configGot.ErrorPercentThreshold)
+ assert.Equal(t, 5, configGot.RequestVolumeThreshold)
+}
+
+func TestGetConfig_2(t *testing.T) {
+ mockInitHystrixConfig()
+ configGot := getConfig("com.ikurento.user.UserProvider", "GetUser0", true)
+ assert.NotNil(t, configGot)
+ assert.Equal(t, 2000, configGot.Timeout)
+ assert.Equal(t, 64, configGot.MaxConcurrentRequests)
+ assert.Equal(t, 4000, configGot.SleepWindow)
+ assert.Equal(t, 45, configGot.ErrorPercentThreshold)
+ assert.Equal(t, 15, configGot.RequestVolumeThreshold)
+}
+
+func TestGetConfig_3(t *testing.T) {
+ mockInitHystrixConfig()
+ //This should use default
+ configGot := getConfig("Mock.Service", "GetMock", true)
+ assert.NotNil(t, configGot)
+ assert.Equal(t, 1000, configGot.Timeout)
+ assert.Equal(t, 600, configGot.MaxConcurrentRequests)
+ assert.Equal(t, 5000, configGot.SleepWindow)
+ assert.Equal(t, 5, configGot.ErrorPercentThreshold)
+ assert.Equal(t, 5, configGot.RequestVolumeThreshold)
+}
+
+type testMockSuccessInvoker struct {
+ protocol.BaseInvoker
+}
+
+func (iv *testMockSuccessInvoker) Invoke(invocation protocol.Invocation) protocol.Result {
+ return &protocol.RPCResult{
+ Rest: "Sucess",
+ Err: nil,
+ }
+}
+
+type testMockFailInvoker struct {
+ protocol.BaseInvoker
+}
+
+func (iv *testMockFailInvoker) Invoke(invocation protocol.Invocation) protocol.Result {
+ return &protocol.RPCResult{
+ Err: errors.Errorf("exception"),
+ }
+}
+
+func TestHystrixFilter_Invoke_Success(t *testing.T) {
+ hf := &HystrixFilter{}
+ result := hf.Invoke(&testMockSuccessInvoker{}, &invocation.RPCInvocation{})
+ assert.NotNil(t, result)
+ assert.NoError(t, result.Error())
+ assert.NotNil(t, result.Result())
+}
+
+func TestHystrixFilter_Invoke_Fail(t *testing.T) {
+ hf := &HystrixFilter{}
+ result := hf.Invoke(&testMockFailInvoker{}, &invocation.RPCInvocation{})
+ assert.NotNil(t, result)
+ assert.Error(t, result.Error())
+}
+
+func TestHystricFilter_Invoke_CircuitBreak(t *testing.T) {
+ mockInitHystrixConfig()
+ hystrix.Flush()
+ hf := &HystrixFilter{COrP: true}
+ resChan := make(chan protocol.Result, 50)
+ for i := 0; i < 50; i++ {
+ go func() {
+ result := hf.Invoke(&testMockFailInvoker{}, &invocation.RPCInvocation{})
+ resChan <- result
+ }()
+ }
+ //This can not always pass the test when on travis due to concurrency, you can uncomment the code below and test it locally
+
+ //var lastRest bool
+ //for i := 0; i < 50; i++ {
+ // lastRest = (<-resChan).Error().(*HystrixFilterError).FailByHystrix()
+ //}
+ //Normally the last result should be true, which means the circuit has been opened
+ //
+ //assert.True(t, lastRest)
+
+}
+
+func TestHystricFilter_Invoke_CircuitBreak_Omit_Exception(t *testing.T) {
+ mockInitHystrixConfig()
+ hystrix.Flush()
+ reg, _ := regexp.Compile(".*exception.*")
+ regs := []*regexp.Regexp{reg}
+ hf := &HystrixFilter{res: map[string][]*regexp.Regexp{"": regs}, COrP: true}
+ resChan := make(chan protocol.Result, 50)
+ for i := 0; i < 50; i++ {
+ go func() {
+ result := hf.Invoke(&testMockFailInvoker{}, &invocation.RPCInvocation{})
+ resChan <- result
+ }()
+ }
+ //This can not always pass the test when on travis due to concurrency, you can uncomment the code below and test it locally
+
+ //time.Sleep(time.Second * 6)
+ //var lastRest bool
+ //for i := 0; i < 50; i++ {
+ // lastRest = (<-resChan).Error().(*HystrixFilterError).FailByHystrix()
+ //}
+ //
+ //assert.False(t, lastRest)
+
+}
+
+func TestGetHystrixFilterConsumer(t *testing.T) {
+ get := GetHystrixFilterConsumer()
+ assert.NotNil(t, get)
+ assert.True(t, get.(*HystrixFilter).COrP)
+}
+func TestGetHystrixFilterProvider(t *testing.T) {
+ get := GetHystrixFilterProvider()
+ assert.NotNil(t, get)
+ assert.False(t, get.(*HystrixFilter).COrP)
+}
diff --git a/filter/impl/token_filter.go b/filter/impl/token_filter.go
new file mode 100644
index 0000000..d10dff5
--- /dev/null
+++ b/filter/impl/token_filter.go
@@ -0,0 +1,66 @@
+/*
+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 impl
+
+import (
+ "strings"
+)
+
+import (
+ perrors "github.com/pkg/errors"
+)
+
+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"
+)
+
+const (
+ TOKEN = "token"
+)
+
+func init() {
+ extension.SetFilter(TOKEN, GetTokenFilter)
+}
+
+type TokenFilter struct{}
+
+func (tf *TokenFilter) Invoke(invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
+ invokerTkn := invoker.GetUrl().GetParam(constant.TOKEN_KEY, "")
+ if len(invokerTkn) > 0 {
+ attachs := invocation.Attachments()
+ remoteTkn, exist := attachs[constant.TOKEN_KEY]
+ if exist && strings.EqualFold(invokerTkn, remoteTkn) {
+ return invoker.Invoke(invocation)
+ }
+ return &protocol.RPCResult{Err: perrors.Errorf("Invalid token! Forbid invoke remote service %v method %s ",
+ invoker, invocation.MethodName())}
+ }
+
+ return invoker.Invoke(invocation)
+}
+
+func (tf *TokenFilter) OnResponse(result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
+ return result
+}
+
+func GetTokenFilter() filter.Filter {
+ return &TokenFilter{}
+}
diff --git a/filter/impl/token_filter_test.go b/filter/impl/token_filter_test.go
new file mode 100644
index 0000000..1473f27
--- /dev/null
+++ b/filter/impl/token_filter_test.go
@@ -0,0 +1,85 @@
+/*
+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 impl
+
+import (
+ "net/url"
+ "testing"
+)
+
+import (
+ "github.com/stretchr/testify/assert"
+)
+
+import (
+ "github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/common/constant"
+ "github.com/apache/dubbo-go/protocol"
+ "github.com/apache/dubbo-go/protocol/invocation"
+)
+
+func TestTokenFilter_Invoke(t *testing.T) {
+ filter := GetTokenFilter()
+
+ url := common.NewURLWithOptions(
+ common.WithParams(url.Values{}),
+ common.WithParamsValue(constant.TOKEN_KEY, "ori_key"))
+ attch := make(map[string]string, 0)
+ attch[constant.TOKEN_KEY] = "ori_key"
+ result := filter.Invoke(protocol.NewBaseInvoker(*url),
+ invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, attch))
+ assert.Nil(t, result.Error())
+ assert.Nil(t, result.Result())
+}
+
+func TestTokenFilter_InvokeEmptyToken(t *testing.T) {
+ filter := GetTokenFilter()
+
+ url := common.URL{}
+ attch := make(map[string]string, 0)
+ attch[constant.TOKEN_KEY] = "ori_key"
+ result := filter.Invoke(protocol.NewBaseInvoker(url),
+ invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, attch))
+ assert.Nil(t, result.Error())
+ assert.Nil(t, result.Result())
+}
+
+func TestTokenFilter_InvokeEmptyAttach(t *testing.T) {
+ filter := GetTokenFilter()
+
+ url := common.NewURLWithOptions(
+ common.WithParams(url.Values{}),
+ common.WithParamsValue(constant.TOKEN_KEY, "ori_key"))
+ attch := make(map[string]string, 0)
+ result := filter.Invoke(protocol.NewBaseInvoker(*url),
+ invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, attch))
+ assert.NotNil(t, result.Error())
+}
+
+func TestTokenFilter_InvokeNotEqual(t *testing.T) {
+ filter := GetTokenFilter()
+
+ url := common.NewURLWithOptions(
+ common.WithParams(url.Values{}),
+ common.WithParamsValue(constant.TOKEN_KEY, "ori_key"))
+ attch := make(map[string]string, 0)
+ attch[constant.TOKEN_KEY] = "err_key"
+ result := filter.Invoke(protocol.NewBaseInvoker(*url),
+ invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, attch))
+ assert.NotNil(t, result.Error())
+}
diff --git a/go.mod b/go.mod
index 8ced5e0..09948c9 100644
--- a/go.mod
+++ b/go.mod
@@ -2,37 +2,41 @@
require (
github.com/Workiva/go-datastructures v1.0.50
+ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e // indirect
- github.com/apache/dubbo-go-hessian2 v1.2.5-0.20190731020727-1697039810c8
+ github.com/apache/dubbo-go-hessian2 v1.2.5-0.20190909140437-80cbb25cbb22
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 // indirect
github.com/coreos/bbolt v1.3.3 // indirect
github.com/coreos/etcd v3.3.13+incompatible
github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
- github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
+ github.com/creasty/defaults v1.3.0
github.com/dubbogo/getty v1.2.2
github.com/dubbogo/gost v1.1.1
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
github.com/go-errors/errors v1.0.1 // indirect
- github.com/gogo/protobuf v1.2.1 // indirect
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect
github.com/golang/mock v1.3.1
github.com/google/btree v1.0.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.9.5 // indirect
+ github.com/hashicorp/consul v1.5.3
+ github.com/hashicorp/consul/api v1.1.0
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
+ github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8
github.com/jonboulle/clockwork v0.1.0 // indirect
github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 // indirect
github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f // indirect
github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 // indirect
github.com/magiconair/properties v1.8.1
- github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/nacos-group/nacos-sdk-go v0.0.0-20190723125407-0242d42e3dbb
github.com/pkg/errors v0.8.1
github.com/prometheus/client_golang v1.1.0 // indirect
github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec
+ github.com/satori/go.uuid v1.2.0
+ github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945 // indirect
github.com/soheilhy/cmux v0.1.4 // indirect
github.com/stretchr/testify v1.3.0
github.com/tebeka/strftime v0.1.3 // indirect
diff --git a/go.sum b/go.sum
index dd8fc7a..1452a76 100644
--- a/go.sum
+++ b/go.sum
@@ -1,22 +1,79 @@
+cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/Azure/azure-sdk-for-go v16.0.0+incompatible h1:gr1qKY/Ll72VjFTZmaBwRK1yQHAxCnV25ekOKroc9ws=
+github.com/Azure/azure-sdk-for-go v16.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
+github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
+github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
+github.com/Azure/go-autorest v10.7.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
+github.com/Azure/go-autorest v10.15.3+incompatible h1:nhKI/bvazIs3C3TFGoSqKY6hZ8f5od5mb5/UcS6HVIY=
+github.com/Azure/go-autorest v10.15.3+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/DataDog/datadog-go v2.2.0+incompatible h1:V5BKkxACZLjzHjSgBbr2gvLA2Ae49yhc6CSY7MLy5k4=
+github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
+github.com/Jeffail/gabs v1.1.0 h1:kw5zCcl9tlJNHTDme7qbi21fDHZmXrnjMoXos3Jw/NI=
+github.com/Jeffail/gabs v1.1.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
+github.com/Microsoft/go-winio v0.4.3 h1:M3NHMuPgMSUPdE5epwNUHlRPSVzHs8HpRTrVXhR0myo=
+github.com/Microsoft/go-winio v0.4.3/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
+github.com/NYTimes/gziphandler v1.0.1 h1:iLrQrdwjDd52kHDA5op2UBJFjmOb9g+7scBan4RN8F0=
+github.com/NYTimes/gziphandler v1.0.1/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
+github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
+github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
+github.com/SAP/go-hdb v0.12.0 h1:5hBQZ2jjyZ268qjDmoDZJuCyLzR6oRLI60eYzmTW9m4=
+github.com/SAP/go-hdb v0.12.0/go.mod h1:etBT+FAi1t5k3K3tf5vQTnosgYmhDkRi8jEnQqCnxF0=
+github.com/SermoDigital/jose v0.0.0-20180104203859-803625baeddc h1:LkkwnbY+S8WmwkWq1SVyRWMH9nYWO1P5XN3OD1tts/w=
+github.com/SermoDigital/jose v0.0.0-20180104203859-803625baeddc/go.mod h1:ARgCUhI1MHQH+ONky/PAtmVHQrP5JlGY0F3poXOp/fA=
+github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
+github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/Workiva/go-datastructures v1.0.50 h1:slDmfW6KCHcC7U+LP3DDBbm4fqTwZGn1beOFPfGaLvo=
github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA=
+github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KMJuWmfCkcxl09JwdlqwDZZ6U14=
+github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw=
+github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 h1:rFw4nCn9iMW+Vajsk51NtYIcwSTkXr+JGrMd36kTDJw=
+github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e h1:MSuLXx/mveDbpDNhVrcWTMeV4lbYWKcyO4rH+jAxmX0=
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ=
github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
-github.com/apache/dubbo-go-hessian2 v1.2.5-0.20190731020727-1697039810c8 h1:7zJlM+8bpCAUhv03TZnXkT4MLlLWng1s7An8CLuN73E=
-github.com/apache/dubbo-go-hessian2 v1.2.5-0.20190731020727-1697039810c8/go.mod h1:LWnndnrFXZmJLAzoyNAPNHSIJ1KOHVkTSsHgC3YYWlo=
+github.com/apache/dubbo-go-hessian2 v1.2.5-0.20190909140437-80cbb25cbb22 h1:Ku+3LFRYVelgo/INS9893QOUeIiKNeNKzK3CzDcqt/4=
+github.com/apache/dubbo-go-hessian2 v1.2.5-0.20190909140437-80cbb25cbb22/go.mod h1:LWnndnrFXZmJLAzoyNAPNHSIJ1KOHVkTSsHgC3YYWlo=
+github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA=
+github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
+github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
+github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM=
+github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg=
+github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to=
+github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/asaskevich/govalidator v0.0.0-20180319081651-7d2e70ef918f h1:/8NcnxL60YFll4ehCwibKotx0BR9v2ND40fomga8qDs=
+github.com/asaskevich/govalidator v0.0.0-20180319081651-7d2e70ef918f/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
+github.com/aws/aws-sdk-go v1.15.24 h1:xLAdTA/ore6xdPAljzZRed7IGqQgC+nY+ERS5vaj4Ro=
+github.com/aws/aws-sdk-go v1.15.24/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
+github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
+github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY=
+github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
+github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
+github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
+github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
+github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 h1:D21IyuvjDCshj1/qq+pCNd3VZOAEI9jy6Bi131YlXgI=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
+github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY=
+github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
+github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY=
+github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
+github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj7ug5D7I/orNUA=
+github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/containerd/continuity v0.0.0-20181203112020-004b46473808 h1:4BX8f882bXEDKfWIf0wa8HRvpnBoPszJJXL+TVbBw4M=
+github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
+github.com/coredns/coredns v1.1.2 h1:bAFHrSsBeTeRG5W3Nf2su3lUGw7Npw2UKeCJm/3A638=
+github.com/coredns/coredns v1.1.2/go.mod h1:zASH/MVDgR6XZTbxvOnsZfffS+31vg6Ackf/wo1+AM0=
github.com/coreos/bbolt v1.3.3 h1:n6AiVyVRKQFNb6mJlwESEvvLoDyiTzXX7ORAUlkeBdY=
github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3q1JMazcgBQ=
@@ -27,25 +84,65 @@
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
+github.com/creasty/defaults v1.3.0 h1:uG+RAxYbJgOPCOdKEcec9ZJXeva7Y6mj/8egdzwmLtw=
+github.com/creasty/defaults v1.3.0/go.mod h1:CIEEvs7oIVZm30R8VxtFJs+4k201gReYyuYHJxZc68I=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/denisenkom/go-mssqldb v0.0.0-20180620032804-94c9c97e8c9f h1:JtRnQbMXb3TcSIm1j452zI45lPMiAQ0puF8iK5EnY9M=
+github.com/denisenkom/go-mssqldb v0.0.0-20180620032804-94c9c97e8c9f/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
+github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661 h1:lrWnAyy/F72MbxIxFUzKmcMCdt9Oi8RzpAxzTNQHD7o=
+github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/digitalocean/godo v1.1.1/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU=
+github.com/digitalocean/godo v1.10.0 h1:uW1/FcvZE/hoixnJcnlmIUvTVNdZCLjRLzmDtRi1xXY=
+github.com/digitalocean/godo v1.10.0/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU=
+github.com/docker/go-connections v0.3.0 h1:3lOnM9cSzgGwx8VfK/NGOW5fLQ0GjIlCkaktF+n1M6o=
+github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
+github.com/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk=
+github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dubbogo/getty v1.2.2 h1:qDC9WXjxcs5NPvWZz2ruVKBKr2r1Jjm6i0Sq//CQwbE=
github.com/dubbogo/getty v1.2.2/go.mod h1:K4b3MkGLf7T+lMgQNFgpg0dI1Wvv1PTisFs1Psf86kU=
github.com/dubbogo/gost v1.1.1 h1:JCM7vx5edPIjDA5ovJTuzEEXuw2t7xLyrlgi2mi5jHI=
github.com/dubbogo/gost v1.1.1/go.mod h1:R7wZm1DrmrKGr50mBZVcg6C9ekG8aL5hP+sgWcIDwQg=
+github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74 h1:2MIhn2R6oXQbgW5yHfS+d6YqyMfXiu2L55rFZC4UD/M=
+github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74/go.mod h1:UqXY1lYT/ERa4OEAywUqdok1T4RCRdArkhic1Opuavo=
+github.com/elazarl/go-bindata-assetfs v0.0.0-20160803192304-e1a2a7ec64b0 h1:ZoRgc53qJCfSLimXqJDrmBhnt5GChDsExMCK7t48o0Y=
+github.com/elazarl/go-bindata-assetfs v0.0.0-20160803192304-e1a2a7ec64b0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
+github.com/envoyproxy/go-control-plane v0.8.0 h1:uE6Fp4fOcAJdc1wTQXLJ+SYistkbG1dNoi6Zs1+Ybvk=
+github.com/envoyproxy/go-control-plane v0.8.0/go.mod h1:GSSbY9P1neVhdY7G4wu+IK1rk/dqhiCC/4ExuWJZVuk=
+github.com/envoyproxy/protoc-gen-validate v0.0.14 h1:YBW6/cKy9prEGRYLnaGa4IDhzxZhRCtKsax8srGKDnM=
+github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 h1:Ghm4eQYC0nEPnSJdVkTrXpu9KtoVCSo1hg7mtI7G9KU=
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw=
+github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
+github.com/fatih/structs v0.0.0-20180123065059-ebf56d35bba7 h1:bGT+Ub6bpzHl7AAYQhBrZ5nYTAH2SF/848WducU0Ao4=
+github.com/fatih/structs v0.0.0-20180123065059-ebf56d35bba7/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
+github.com/go-ini/ini v1.25.4 h1:Mujh4R/dH6YL8bxuISne3xX2+qcQ9p0IxKAP6ExWoUo=
+github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-ldap/ldap v3.0.2+incompatible h1:kD5HQcAzlQ7yrhfn+h+MSABeAy/jAJhvIJ/QDllP44g=
+github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
+github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
+github.com/go-sql-driver/mysql v0.0.0-20180618115901-749ddf1598b4 h1:1LlmVz15APoKz9dnm5j2ePptburJlwEH+/v/pUuoxck=
+github.com/go-sql-driver/mysql v0.0.0-20180618115901-749ddf1598b4/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw=
+github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
+github.com/gocql/gocql v0.0.0-20180617115710-e06f8c1bcd78 h1:G7iRamCffNivybfZvsJjtk3k2qHa73xW+OysVkukcGk=
+github.com/gocql/gocql v0.0.0-20180617115710-e06f8c1bcd78/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0=
+github.com/gogo/googleapis v1.1.0 h1:kFkMAZBNAn4j7K0GiZr8cRYzejq68VbheufiV3YuyFI=
+github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
@@ -61,36 +158,147 @@
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
+github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
+github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 h1:zLTLjkaOFEFIOxY5BWLFLwh+cL8vOBW4XJ2aqLE/Tf0=
+github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
+github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
+github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g=
+github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
+github.com/gophercloud/gophercloud v0.0.0-20180828235145-f29afc2cceca h1:wobTb8SE189AuxzEKClyYxiI4nUGWlpVtl13eLiFlOE=
+github.com/gophercloud/gophercloud v0.0.0-20180828235145-f29afc2cceca/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4=
+github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
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/gotestyourself/gotestyourself v2.2.0+incompatible h1:1yOKgt0XYKUg1HOKunGOSt2ocU4bxLCjmIHt0vRtVHM=
+github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
+github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
+github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
+github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
+github.com/hashicorp/consul v1.5.3 h1:EmTWRf/cuqZk6Ug9tgFUVE9xNgJPpmBvJwJMvm+agSk=
+github.com/hashicorp/consul v1.5.3/go.mod h1:61E2GJCPEP3oq8La7sfDdWGQ66+Zbxzw5ecOdFD7xIE=
+github.com/hashicorp/consul/api v1.1.0 h1:BNQPM9ytxj6jbjjdRPioQ94T6YXriSopn0i8COv6SRA=
+github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
+github.com/hashicorp/consul/sdk v0.1.1 h1:LnuDWGNsoajlhGyHJvuWW6FVqRl8JOTPqS6CPTsYjhY=
+github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-bexpr v0.1.0 h1:hA/9CWGPsQ6YZXvPvizD+VEEjBG4V6Un0Qcyav5ghK4=
+github.com/hashicorp/go-bexpr v0.1.0/go.mod h1:ANbpTX1oAql27TZkKVeW8p1w8NTdnyzPe/0qqPCKohU=
+github.com/hashicorp/go-checkpoint v0.0.0-20171009173528-1545e56e46de/go.mod h1:xIwEieBHERyEvaeKF/TcHh1Hu+lxPM+n2vT1+g9I4m4=
+github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
+github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-discover v0.0.0-20190403160810-22221edb15cd h1:SynRxs8h2h7lLSA5py5a3WWkYpImhREtju0CuRd97wc=
+github.com/hashicorp/go-discover v0.0.0-20190403160810-22221edb15cd/go.mod h1:ueUgD9BeIocT7QNuvxSyJyPAM9dfifBcaWmeybb67OY=
+github.com/hashicorp/go-hclog v0.9.1 h1:9PZfAcVEvez4yhLH2TBU64/h/z4xlFI80cWXRrxuKuM=
+github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
+github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
+github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
+github.com/hashicorp/go-memdb v0.0.0-20180223233045-1289e7fffe71 h1:yxxFgVz31vFoKKTtRUNbXLNe4GFnbLKqg+0N7yG42L8=
+github.com/hashicorp/go-memdb v0.0.0-20180223233045-1289e7fffe71/go.mod h1:kbfItVoBJwCfKXDXN4YoAXjxcFVZ7MRrJzyTX6H4giE=
+github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI=
+github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
+github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-plugin v0.0.0-20180331002553-e8d22c780116 h1:Y4V/yReWjQo/Ngyc0w6C3EKXKincp4YgvXeo8lI4LrI=
+github.com/hashicorp/go-plugin v0.0.0-20180331002553-e8d22c780116/go.mod h1:JSqWYsict+jzcj0+xElxyrBQRPNoiWQuddnxArJ7XHQ=
+github.com/hashicorp/go-raftchunking v0.6.1 h1:moEnaG3gcwsWNyIBJoD5PCByE+Ewkqxh6N05CT+MbwA=
+github.com/hashicorp/go-raftchunking v0.6.1/go.mod h1:cGlg3JtDy7qy6c/3Bu660Mic1JF+7lWqIwCFSb08fX0=
+github.com/hashicorp/go-retryablehttp v0.5.3 h1:QlWt0KvWT0lq8MFppF9tsJGF+ynG7ztc2KIPhzRGk7s=
+github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
+github.com/hashicorp/go-rootcerts v1.0.0 h1:Rqb66Oo1X/eSV1x66xbDccZjhJigjg0+e82kpwzSwCI=
+github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
+github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs=
+github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
+github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE=
+github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
+github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE=
+github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-version v0.0.0-20170202080759-03c5bf6be031 h1:c3Xdf5fTpk+hqhxqCO+ymqjfUXV9+GZqNgTtlnVzDos=
+github.com/hashicorp/go-version v0.0.0-20170202080759-03c5bf6be031/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
+github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/hcl v0.0.0-20180906183839-65a6292f0157 h1:PJ+K03hio6ADVjEc6lFu5r866o67xEEMQ73CFdI6R2U=
+github.com/hashicorp/hcl v0.0.0-20180906183839-65a6292f0157/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hashicorp/hil v0.0.0-20160711231837-1e86c6b523c5 h1:uk280DXEbQiCOZgCOI3elFSeNxf8YIZiNsbr2pQLYD0=
+github.com/hashicorp/hil v0.0.0-20160711231837-1e86c6b523c5/go.mod h1:KHvg/R2/dPtaePb16oW4qIyzkMxXOL38xjRN64adsts=
+github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
+github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
+github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
+github.com/hashicorp/mdns v1.0.1 h1:XFSOubp8KWB+Jd2PDyaX5xUd5bhSP/+pTDZVDMzZJM8=
+github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
+github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
+github.com/hashicorp/memberlist v0.1.4 h1:gkyML/r71w3FL8gUi74Vk76avkj/9lYAY9lvg0OcoGs=
+github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
+github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69 h1:lc3c72qGlIMDqQpQH82Y4vaglRMMFdJbziYWriR4UcE=
+github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69/go.mod h1:/z+jUGRBlwVpUZfjute9jWaF6/HuhjuFQuL1YXzVD1Q=
+github.com/hashicorp/raft v1.1.1 h1:HJr7UE1x/JrJSc9Oy6aDBHtNHUUBHjcQjTgvUVihoZs=
+github.com/hashicorp/raft v1.1.1/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8=
+github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea h1:xykPFhrBAS2J0VBzVa5e80b5ZtYuNQtgXjN40qBZlD4=
+github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk=
+github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0=
+github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
+github.com/hashicorp/vault v0.10.3 h1:3Hf6mwC4rggOq6ViWSoJ2yfk1oBS5ed58LLcP33gmEg=
+github.com/hashicorp/vault v0.10.3/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bAbosPMpP0=
+github.com/hashicorp/vault-plugin-secrets-kv v0.0.0-20190318174639-195e0e9d07f1 h1:7IvvWArBoSjStPohKqHj3ksXNjcyPsyXYDIhCQw6Vtg=
+github.com/hashicorp/vault-plugin-secrets-kv v0.0.0-20190318174639-195e0e9d07f1/go.mod h1:VJHHT2SC1tAPrfENQeBhLlb5FbZoKZM+oC/ROmEftz0=
+github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443 h1:O/pT5C1Q3mVXMyuqg7yuAWUg/jMZR1/0QTzTRdNR6Uw=
+github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443/go.mod h1:bEpDU35nTu0ey1EXjwNwPjI9xErAsoOCmcMb9GKvyxo=
+github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ=
+github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
+github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
+github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da h1:FjHUJJ7oBW4G/9j1KzlHaXL09LyMVM9rupS39lncbXk=
+github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4=
+github.com/jefferai/jsonx v0.0.0-20160721235117-9cc31c3135ee h1:AQ/QmCk6x8ECPpf2pkPtA4lyncEEBbs8VFnVXPYKhIs=
+github.com/jefferai/jsonx v0.0.0-20160721235117-9cc31c3135ee/go.mod h1:N0t2vlmpe8nyZB5ouIbJQPDSR+mH6oe7xHB9VZHSUzM=
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4=
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag=
+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/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62 h1:JHCT6xuyPUrbbgAPE/3dqlvUKzRHMNuTBKKUb6OeR/k=
+github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62/go.mod h1:U+RSyWxWd04xTqnuOQxnai7XGS2PrPY2cfGoDKtMHjA=
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/keybase/go-crypto v0.0.0-20180614160407-5114a9a81e1b h1:VE6r2OwP5gj+Z9aCkSKl3MlmnZbfMAjhvR5T7abKHEo=
+github.com/keybase/go-crypto v0.0.0-20180614160407-5114a9a81e1b/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
@@ -107,10 +315,36 @@
github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f/go.mod h1:UGmTpUd3rjbtfIpwAPrcfmGf/Z1HS95TATB+m57TPB8=
github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 h1:Bvq8AziQ5jFF4BHGAEDSqwPW1NJS3XshxbRCxtjFAZc=
github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042/go.mod h1:TPpsiPUEh0zFL1Snz4crhMlBe60PYxRHr5oFF3rRYg0=
+github.com/lib/pq v0.0.0-20180523175426-90697d60dd84 h1:it29sI2IM490luSc3RAhp5WuCYnc6RtbfLVAB7nmC5M=
+github.com/lib/pq v0.0.0-20180523175426-90697d60dd84/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
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/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
+github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI=
+github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA=
+github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
+github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y=
+github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
+github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
+github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
+github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0=
+github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
+github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
+github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
+github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 h1:hOY53G+kBFhbYFpRVxHl5eS7laP6B1+Cq+Z9Dry1iMU=
+github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
+github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
+github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE=
+github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -120,49 +354,105 @@
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nacos-group/nacos-sdk-go v0.0.0-20190723125407-0242d42e3dbb h1:lbmvw8r9W55w+aQgWn35W1nuleRIECMoqUrmwAOAvoI=
github.com/nacos-group/nacos-sdk-go v0.0.0-20190723125407-0242d42e3dbb/go.mod h1:CEkSvEpoveoYjA81m4HNeYQ0sge0LFGKSEqO3JKHllo=
+github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s=
+github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk=
+github.com/oklog/run v0.0.0-20180308005104-6934b124db28 h1:Hbr3fbVPXea52oPQeP7KLSxP52g6SFaNY1IqAmUyEW0=
+github.com/oklog/run v0.0.0-20180308005104-6934b124db28/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
+github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
+github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
+github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
+github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
+github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y=
+github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
+github.com/ory/dockertest v3.3.4+incompatible h1:VrpM6Gqg7CrPm3bL4Wm1skO+zFWLbh7/Xb5kGEbJRh8=
+github.com/ory/dockertest v3.3.4+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
+github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c h1:vwpFWvAO8DeIZfFeqASzZfsxuWPno9ncAebBEP0N3uE=
+github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c/go.mod h1:otzZQXgoO96RTzDB/Hycg0qZcXZsWJGJRSXbmEIJ+4M=
+github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
+github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/patrickmn/go-cache v0.0.0-20180527043350-9f6ff22cfff8 h1:BR6MM54q4W9pn0SySwg6yctZtBKlTdUq6a+b0kArBnE=
+github.com/patrickmn/go-cache v0.0.0-20180527043350-9f6ff22cfff8/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
+github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
+github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w=
+github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb0+HxJfRI8=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.3 h1:CTwfnzjQ+8dS6MhHHu4YswVAD99sL2wjPqP+VkURmKE=
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
+github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 h1:Wdi9nwnhFNAlseAOekn6B5G/+GMtks9UKbvRU/CMM/o=
+github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03/go.mod h1:gRAiPF5C5Nd0eyyRdqIu9qTiFSoZzpTq727b5B8fkkU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 h1:7YvPJVmEeFHR1Tj9sZEYsmarJEQfMVYpd/Vyy/A8dqE=
+github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec h1:6ncX5ko6B9LntYM0YBRXkiSaZMmLYeZ/NWcmeB43mMY=
github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
+github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
+github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
+github.com/shirou/gopsutil v0.0.0-20181107111621-48177ef5f880 h1:1Ge4j/3uB2rxzPWD3TC+daeCw+w91z8UCUL/7WH5gn8=
+github.com/shirou/gopsutil v0.0.0-20181107111621-48177ef5f880/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
+github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U=
+github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
+github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945 h1:N8Bg45zpk/UcpNGnfJt2y/3lRWASHNTUET8owPYCgYI=
+github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d h1:bVQRCxQvfjNUeRqaY/uT0tFuvuFY0ulgnczuR684Xic=
+github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d/go.mod h1:Cw4GTlQccdRGSEf6KiMju767x0NEHE0YIVPJSaXjlsw=
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/tebeka/strftime v0.1.3 h1:5HQXOqWKYRFfNyBMNVc9z5+QzuBtIXy03psIhtdJYto=
github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ=
+github.com/tent/http-link-go v0.0.0-20130702225549-ac974c61c2f9/go.mod h1:RHkNRtSLfOK7qBTHaeSX1D6BNpI3qw7NTxsmNr4RvN8=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 h1:kF/7m/ZU+0D4Jj5eZ41Zm3IH/J8OElK1Qtd7tVKAwLk=
github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3/go.mod h1:QDlpd3qS71vYtakd2hmdpqhJ9nwv6mD6A30bQ1BPBFE=
+github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8=
+github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
+github.com/vmware/govmomi v0.18.0 h1:f7QxSmP7meCtoAmiKZogvVbLInT+CZx6Px6K5rYsJZo=
+github.com/vmware/govmomi v0.18.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
@@ -176,55 +466,103 @@
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
+golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/oauth2 v0.0.0-20170807180024-9a379c6b3e95/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190508220229-2d0786266e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 h1:4y9KwBHBgBNwDbtu44R5o1fdOCQUEXhbk/P4A9WmJq0=
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+google.golang.org/api v0.0.0-20180829000535-087779f1d2c9 h1:z1TeLUmxf9ws9KLICfmX+KGXTs+rjm+aGWzfsv7MZ9w=
+google.golang.org/api v0.0.0-20180829000535-087779f1d2c9/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
+google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.22.1 h1:/7cs52RnTJmD43s3uxzlq2U7nqVTd/37viQwMrMNlOM=
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM=
+gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
+gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
+gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk=
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/mgo.v2 v2.0.0-20160818020120-3f83fa500528 h1:/saqWwm73dLmuzbNhe92F0QsZ/KiFND+esHco2v1hiY=
+gopkg.in/mgo.v2 v2.0.0-20160818020120-3f83fa500528/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
+gopkg.in/ory-am/dockertest.v3 v3.3.4 h1:oen8RiwxVNxtQ1pRoV4e4jqh6UjNsOuIZ1NXns6jdcw=
+gopkg.in/ory-am/dockertest.v3 v3.3.4/go.mod h1:s9mmoLkaGeAh97qygnNj4xWkiN7e1SKekYC6CovU+ek=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
+gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4=
+gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gotest.tools v2.2.0+incompatible h1:y0IMTfclpMdsdIbr6uwmJn5/WZ7vFuObxDMdrylFM3A=
+gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+istio.io/gogo-genproto v0.0.0-20190124151557-6d926a6e6feb/go.mod h1:eIDJ6jNk/IeJz6ODSksHl5Aiczy5JUq6vFhJWI5OtiI=
+k8s.io/api v0.0.0-20180806132203-61b11ee65332/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
+k8s.io/api v0.0.0-20190325185214-7544f9db76f6 h1:9MWtbqhwTyDvF4cS1qAhxDb9Mi8taXiAu+5nEacl7gY=
+k8s.io/api v0.0.0-20190325185214-7544f9db76f6/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
+k8s.io/apimachinery v0.0.0-20180821005732-488889b0007f/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
+k8s.io/apimachinery v0.0.0-20190223001710-c182ff3b9841 h1:Q4RZrHNtlC/mSdC1sTrcZ5RchC/9vxLVj57pWiCBKv4=
+k8s.io/apimachinery v0.0.0-20190223001710-c182ff3b9841/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
+k8s.io/client-go v8.0.0+incompatible h1:tTI4hRmb1DRMl4fG6Vclfdi6nTM82oIrTT7HfitmxC4=
+k8s.io/client-go v8.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
diff --git a/protocol/dubbo/client.go b/protocol/dubbo/client.go
index 6ac5e72..4927f51 100644
--- a/protocol/dubbo/client.go
+++ b/protocol/dubbo/client.go
@@ -59,7 +59,7 @@
return
}
dubboConf := protocolConf.(map[interface{}]interface{})[DUBBO]
- if protocolConf == nil {
+ if dubboConf == nil {
logger.Warnf("dubboConf is nil")
return
}
@@ -150,46 +150,74 @@
return c
}
-// call one way
-func (c *Client) CallOneway(addr string, svcUrl common.URL, method string, args interface{}) error {
-
- return perrors.WithStack(c.call(CT_OneWay, addr, svcUrl, method, args, nil, nil))
+type Request struct {
+ addr string
+ svcUrl common.URL
+ method string
+ args interface{}
+ atta map[string]string
}
-// if @reply is nil, the transport layer will get the response without notify the invoker.
-func (c *Client) Call(addr string, svcUrl common.URL, method string, args, reply interface{}) error {
+func NewRequest(addr string, svcUrl common.URL, method string, args interface{}, atta map[string]string) *Request {
+ return &Request{
+ addr: addr,
+ svcUrl: svcUrl,
+ method: method,
+ args: args,
+ atta: atta,
+ }
+}
+
+type Response struct {
+ reply interface{}
+ atta map[string]string
+}
+
+func NewResponse(reply interface{}, atta map[string]string) *Response {
+ return &Response{
+ reply: reply,
+ atta: atta,
+ }
+}
+
+// call one way
+func (c *Client) CallOneway(request *Request) error {
+
+ return perrors.WithStack(c.call(CT_OneWay, request, NewResponse(nil, nil), nil))
+}
+
+// if @response is nil, the transport layer will get the response without notify the invoker.
+func (c *Client) Call(request *Request, response *Response) error {
ct := CT_TwoWay
- if reply == nil {
+ if response.reply == nil {
ct = CT_OneWay
}
- return perrors.WithStack(c.call(ct, addr, svcUrl, method, args, reply, nil))
+ return perrors.WithStack(c.call(ct, request, response, nil))
}
-func (c *Client) AsyncCall(addr string, svcUrl common.URL, method string, args interface{},
- callback AsyncCallback, reply interface{}) error {
+func (c *Client) AsyncCall(request *Request, callback AsyncCallback, response *Response) error {
- return perrors.WithStack(c.call(CT_TwoWay, addr, svcUrl, method, args, reply, callback))
+ return perrors.WithStack(c.call(CT_TwoWay, request, response, callback))
}
-func (c *Client) call(ct CallType, addr string, svcUrl common.URL, method string,
- args, reply interface{}, callback AsyncCallback) error {
+func (c *Client) call(ct CallType, request *Request, response *Response, callback AsyncCallback) error {
p := &DubboPackage{}
- p.Service.Path = strings.TrimPrefix(svcUrl.Path, "/")
- p.Service.Interface = svcUrl.GetParam(constant.INTERFACE_KEY, "")
- p.Service.Version = svcUrl.GetParam(constant.VERSION_KEY, "")
- p.Service.Method = method
+ p.Service.Path = strings.TrimPrefix(request.svcUrl.Path, "/")
+ p.Service.Interface = request.svcUrl.GetParam(constant.INTERFACE_KEY, "")
+ p.Service.Version = request.svcUrl.GetParam(constant.VERSION_KEY, "")
+ p.Service.Method = request.method
p.Service.Timeout = c.opts.RequestTimeout
p.Header.SerialID = byte(S_Dubbo)
- p.Body = args
+ p.Body = hessian.NewRequest(request.args, request.atta)
var rsp *PendingResponse
if ct != CT_OneWay {
p.Header.Type = hessian.PackageRequest_TwoWay
rsp = NewPendingResponse()
- rsp.reply = reply
+ rsp.response = response
rsp.callback = callback
} else {
p.Header.Type = hessian.PackageRequest
@@ -200,7 +228,7 @@
session getty.Session
conn *gettyRPCClient
)
- conn, session, err = c.selectSession(addr)
+ conn, session, err = c.selectSession(request.addr)
if err != nil {
return perrors.WithStack(err)
}
@@ -259,6 +287,7 @@
if pkg == nil {
pkg = &DubboPackage{}
+ pkg.Body = hessian.NewRequest([]interface{}{}, nil)
pkg.Body = []interface{}{}
pkg.Header.Type = hessian.PackageHeartbeat
pkg.Header.SerialID = byte(S_Dubbo)
diff --git a/protocol/dubbo/client_test.go b/protocol/dubbo/client_test.go
index cd961d3..eb1f15c 100644
--- a/protocol/dubbo/client_test.go
+++ b/protocol/dubbo/client_test.go
@@ -33,6 +33,7 @@
import (
"github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
"github.com/apache/dubbo-go/protocol"
)
@@ -50,7 +51,7 @@
c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
//user := &User{}
- err := c.CallOneway("127.0.0.1:20000", url, "GetUser", []interface{}{"1", "username"})
+ err := c.CallOneway(NewRequest("127.0.0.1:20000", url, "GetUser", []interface{}{"1", "username"}, nil))
assert.NoError(t, err)
// destroy
@@ -70,51 +71,56 @@
}
c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
- user := &User{}
- err := c.Call("127.0.0.1:20000", url, "GetBigPkg", []interface{}{nil}, user)
+ var (
+ user *User
+ err error
+ )
+
+ user = &User{}
+ err = c.Call(NewRequest("127.0.0.1:20000", url, "GetBigPkg", []interface{}{nil}, nil), NewResponse(user, nil))
assert.NoError(t, err)
assert.NotEqual(t, "", user.Id)
assert.NotEqual(t, "", user.Name)
user = &User{}
- err = c.Call("127.0.0.1:20000", url, "GetUser", []interface{}{"1", "username"}, user)
+ err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser", []interface{}{"1", "username"}, nil), NewResponse(user, nil))
assert.NoError(t, err)
assert.Equal(t, User{Id: "1", Name: "username"}, *user)
user = &User{}
- err = c.Call("127.0.0.1:20000", url, "GetUser0", []interface{}{"1", nil, "username"}, user)
+ err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser0", []interface{}{"1", nil, "username"}, nil), NewResponse(user, nil))
assert.NoError(t, err)
assert.Equal(t, User{Id: "1", Name: "username"}, *user)
- err = c.Call("127.0.0.1:20000", url, "GetUser1", []interface{}{}, user)
+ err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser1", []interface{}{}, nil), NewResponse(user, nil))
assert.NoError(t, err)
- err = c.Call("127.0.0.1:20000", url, "GetUser2", []interface{}{}, user)
+ err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser2", []interface{}{}, nil), NewResponse(user, nil))
assert.EqualError(t, err, "error")
user2 := []interface{}{}
- err = c.Call("127.0.0.1:20000", url, "GetUser3", []interface{}{}, &user2)
+ err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser3", []interface{}{}, nil), NewResponse(&user2, nil))
assert.NoError(t, err)
assert.Equal(t, &User{Id: "1", Name: "username"}, user2[0])
user2 = []interface{}{}
- err = c.Call("127.0.0.1:20000", url, "GetUser4", []interface{}{[]interface{}{"1", "username"}}, &user2)
+ err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser4", []interface{}{[]interface{}{"1", "username"}}, nil), NewResponse(&user2, nil))
assert.NoError(t, err)
assert.Equal(t, &User{Id: "1", Name: "username"}, user2[0])
user3 := map[interface{}]interface{}{}
- err = c.Call("127.0.0.1:20000", url, "GetUser5", []interface{}{map[interface{}]interface{}{"id": "1", "name": "username"}}, &user3)
+ err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser5", []interface{}{map[interface{}]interface{}{"id": "1", "name": "username"}}, nil), NewResponse(&user3, nil))
assert.NoError(t, err)
assert.NotNil(t, user3)
assert.Equal(t, &User{Id: "1", Name: "username"}, user3["key"])
user = &User{}
- err = c.Call("127.0.0.1:20000", url, "GetUser6", []interface{}{0}, user)
+ err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser6", []interface{}{0}, nil), NewResponse(user, nil))
assert.NoError(t, err)
assert.Equal(t, User{Id: "", Name: ""}, *user)
user = &User{}
- err = c.Call("127.0.0.1:20000", url, "GetUser6", []interface{}{1}, user)
+ err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser6", []interface{}{1}, nil), NewResponse(user, nil))
assert.NoError(t, err)
assert.Equal(t, User{Id: "1", Name: ""}, *user)
@@ -138,10 +144,10 @@
user := &User{}
lock := sync.Mutex{}
lock.Lock()
- err := c.AsyncCall("127.0.0.1:20000", url, "GetUser", []interface{}{"1", "username"}, func(response CallResponse) {
- assert.Equal(t, User{Id: "1", Name: "username"}, *response.Reply.(*User))
+ err := c.AsyncCall(NewRequest("127.0.0.1:20000", url, "GetUser", []interface{}{"1", "username"}, nil), func(response CallResponse) {
+ assert.Equal(t, User{Id: "1", Name: "username"}, *response.Reply.(*Response).reply.(*User))
lock.Unlock()
- }, user)
+ }, NewResponse(user, nil))
assert.NoError(t, err)
assert.Equal(t, User{}, *user)
@@ -209,7 +215,9 @@
"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&"+
"side=provider&timeout=3000×tamp=1556509797245&bean.name=UserProvider")
assert.NoError(t, err)
- proto.Export(protocol.NewBaseInvoker(url))
+ proto.Export(&proxy_factory.ProxyInvoker{
+ BaseInvoker: *protocol.NewBaseInvoker(url),
+ })
time.Sleep(time.Second * 2)
diff --git a/protocol/dubbo/codec.go b/protocol/dubbo/codec.go
index 98c29a4..a878ffd 100644
--- a/protocol/dubbo/codec.go
+++ b/protocol/dubbo/codec.go
@@ -91,9 +91,8 @@
pendingRsp, ok := client.pendingResponses.Load(SequenceType(p.Header.ID))
if !ok {
return perrors.Errorf("client.GetPendingResponse(%v) = nil", p.Header.ID)
- } else {
- p.Body = &hessian.Response{RspObj: pendingRsp.(*PendingResponse).reply}
}
+ p.Body = &hessian.Response{RspObj: pendingRsp.(*PendingResponse).response.reply}
}
// read body
@@ -111,14 +110,15 @@
start time.Time
readStart time.Time
callback AsyncCallback
- reply interface{}
+ response *Response
done chan struct{}
}
func NewPendingResponse() *PendingResponse {
return &PendingResponse{
- start: time.Now(),
- done: make(chan struct{}),
+ start: time.Now(),
+ response: &Response{},
+ done: make(chan struct{}),
}
}
@@ -127,6 +127,6 @@
Cause: r.err,
Start: r.start,
ReadStart: r.readStart,
- Reply: r.reply,
+ Reply: r.response,
}
}
diff --git a/protocol/dubbo/codec_test.go b/protocol/dubbo/codec_test.go
index 52bb1fc..c192c22 100644
--- a/protocol/dubbo/codec_test.go
+++ b/protocol/dubbo/codec_test.go
@@ -64,11 +64,11 @@
assert.Equal(t, hessian.PackageRequest, pkgres.Header.Type)
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, "2.0.2", pkgres.Body.([]interface{})[0])
assert.Equal(t, "path", 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{}{"group": "", "interface": "Service", "path": "path", "timeout": "1000"}, pkgres.Body.([]interface{})[6])
+ assert.Equal(t, map[string]string{"dubbo": "2.0.2", "group": "", "interface": "Service", "path": "path", "timeout": "1000", "version": "2.6"}, pkgres.Body.([]interface{})[6])
}
diff --git a/protocol/dubbo/dubbo_invoker.go b/protocol/dubbo/dubbo_invoker.go
index 46b3dcc..bc321a9 100644
--- a/protocol/dubbo/dubbo_invoker.go
+++ b/protocol/dubbo/dubbo_invoker.go
@@ -34,7 +34,11 @@
invocation_impl "github.com/apache/dubbo-go/protocol/invocation"
)
-var Err_No_Reply = perrors.New("request need @reply")
+var Err_No_Reply = perrors.New("request need @response")
+
+var (
+ attachmentKey = []string{constant.INTERFACE_KEY, constant.GROUP_KEY, constant.TOKEN_KEY, constant.TIMEOUT_KEY}
+)
type DubboInvoker struct {
protocol.BaseInvoker
@@ -57,6 +61,11 @@
)
inv := invocation.(*invocation_impl.RPCInvocation)
+ for _, k := range attachmentKey {
+ if v := di.GetUrl().GetParam(k, ""); len(v) > 0 {
+ inv.SetAttachments(k, v)
+ }
+ }
url := di.GetUrl()
// async
async, err := strconv.ParseBool(inv.AttachmentsByKey(constant.ASYNC_KEY, "false"))
@@ -64,21 +73,23 @@
logger.Errorf("ParseBool - error: %v", err)
async = false
}
+ response := NewResponse(inv.Reply(), nil)
if async {
if callBack, ok := inv.CallBack().(func(response CallResponse)); ok {
- result.Err = di.client.AsyncCall(url.Location, url, inv.MethodName(), inv.Arguments(), callBack, inv.Reply())
+ result.Err = di.client.AsyncCall(NewRequest(url.Location, url, inv.MethodName(), inv.Arguments(), inv.Attachments()), callBack, response)
} else {
- result.Err = di.client.CallOneway(url.Location, url, inv.MethodName(), inv.Arguments())
+ result.Err = di.client.CallOneway(NewRequest(url.Location, url, inv.MethodName(), inv.Arguments(), inv.Attachments()))
}
} else {
if inv.Reply() == nil {
result.Err = Err_No_Reply
} else {
- result.Err = di.client.Call(url.Location, url, inv.MethodName(), inv.Arguments(), inv.Reply())
+ result.Err = di.client.Call(NewRequest(url.Location, url, inv.MethodName(), inv.Arguments(), inv.Attachments()), response)
}
}
if result.Err == nil {
result.Rest = inv.Reply()
+ result.Attrs = response.atta
}
logger.Debugf("result.Err: %v, result.Rest: %v", result.Err, result.Rest)
diff --git a/protocol/dubbo/dubbo_invoker_test.go b/protocol/dubbo/dubbo_invoker_test.go
index 09a4c12..0a76535 100644
--- a/protocol/dubbo/dubbo_invoker_test.go
+++ b/protocol/dubbo/dubbo_invoker_test.go
@@ -49,12 +49,13 @@
user := &User{}
inv := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("GetUser"), invocation.WithArguments([]interface{}{"1", "username"}),
- invocation.WithReply(user))
+ invocation.WithReply(user), invocation.WithAttachments(map[string]string{"test_key": "test_value"}))
// Call
res := invoker.Invoke(inv)
assert.NoError(t, res.Error())
assert.Equal(t, User{Id: "1", Name: "username"}, *res.Result().(*User))
+ assert.Equal(t, "test_value", res.Attachments()["test_key"]) // test attachments for request/response
// CallOneway
inv.SetAttachments(constant.ASYNC_KEY, "true")
@@ -65,7 +66,7 @@
lock := sync.Mutex{}
lock.Lock()
inv.SetCallBack(func(response CallResponse) {
- assert.Equal(t, User{Id: "1", Name: "username"}, *response.Reply.(*User))
+ assert.Equal(t, User{Id: "1", Name: "username"}, *response.Reply.(*Response).reply.(*User))
lock.Unlock()
})
res = invoker.Invoke(inv)
@@ -75,7 +76,7 @@
inv.SetAttachments(constant.ASYNC_KEY, "false")
inv.SetReply(nil)
res = invoker.Invoke(inv)
- assert.EqualError(t, res.Error(), "request need @reply")
+ assert.EqualError(t, res.Error(), "request need @response")
// destroy
lock.Lock()
diff --git a/protocol/dubbo/dubbo_protocol.go b/protocol/dubbo/dubbo_protocol.go
index 4438a0b..59d1ea0 100644
--- a/protocol/dubbo/dubbo_protocol.go
+++ b/protocol/dubbo/dubbo_protocol.go
@@ -18,12 +18,15 @@
package dubbo
import (
+ "sync"
+)
+
+import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/common/logger"
"github.com/apache/dubbo-go/config"
"github.com/apache/dubbo-go/protocol"
- "sync"
)
const (
diff --git a/protocol/dubbo/dubbo_protocol_test.go b/protocol/dubbo/dubbo_protocol_test.go
index 26ce4a1..a6b0bc1 100644
--- a/protocol/dubbo/dubbo_protocol_test.go
+++ b/protocol/dubbo/dubbo_protocol_test.go
@@ -19,7 +19,6 @@
import (
"context"
- "github.com/apache/dubbo-go/common/constant"
"testing"
)
@@ -29,6 +28,7 @@
import (
"github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/protocol"
)
diff --git a/protocol/dubbo/listener.go b/protocol/dubbo/listener.go
index aa20828..1a7b002 100644
--- a/protocol/dubbo/listener.go
+++ b/protocol/dubbo/listener.go
@@ -18,10 +18,8 @@
package dubbo
import (
- "context"
"fmt"
"net/url"
- "reflect"
"sync"
"time"
)
@@ -107,6 +105,8 @@
pendingResponse.err = p.Err
}
+ pendingResponse.response.atta = p.Body.(*Response).atta
+
if pendingResponse.callback == nil {
pendingResponse.done <- struct{}{}
} else {
@@ -209,6 +209,28 @@
twoway = false
}
+ defer func() {
+ if e := recover(); e != nil {
+ p.Header.ResponseStatus = hessian.Response_SERVER_ERROR
+ if err, ok := e.(error); ok {
+ logger.Errorf("OnMessage panic: %+v", perrors.WithStack(err))
+ p.Body = perrors.WithStack(err)
+ } else if err, ok := e.(string); ok {
+ logger.Errorf("OnMessage panic: %+v", perrors.New(err))
+ p.Body = perrors.New(err)
+ } else {
+ logger.Errorf("OnMessage panic: %+v, this is impossible.", e)
+ p.Body = e
+ }
+
+ if !twoway {
+ return
+ }
+ h.reply(session, p, hessian.PackageResponse)
+ }
+
+ }()
+
u := common.NewURLWithOptions(common.WithPath(p.Service.Path), common.WithParams(url.Values{}),
common.WithParamsValue(constant.GROUP_KEY, p.Service.Group),
common.WithParamsValue(constant.INTERFACE_KEY, p.Service.Interface),
@@ -224,27 +246,18 @@
}
invoker := exporter.(protocol.Exporter).GetInvoker()
if invoker != nil {
- result := invoker.Invoke(invocation.NewRPCInvocation(p.Service.Method, p.Body.(map[string]interface{})["args"].([]interface{}), map[string]string{
- constant.PATH_KEY: p.Service.Path,
- constant.GROUP_KEY: p.Service.Group,
- constant.INTERFACE_KEY: p.Service.Interface,
- constant.VERSION_KEY: p.Service.Version,
- }))
+ result := invoker.Invoke(invocation.NewRPCInvocation(p.Service.Method, p.Body.(map[string]interface{})["args"].([]interface{}),
+ p.Body.(map[string]interface{})["attachments"].(map[string]string)))
if err := result.Error(); err != nil {
p.Header.ResponseStatus = hessian.Response_OK
- p.Body = err
- h.reply(session, p, hessian.PackageResponse)
- return
- }
- if res := result.Result(); res != nil {
+ p.Body = hessian.NewResponse(nil, err, result.Attachments())
+ } else {
+ res := result.Result()
p.Header.ResponseStatus = hessian.Response_OK
- p.Body = res
- h.reply(session, p, hessian.PackageResponse)
- return
+ p.Body = hessian.NewResponse(res, nil, result.Attachments())
}
}
- h.callService(p, nil)
if !twoway {
return
}
@@ -276,91 +289,6 @@
}
}
-func (h *RpcServerHandler) callService(req *DubboPackage, ctx context.Context) {
-
- defer func() {
- if e := recover(); e != nil {
- req.Header.ResponseStatus = hessian.Response_SERVER_ERROR
- if err, ok := e.(error); ok {
- logger.Errorf("callService panic: %+v", perrors.WithStack(err))
- req.Body = perrors.WithStack(err)
- } else if err, ok := e.(string); ok {
- logger.Errorf("callService panic: %+v", perrors.New(err))
- req.Body = perrors.New(err)
- } else {
- logger.Errorf("callService panic: %+v, this is impossible.", e)
- req.Body = e
- }
- }
- }()
-
- svcIf := req.Body.(map[string]interface{})["service"]
- if svcIf == nil {
- logger.Errorf("service not found!")
- req.Header.ResponseStatus = hessian.Response_BAD_REQUEST
- req.Body = perrors.New("service not found")
- return
- }
- svc := svcIf.(*common.Service)
- method := svc.Method()[req.Service.Method]
- if method == nil {
- logger.Errorf("method not found!")
- req.Header.ResponseStatus = hessian.Response_BAD_REQUEST
- req.Body = perrors.New("method not found")
- return
- }
-
- in := []reflect.Value{svc.Rcvr()}
- if method.CtxType() != nil {
- in = append(in, method.SuiteContext(ctx))
- }
-
- // prepare argv
- argv := req.Body.(map[string]interface{})["args"]
- if (len(method.ArgsType()) == 1 || len(method.ArgsType()) == 2 && method.ReplyType() == nil) && method.ArgsType()[0].String() == "[]interface {}" {
- in = append(in, reflect.ValueOf(argv))
- } else {
- for i := 0; i < len(argv.([]interface{})); i++ {
- t := reflect.ValueOf(argv.([]interface{})[i])
- if !t.IsValid() {
- at := method.ArgsType()[i]
- if at.Kind() == reflect.Ptr {
- at = at.Elem()
- }
- t = reflect.New(at)
- }
- in = append(in, t)
- }
- }
-
- // prepare replyv
- var replyv reflect.Value
- if method.ReplyType() == nil && len(method.ArgsType()) > 0 {
- replyv = reflect.New(method.ArgsType()[len(method.ArgsType())-1].Elem())
- in = append(in, replyv)
- }
-
- returnValues := method.Method().Func.Call(in)
-
- var retErr interface{}
- if len(returnValues) == 1 {
- retErr = returnValues[0].Interface()
- } else {
- replyv = returnValues[0]
- retErr = returnValues[1].Interface()
- }
- if retErr != nil {
- req.Header.ResponseStatus = hessian.Response_OK
- req.Body = retErr
- } else {
- if replyv.IsValid() && (replyv.Kind() != reflect.Ptr || replyv.Kind() == reflect.Ptr && replyv.Elem().IsValid()) {
- req.Body = replyv.Interface()
- } else {
- req.Body = nil
- }
- }
-}
-
func (h *RpcServerHandler) reply(session getty.Session, req *DubboPackage, tp hessian.PackageType) {
resp := &DubboPackage{
Header: hessian.DubboHeader{
diff --git a/protocol/dubbo/pool.go b/protocol/dubbo/pool.go
index a8bb652..d619a2f 100644
--- a/protocol/dubbo/pool.go
+++ b/protocol/dubbo/pool.go
@@ -22,6 +22,7 @@
"math/rand"
"net"
"sync"
+ "sync/atomic"
"time"
)
@@ -38,7 +39,7 @@
once sync.Once
protocol string
addr string
- created int64 // zero, not create or be destroyed
+ active int64 // zero, not create or be destroyed
pool *gettyRPCClientPool
@@ -78,11 +79,19 @@
time.Sleep(1e6)
}
logger.Infof("client init ok")
- c.created = time.Now().Unix()
+ c.updateActive(time.Now().Unix())
return c, nil
}
+func (c *gettyRPCClient) updateActive(active int64) {
+ atomic.StoreInt64(&c.active, active)
+}
+
+func (c *gettyRPCClient) getActive() int64 {
+ return atomic.LoadInt64(&c.active)
+}
+
func (c *gettyRPCClient) newSession(session getty.Session) error {
var (
ok bool
@@ -145,6 +154,9 @@
}
c.lock.Lock()
+ if c.sessions == nil {
+ c.sessions = make([]*rpcSession, 0, 16)
+ }
c.sessions = append(c.sessions, &rpcSession{session: session})
c.lock.Unlock()
}
@@ -169,9 +181,8 @@
}
logger.Infof("after remove session{%s}, left session number:%d", session.Stat(), len(c.sessions))
if len(c.sessions) == 0 {
- c.pool.Lock()
- c.close() // -> pool.remove(c)
- c.pool.Unlock()
+ c.pool.safeRemove(c)
+ c.close()
}
}
@@ -225,10 +236,8 @@
}
func (c *gettyRPCClient) close() error {
- err := perrors.Errorf("close gettyRPCClient{%#v} again", c)
+ closeErr := perrors.Errorf("close gettyRPCClient{%#v} again", c)
c.once.Do(func() {
- // delete @c from client pool
- c.pool.remove(c)
c.gettyClient.Close()
c.gettyClient = nil
for _, s := range c.sessions {
@@ -238,10 +247,17 @@
}
c.sessions = c.sessions[:0]
- c.created = 0
- err = nil
+ c.updateActive(0)
+ closeErr = nil
})
- return err
+ return closeErr
+}
+
+func (c *gettyRPCClient) safeClose() error {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ return c.close()
}
type gettyRPCClientPool struct {
@@ -258,7 +274,7 @@
rpcClient: rpcClient,
size: size,
ttl: int64(ttl.Seconds()),
- conns: []*gettyRPCClient{},
+ conns: make([]*gettyRPCClient, 0, 16),
}
}
@@ -268,7 +284,7 @@
p.conns = nil
p.Unlock()
for _, conn := range conns {
- conn.close()
+ conn.safeClose()
}
}
@@ -286,11 +302,12 @@
conn := p.conns[len(p.conns)-1]
p.conns = p.conns[:len(p.conns)-1]
- if d := now - conn.created; d > p.ttl {
- conn.close() // -> pool.remove(c)
+ if d := now - conn.getActive(); d > p.ttl {
+ p.remove(conn)
+ conn.safeClose()
continue
}
- conn.created = now //update created time
+ conn.updateActive(now) //update active time
return conn, nil
}
@@ -299,34 +316,36 @@
}
func (p *gettyRPCClientPool) release(conn *gettyRPCClient, err error) {
- if conn == nil || conn.created == 0 {
+ if conn == nil || conn.getActive() == 0 {
return
}
+
if err != nil {
- conn.close()
+ conn.safeClose()
return
}
p.Lock()
defer p.Unlock()
+
if p.conns == nil {
return
}
if len(p.conns) >= p.size {
- conn.close()
+ // delete @conn from client pool
+ p.remove(conn)
+ conn.safeClose()
return
}
p.conns = append(p.conns, conn)
}
func (p *gettyRPCClientPool) remove(conn *gettyRPCClient) {
- if conn == nil || conn.created == 0 {
+ if conn == nil || conn.getActive() == 0 {
return
}
- //p.Lock()
- //defer p.Unlock()
if p.conns == nil {
return
}
@@ -340,3 +359,10 @@
}
}
}
+
+func (p *gettyRPCClientPool) safeRemove(conn *gettyRPCClient) {
+ p.Lock()
+ defer p.Unlock()
+
+ p.remove(conn)
+}
diff --git a/protocol/dubbo/readwriter.go b/protocol/dubbo/readwriter.go
index 8c6c8a5..a57c29f 100644
--- a/protocol/dubbo/readwriter.go
+++ b/protocol/dubbo/readwriter.go
@@ -23,7 +23,7 @@
)
import (
- hessian "github.com/apache/dubbo-go-hessian2"
+ "github.com/apache/dubbo-go-hessian2"
"github.com/dubbogo/getty"
perrors "github.com/pkg/errors"
)
@@ -63,7 +63,7 @@
}
pkg.Err = pkg.Body.(*hessian.Response).Exception
- pkg.Body = pkg.Body.(*hessian.Response).RspObj
+ pkg.Body = NewResponse(pkg.Body.(*hessian.Response).RspObj, pkg.Body.(*hessian.Response).Attachments)
return pkg, hessian.HEADER_LENGTH + pkg.Header.BodyLen, nil
}
@@ -118,7 +118,7 @@
if len(req) > 0 {
var dubboVersion, argsTypes string
var args []interface{}
- var attachments map[interface{}]interface{}
+ var attachments map[string]string
if req[0] != nil {
dubboVersion = req[0].(string)
}
@@ -138,14 +138,18 @@
args = req[5].([]interface{})
}
if req[6] != nil {
- attachments = req[6].(map[interface{}]interface{})
+ attachments = req[6].(map[string]string)
}
- pkg.Service.Interface = attachments[constant.INTERFACE_KEY].(string)
- if pkg.Service.Path == "" && attachments[constant.PATH_KEY] != nil {
- pkg.Service.Path = attachments[constant.PATH_KEY].(string)
+ if pkg.Service.Path == "" && len(attachments[constant.PATH_KEY]) > 0 {
+ pkg.Service.Path = attachments[constant.PATH_KEY]
}
- if attachments[constant.GROUP_KEY] != nil {
- pkg.Service.Group = attachments[constant.GROUP_KEY].(string)
+ if _, ok := attachments[constant.INTERFACE_KEY]; ok {
+ pkg.Service.Interface = attachments[constant.INTERFACE_KEY]
+ } else {
+ pkg.Service.Interface = pkg.Service.Path
+ }
+ if len(attachments[constant.GROUP_KEY]) > 0 {
+ pkg.Service.Group = attachments[constant.GROUP_KEY]
}
pkg.Body = map[string]interface{}{
"dubboVersion": dubboVersion,
diff --git a/protocol/dubbo/server.go b/protocol/dubbo/server.go
index 8daeee0..5f93a79 100644
--- a/protocol/dubbo/server.go
+++ b/protocol/dubbo/server.go
@@ -48,7 +48,7 @@
return
}
dubboConf := protocolConf.(map[interface{}]interface{})[DUBBO]
- if protocolConf == nil {
+ if dubboConf == nil {
logger.Warnf("dubboConf is nil")
return
}
diff --git a/protocol/jsonrpc/http_test.go b/protocol/jsonrpc/http_test.go
index 1f44680..9be55e2 100644
--- a/protocol/jsonrpc/http_test.go
+++ b/protocol/jsonrpc/http_test.go
@@ -32,6 +32,7 @@
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
+ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
"github.com/apache/dubbo-go/protocol"
)
@@ -60,7 +61,9 @@
"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&"+
"side=provider&timeout=3000×tamp=1556509797245&bean.name=UserProvider")
assert.NoError(t, err)
- proto.Export(protocol.NewBaseInvoker(url))
+ proto.Export(&proxy_factory.ProxyInvoker{
+ BaseInvoker: *protocol.NewBaseInvoker(url),
+ })
time.Sleep(time.Second * 2)
client := NewHTTPClient(&HTTPOptions{})
diff --git a/protocol/jsonrpc/jsonrpc_invoker_test.go b/protocol/jsonrpc/jsonrpc_invoker_test.go
index bc88759..8c91033 100644
--- a/protocol/jsonrpc/jsonrpc_invoker_test.go
+++ b/protocol/jsonrpc/jsonrpc_invoker_test.go
@@ -29,6 +29,7 @@
import (
"github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
"github.com/apache/dubbo-go/protocol"
"github.com/apache/dubbo-go/protocol/invocation"
)
@@ -47,7 +48,9 @@
"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&"+
"side=provider&timeout=3000×tamp=1556509797245&bean.name=UserProvider")
assert.NoError(t, err)
- proto.Export(protocol.NewBaseInvoker(url))
+ proto.Export(&proxy_factory.ProxyInvoker{
+ BaseInvoker: *protocol.NewBaseInvoker(url),
+ })
time.Sleep(time.Second * 2)
client := NewHTTPClient(&HTTPOptions{
diff --git a/protocol/jsonrpc/server.go b/protocol/jsonrpc/server.go
index 6b3a39c..dc85e0f 100644
--- a/protocol/jsonrpc/server.go
+++ b/protocol/jsonrpc/server.go
@@ -25,7 +25,6 @@
"io/ioutil"
"net"
"net/http"
- "reflect"
"runtime"
"runtime/debug"
"sync"
@@ -330,13 +329,16 @@
constant.VERSION_KEY: codec.req.Version,
}))
if err := result.Error(); err != nil {
- if errRsp := sendErrorResp(header, []byte(err.Error())); errRsp != nil {
+ rspStream, err := codec.Write(err.Error(), invalidRequest)
+ if err != nil {
+ return perrors.WithStack(err)
+ }
+ if errRsp := sendErrorResp(header, rspStream); errRsp != nil {
logger.Warnf("Exporter: sendErrorResp(header:%#v, error:%v) = error:%s",
header, err, errRsp)
- return perrors.WithStack(errRsp)
}
- }
- if res := result.Result(); res != nil {
+ } else {
+ res := result.Result()
rspStream, err := codec.Write("", res)
if err != nil {
return perrors.WithStack(err)
@@ -344,102 +346,9 @@
if errRsp := sendResp(header, rspStream); errRsp != nil {
logger.Warnf("Exporter: sendResp(header:%#v, error:%v) = error:%s",
header, err, errRsp)
- return perrors.WithStack(errRsp)
}
}
}
- // get method
- svc := common.ServiceMap.GetService(JSONRPC, path)
- if svc == nil {
- return perrors.New("cannot find svc " + path)
- }
- method := svc.Method()[methodName]
- if method == nil {
- return perrors.New("cannot find method " + methodName + " of svc " + path)
- }
- in := []reflect.Value{svc.Rcvr()}
- if method.CtxType() != nil {
- in = append(in, method.SuiteContext(ctx))
- }
-
- // prepare argv
- if (len(method.ArgsType()) == 1 || len(method.ArgsType()) == 2 && method.ReplyType() == nil) && method.ArgsType()[0].String() == "[]interface {}" {
- in = append(in, reflect.ValueOf(args))
- } else {
- for i := 0; i < len(args); i++ {
- t := reflect.ValueOf(args[i])
- if !t.IsValid() {
- at := method.ArgsType()[i]
- if at.Kind() == reflect.Ptr {
- at = at.Elem()
- }
- t = reflect.New(at)
- }
- in = append(in, t)
- }
- }
-
- // prepare replyv
- var replyv reflect.Value
- if method.ReplyType() == nil && len(method.ArgsType()) > 0 {
- replyv = reflect.New(method.ArgsType()[len(method.ArgsType())-1].Elem())
- in = append(in, replyv)
- }
-
- returnValues := method.Method().Func.Call(in)
-
- var (
- retErr interface{}
- errMsg string
- )
- if len(returnValues) == 1 {
- retErr = returnValues[0].Interface()
- } else {
- replyv = returnValues[0]
- retErr = returnValues[1].Interface()
- }
- if retErr != nil {
- errMsg = retErr.(error).Error()
- }
-
- // write response
- code := 200
- var rspReply interface{}
- if replyv.IsValid() && (replyv.Kind() != reflect.Ptr || replyv.Kind() == reflect.Ptr && replyv.Elem().IsValid()) {
- rspReply = replyv.Interface()
- }
- if len(errMsg) != 0 {
- code = 500
- rspReply = invalidRequest
- }
- rspStream, err := codec.Write(errMsg, rspReply)
- if err != nil {
- return perrors.WithStack(err)
- }
- rsp := &http.Response{
- StatusCode: code,
- ProtoMajor: 1,
- ProtoMinor: 1,
- Header: make(http.Header),
- ContentLength: int64(len(rspStream)),
- Body: ioutil.NopCloser(bytes.NewReader(rspStream)),
- }
- delete(header, "Content-Type")
- delete(header, "Content-Length")
- delete(header, "Timeout")
- for k, v := range header {
- rsp.Header.Set(k, v)
- }
-
- rspBuf := bytes.NewBuffer(make([]byte, DefaultHTTPRspBufferSize))
- rspBuf.Reset()
- if err = rsp.Write(rspBuf); err != nil {
- logger.Warnf("rsp.Write(rsp:%#v) = error:%s", rsp, err)
- return nil
- }
- if _, err = rspBuf.WriteTo(conn); err != nil {
- logger.Warnf("rspBuf.WriteTo(conn:%#v) = error:%s", conn, err)
- }
return nil
}
diff --git a/protocol/protocolwrapper/protocol_filter_wrapper.go b/protocol/protocolwrapper/protocol_filter_wrapper.go
index b1392ff..7c58fab 100644
--- a/protocol/protocolwrapper/protocol_filter_wrapper.go
+++ b/protocol/protocolwrapper/protocol_filter_wrapper.go
@@ -62,7 +62,7 @@
}
func buildInvokerChain(invoker protocol.Invoker, key string) protocol.Invoker {
- filtName := invoker.GetUrl().Params.Get(key)
+ filtName := invoker.GetUrl().GetParam(key, "")
if filtName == "" {
return invoker
}
diff --git a/protocol/protocolwrapper/protocol_filter_wrapper_test.go b/protocol/protocolwrapper/protocol_filter_wrapper_test.go
index 8a33249..dc37631 100644
--- a/protocol/protocolwrapper/protocol_filter_wrapper_test.go
+++ b/protocol/protocolwrapper/protocol_filter_wrapper_test.go
@@ -30,7 +30,8 @@
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
- "github.com/apache/dubbo-go/filter/impl"
+ "github.com/apache/dubbo-go/common/logger"
+ "github.com/apache/dubbo-go/filter"
"github.com/apache/dubbo-go/protocol"
)
@@ -40,7 +41,7 @@
u := common.NewURLWithOptions(
common.WithParams(url.Values{}),
- common.WithParamsValue(constant.SERVICE_FILTER_KEY, impl.ECHO))
+ common.WithParamsValue(constant.SERVICE_FILTER_KEY, "echo"))
exporter := filtProto.Export(protocol.NewBaseInvoker(*u))
_, ok := exporter.GetInvoker().(*FilterInvoker)
assert.True(t, ok)
@@ -52,8 +53,35 @@
u := common.NewURLWithOptions(
common.WithParams(url.Values{}),
- common.WithParamsValue(constant.REFERENCE_FILTER_KEY, impl.ECHO))
+ common.WithParamsValue(constant.REFERENCE_FILTER_KEY, "echo"))
invoker := filtProto.Refer(*u)
_, ok := invoker.(*FilterInvoker)
assert.True(t, ok)
}
+
+//the same as echo filter, for test
+func init() {
+ extension.SetFilter("echo", GetFilter)
+}
+
+type EchoFilterForTest struct{}
+
+func (ef *EchoFilterForTest) Invoke(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 {
+ return &protocol.RPCResult{
+ Rest: invocation.Arguments()[0],
+ }
+ }
+
+ return invoker.Invoke(invocation)
+}
+
+func (ef *EchoFilterForTest) OnResponse(result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
+ return result
+}
+
+func GetFilter() filter.Filter {
+ return &EchoFilterForTest{}
+}
diff --git a/protocol/RpcStatus.go b/protocol/rpc_status.go
similarity index 98%
rename from protocol/RpcStatus.go
rename to protocol/rpc_status.go
index 78796b6..3a8bfbc 100644
--- a/protocol/RpcStatus.go
+++ b/protocol/rpc_status.go
@@ -15,7 +15,6 @@
* limitations under the License.
*/
-// @author yiji@apache.org
package protocol
import (
diff --git a/registry/base_configuration_listener.go b/registry/base_configuration_listener.go
new file mode 100644
index 0000000..925baa2
--- /dev/null
+++ b/registry/base_configuration_listener.go
@@ -0,0 +1,99 @@
+/*
+ * 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 registry
+
+import (
+ perrors "github.com/pkg/errors"
+)
+import (
+ "github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/common/config"
+ "github.com/apache/dubbo-go/common/constant"
+ "github.com/apache/dubbo-go/common/logger"
+ "github.com/apache/dubbo-go/config_center"
+ "github.com/apache/dubbo-go/remoting"
+)
+
+type BaseConfigurationListener struct {
+ configurators []config_center.Configurator
+ dynamicConfiguration config_center.DynamicConfiguration
+ defaultConfiguratorFunc func(url *common.URL) config_center.Configurator
+}
+
+func (bcl *BaseConfigurationListener) Configurators() []config_center.Configurator {
+ return bcl.configurators
+}
+func (bcl *BaseConfigurationListener) InitWith(key string, listener config_center.ConfigurationListener, f func(url *common.URL) config_center.Configurator) {
+ bcl.dynamicConfiguration = config.GetEnvInstance().GetDynamicConfiguration()
+ if bcl.dynamicConfiguration == nil {
+ //set configurators to empty
+ bcl.configurators = []config_center.Configurator{}
+ return
+ }
+ bcl.defaultConfiguratorFunc = f
+ bcl.dynamicConfiguration.AddListener(key, listener)
+ if rawConfig, err := bcl.dynamicConfiguration.GetConfig(key, config_center.WithGroup(constant.DUBBO)); err != nil {
+ //set configurators to empty
+ bcl.configurators = []config_center.Configurator{}
+ return
+ } else if len(rawConfig) > 0 {
+ bcl.genConfiguratorFromRawRule(rawConfig)
+ }
+}
+
+func (bcl *BaseConfigurationListener) Process(event *config_center.ConfigChangeEvent) {
+ logger.Infof("Notification of overriding rule, change type is: %v , raw config content is:%v", event.ConfigType, event.Value)
+ if event.ConfigType == remoting.EventTypeDel {
+ bcl.configurators = nil
+ } else {
+ if err := bcl.genConfiguratorFromRawRule(event.Value.(string)); err != nil {
+ logger.Error(perrors.WithStack(err))
+ }
+ }
+}
+
+func (bcl *BaseConfigurationListener) genConfiguratorFromRawRule(rawConfig string) error {
+ urls, err := bcl.dynamicConfiguration.Parser().ParseToUrls(rawConfig)
+ if err != nil {
+ return perrors.WithMessage(err, "Failed to parse raw dynamic config and it will not take effect, the raw config is: "+
+ rawConfig)
+ }
+ bcl.configurators = ToConfigurators(urls, bcl.defaultConfiguratorFunc)
+ return nil
+}
+func (bcl *BaseConfigurationListener) OverrideUrl(url *common.URL) {
+ for _, v := range bcl.configurators {
+ v.Configure(url)
+ }
+}
+
+func ToConfigurators(urls []*common.URL, f func(url *common.URL) config_center.Configurator) []config_center.Configurator {
+ if len(urls) == 0 {
+ return nil
+ }
+ var configurators []config_center.Configurator
+ for _, url := range urls {
+ if url.Protocol == constant.EMPTY_PROTOCOL {
+ configurators = []config_center.Configurator{}
+ break
+ }
+ //TODO:anyhost_key judage
+ configurators = append(configurators, f(url))
+ }
+ return configurators
+}
diff --git a/registry/consul/listener.go b/registry/consul/listener.go
new file mode 100644
index 0000000..b047a4c
--- /dev/null
+++ b/registry/consul/listener.go
@@ -0,0 +1,206 @@
+/*
+ * 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 consul
+
+import (
+ "sync"
+)
+
+import (
+ consul "github.com/hashicorp/consul/api"
+ "github.com/hashicorp/consul/api/watch"
+ perrors "github.com/pkg/errors"
+)
+
+import (
+ "github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/common/logger"
+ "github.com/apache/dubbo-go/registry"
+ "github.com/apache/dubbo-go/remoting"
+)
+
+// Consul listener wraps the consul watcher, to
+// listen the service information change in consul
+// registry.
+type consulListener struct {
+ // Registry url.
+ registryUrl common.URL
+
+ // Consumer url.
+ consumerUrl common.URL
+
+ // Consul watcher.
+ plan *watch.Plan
+
+ // Most recent service urls return by
+ // watcher.
+ urls []common.URL
+
+ // All service information changes will
+ // be wrapped into ServiceEvent, and be
+ // sent into eventCh. Then listener's
+ // Next method will get event from eventCh,
+ // and return to upstream.
+ eventCh chan *registry.ServiceEvent
+
+ // All errors, happening in the listening
+ // period, will be caught and send into
+ // errCh. Then listener's Next method will
+ // get error from errCh, and return to
+ // upstream.
+ errCh chan error
+
+ // Done field represents whether consul
+ // listener has been closed. When closing
+ // listener, this field will be closed,
+ // and will notify consul watcher to close.
+ done chan struct{}
+
+ // After listener notifies consul watcher
+ // to close, listener will call wg.wait to
+ // make sure that consul watcher is closed
+ // before the listener closes.
+ wg sync.WaitGroup
+}
+
+func newConsulListener(registryUrl common.URL, consumerUrl common.URL) (*consulListener, error) {
+ params := make(map[string]interface{}, 8)
+ params["type"] = "service"
+ params["service"] = consumerUrl.Service()
+ params["tag"] = "dubbo"
+ params["passingonly"] = true
+ plan, err := watch.Parse(params)
+ if err != nil {
+ return nil, err
+ }
+
+ listener := &consulListener{
+ registryUrl: registryUrl,
+ consumerUrl: consumerUrl,
+ plan: plan,
+ urls: make([]common.URL, 0, 8),
+ eventCh: make(chan *registry.ServiceEvent, 32),
+ errCh: make(chan error, 32),
+ done: make(chan struct{}),
+ }
+
+ // Set handler to consul watcher, and
+ // make watcher begin to watch service
+ // information change.
+ listener.plan.Handler = listener.handler
+ listener.wg.Add(1)
+ go listener.run()
+ return listener, nil
+}
+
+// Wrap the consul watcher run api. There are three
+// conditions that will finish the run:
+// - close done
+// - call plan.Stop
+// - close eventCh and errCh
+// If run meets first two conditions, it will close
+// gracefully. However, if run meets the last condition,
+// run will close with panic, so use recover to cover
+// this case.
+func (l *consulListener) run() {
+ defer func() {
+ p := recover()
+ if p != nil {
+ logger.Warnf("consul listener finish with panic %v", p)
+ }
+ l.wg.Done()
+ }()
+
+ for {
+ select {
+ case <-l.done:
+ return
+ default:
+ err := l.plan.Run(l.registryUrl.Location)
+ if err != nil {
+ l.errCh <- err
+ }
+ }
+ }
+}
+
+func (l *consulListener) handler(idx uint64, raw interface{}) {
+ var (
+ service *consul.ServiceEntry
+ event *registry.ServiceEvent
+ url common.URL
+ ok bool
+ err error
+ )
+
+ services, ok := raw.([]*consul.ServiceEntry)
+ if !ok {
+ err = perrors.New("handler get non ServiceEntry type parameter")
+ l.errCh <- err
+ return
+ }
+ newUrls := make([]common.URL, 0, 8)
+ events := make([]*registry.ServiceEvent, 0, 8)
+
+ for _, service = range services {
+ url, err = retrieveURL(service)
+ if err != nil {
+ l.errCh <- err
+ return
+ }
+ newUrls = append(newUrls, url)
+ }
+
+ for _, url = range l.urls {
+ ok = in(url, newUrls)
+ if !ok {
+ event := ®istry.ServiceEvent{Action: remoting.EventTypeDel, Service: url}
+ events = append(events, event)
+ }
+ }
+
+ for _, url = range newUrls {
+ ok = in(url, l.urls)
+ if !ok {
+ event := ®istry.ServiceEvent{Action: remoting.EventTypeAdd, Service: url}
+ events = append(events, event)
+ }
+ }
+
+ l.urls = newUrls
+ for _, event = range events {
+ l.eventCh <- event
+ }
+}
+
+func (l *consulListener) Next() (*registry.ServiceEvent, error) {
+ select {
+ case event := <-l.eventCh:
+ return event, nil
+ case err := <-l.errCh:
+ return nil, err
+ }
+}
+
+func (l *consulListener) Close() {
+ close(l.done)
+ l.plan.Stop()
+ close(l.eventCh)
+ close(l.errCh)
+ l.wg.Wait()
+}
diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go b/registry/consul/listener_test.go
similarity index 67%
copy from examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go
copy to registry/consul/listener_test.go
index c613858..7dccbaa 100644
--- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/version.go
+++ b/registry/consul/listener_test.go
@@ -15,8 +15,19 @@
* limitations under the License.
*/
-package main
+package consul
-var (
- Version = "2.6.0"
+import (
+ "github.com/stretchr/testify/assert"
)
+
+import (
+ "github.com/apache/dubbo-go/remoting"
+)
+
+func (suite *consulRegistryTestSuite) testListener(action remoting.EventType) {
+ event, err := suite.listener.Next()
+ assert.NoError(suite.t, err)
+ assert.Equal(suite.t, action, event.Action)
+ assert.True(suite.t, suite.providerUrl.URLEqual(event.Service))
+}
diff --git a/registry/consul/registry.go b/registry/consul/registry.go
new file mode 100644
index 0000000..1fd3e54
--- /dev/null
+++ b/registry/consul/registry.go
@@ -0,0 +1,184 @@
+/*
+ * 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 consul
+
+import (
+ "strconv"
+ "time"
+)
+
+import (
+ consul "github.com/hashicorp/consul/api"
+ perrors "github.com/pkg/errors"
+)
+
+import (
+ "github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/common/constant"
+ "github.com/apache/dubbo-go/common/extension"
+ "github.com/apache/dubbo-go/common/logger"
+ "github.com/apache/dubbo-go/registry"
+)
+
+const (
+ RegistryConnDelay = 3
+)
+
+func init() {
+ extension.SetRegistry("consul", newConsulRegistry)
+}
+
+// Consul registry wraps the consul client, to
+// register and subscribe service.
+type consulRegistry struct {
+ // Registry url.
+ *common.URL
+
+ // Consul client.
+ client *consul.Client
+
+ // Done field represents whether
+ // consul registry is closed.
+ done chan struct{}
+}
+
+func newConsulRegistry(url *common.URL) (registry.Registry, error) {
+ config := &consul.Config{Address: url.Location}
+ client, err := consul.NewClient(config)
+ if err != nil {
+ return nil, err
+ }
+
+ r := &consulRegistry{
+ URL: url,
+ client: client,
+ done: make(chan struct{}),
+ }
+
+ return r, nil
+}
+
+func (r *consulRegistry) Register(url common.URL) error {
+ var err error
+
+ role, _ := strconv.Atoi(r.URL.GetParam(constant.ROLE_KEY, ""))
+ if role == common.PROVIDER {
+ err = r.register(url)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (r *consulRegistry) register(url common.URL) error {
+ service, err := buildService(url)
+ if err != nil {
+ return err
+ }
+ return r.client.Agent().ServiceRegister(service)
+}
+
+func (r *consulRegistry) Unregister(url common.URL) error {
+ var err error
+
+ role, _ := strconv.Atoi(r.URL.GetParam(constant.ROLE_KEY, ""))
+ if role == common.PROVIDER {
+ err = r.unregister(url)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (r *consulRegistry) unregister(url common.URL) error {
+ return r.client.Agent().ServiceDeregister(buildId(url))
+}
+
+func (r *consulRegistry) subscribe(url *common.URL) (registry.Listener, error) {
+ var (
+ listener registry.Listener
+ err error
+ )
+
+ role, _ := strconv.Atoi(r.URL.GetParam(constant.ROLE_KEY, ""))
+ if role == common.CONSUMER {
+ listener, err = r.getListener(*url)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return listener, nil
+}
+
+//subscibe from registry
+func (r *consulRegistry) Subscribe(url *common.URL, notifyListener registry.NotifyListener) {
+ for {
+ if !r.IsAvailable() {
+ logger.Warnf("event listener game over.")
+ return
+ }
+
+ listener, err := r.subscribe(url)
+ if err != nil {
+ if !r.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()
+ return
+ } else {
+ logger.Infof("update begin, service event: %v", serviceEvent.String())
+ notifyListener.Notify(serviceEvent)
+ }
+
+ }
+
+ }
+}
+
+func (r *consulRegistry) getListener(url common.URL) (registry.Listener, error) {
+ listener, err := newConsulListener(*r.URL, url)
+ return listener, err
+}
+
+func (r *consulRegistry) GetUrl() common.URL {
+ return *r.URL
+}
+
+func (r *consulRegistry) IsAvailable() bool {
+ select {
+ case <-r.done:
+ return false
+ default:
+ return true
+ }
+}
+
+func (r *consulRegistry) Destroy() {
+ close(r.done)
+}
diff --git a/registry/consul/registry_test.go b/registry/consul/registry_test.go
new file mode 100644
index 0000000..ff8c2e2
--- /dev/null
+++ b/registry/consul/registry_test.go
@@ -0,0 +1,57 @@
+/*
+ * 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 consul
+
+import (
+ "github.com/stretchr/testify/assert"
+)
+
+func (suite *consulRegistryTestSuite) testNewProviderRegistry() {
+ providerRegistryUrl := newProviderRegistryUrl(registryHost, registryPort)
+ providerRegistry, err := newConsulRegistry(providerRegistryUrl)
+ assert.NoError(suite.t, err)
+ suite.providerRegistry = providerRegistry
+}
+
+func (suite *consulRegistryTestSuite) testNewConsumerRegistry() {
+ consumerRegistryUrl := newConsumerRegistryUrl(registryHost, registryPort)
+ consumerRegistry, err := newConsulRegistry(consumerRegistryUrl)
+ assert.NoError(suite.t, err)
+ suite.consumerRegistry = consumerRegistry.(*consulRegistry)
+}
+
+func (suite *consulRegistryTestSuite) testRegister() {
+ providerUrl := newProviderUrl(providerHost, providerPort, service, protocol)
+ suite.providerUrl = providerUrl
+ err := suite.providerRegistry.Register(providerUrl)
+ assert.NoError(suite.t, err)
+}
+
+func (suite *consulRegistryTestSuite) testUnregister() {
+ consulProviderRegistry, _ := suite.providerRegistry.(*consulRegistry)
+ err := consulProviderRegistry.Unregister(suite.providerUrl)
+ assert.NoError(suite.t, err)
+}
+
+func (suite *consulRegistryTestSuite) testSubscribe() {
+ consumerUrl := newConsumerUrl(consumerHost, consumerPort, service, protocol)
+ suite.consumerUrl = consumerUrl
+ listener, err := suite.consumerRegistry.subscribe(&consumerUrl)
+ assert.NoError(suite.t, err)
+ suite.listener = listener
+}
diff --git a/registry/consul/utils.go b/registry/consul/utils.go
new file mode 100644
index 0000000..ee17fcc
--- /dev/null
+++ b/registry/consul/utils.go
@@ -0,0 +1,117 @@
+/*
+ * 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 consul
+
+import (
+ "context"
+ "crypto/md5"
+ "encoding/hex"
+ "fmt"
+ "strconv"
+)
+
+import (
+ consul "github.com/hashicorp/consul/api"
+ perrors "github.com/pkg/errors"
+)
+
+import (
+ "github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/common/utils"
+)
+
+func buildId(url common.URL) string {
+ t := md5.Sum([]byte(url.String()))
+ return hex.EncodeToString(t[:])
+}
+
+func buildService(url common.URL) (*consul.AgentServiceRegistration, error) {
+ var err error
+
+ // id
+ id := buildId(url)
+
+ // address
+ if url.Ip == "" {
+ url.Ip, _ = utils.GetLocalIP()
+ }
+
+ // port
+ port, err := strconv.Atoi(url.Port)
+ if err != nil {
+ return nil, err
+ }
+
+ // tcp
+ tcp := fmt.Sprintf("%s:%d", url.Ip, port)
+
+ // tags
+ tags := make([]string, 0, 8)
+
+ url.RangeParams(func(key, value string) bool {
+ tags = append(tags, key+"="+value)
+ return true
+ })
+
+ tags = append(tags, "dubbo")
+
+ // meta
+ meta := make(map[string]string, 8)
+ meta["url"] = url.String()
+
+ // check
+ check := &consul.AgentServiceCheck{
+ TCP: tcp,
+ Interval: url.GetParam("consul-check-interval", "10s"),
+ Timeout: url.GetParam("consul-check-timeout", "1s"),
+ DeregisterCriticalServiceAfter: url.GetParam("consul-deregister-critical-service-after", "20s"),
+ }
+
+ service := &consul.AgentServiceRegistration{
+ Name: url.Service(),
+ ID: id,
+ Address: url.Ip,
+ Port: port,
+ Tags: tags,
+ Meta: meta,
+ Check: check,
+ }
+
+ return service, nil
+}
+
+func retrieveURL(service *consul.ServiceEntry) (common.URL, error) {
+ url, ok := service.Service.Meta["url"]
+ if !ok {
+ return common.URL{}, perrors.New("retrieve url fails with no url key in service meta")
+ }
+ url1, err := common.NewURL(context.Background(), url)
+ if err != nil {
+ return common.URL{}, perrors.WithStack(err)
+ }
+ return url1, nil
+}
+
+func in(url common.URL, urls []common.URL) bool {
+ for _, url1 := range urls {
+ if url.URLEqual(url1) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/registry/consul/utils_test.go b/registry/consul/utils_test.go
new file mode 100644
index 0000000..d66600b
--- /dev/null
+++ b/registry/consul/utils_test.go
@@ -0,0 +1,226 @@
+/*
+ * 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 consul
+
+import (
+ "fmt"
+ "io/ioutil"
+ "net"
+ "net/url"
+ "os"
+ "strconv"
+ "sync"
+ "testing"
+)
+
+import (
+ "github.com/hashicorp/consul/agent"
+)
+
+import (
+ "github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/common/constant"
+ "github.com/apache/dubbo-go/registry"
+ "github.com/apache/dubbo-go/remoting"
+)
+
+var (
+ registryHost = "localhost"
+ registryPort = 8500
+ providerHost = "localhost"
+ providerPort = 8000
+ consumerHost = "localhost"
+ consumerPort = 8001
+ service = "HelloWorld"
+ protocol = "tcp"
+)
+
+func newProviderRegistryUrl(host string, port int) *common.URL {
+ url1 := common.NewURLWithOptions(
+ common.WithIp(host),
+ common.WithPort(strconv.Itoa(port)),
+ common.WithParams(url.Values{}),
+ common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER)),
+ )
+ return url1
+}
+
+func newConsumerRegistryUrl(host string, port int) *common.URL {
+ url1 := common.NewURLWithOptions(
+ common.WithIp(host),
+ common.WithPort(strconv.Itoa(port)),
+ common.WithParams(url.Values{}),
+ common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER)),
+ )
+ return url1
+}
+
+func newProviderUrl(host string, port int, service string, protocol string) common.URL {
+ url1 := common.NewURLWithOptions(
+ common.WithIp(host),
+ common.WithPort(strconv.Itoa(port)),
+ common.WithPath(service),
+ common.WithProtocol(protocol),
+ )
+ return *url1
+}
+
+func newConsumerUrl(host string, port int, service string, protocol string) common.URL {
+ url1 := common.NewURLWithOptions(
+ common.WithIp(host),
+ common.WithPort(strconv.Itoa(port)),
+ common.WithPath(service),
+ common.WithProtocol(protocol),
+ )
+ return *url1
+}
+
+type testConsulAgent struct {
+ dataDir string
+ testAgent *agent.TestAgent
+}
+
+func newConsulAgent(t *testing.T, port int) *testConsulAgent {
+ dataDir, _ := ioutil.TempDir("./", "agent")
+ hcl := `
+ ports {
+ http = ` + strconv.Itoa(port) + `
+ }
+ data_dir = "` + dataDir + `"
+ `
+ testAgent := &agent.TestAgent{Name: t.Name(), DataDir: dataDir, HCL: hcl}
+ testAgent.Start(t)
+
+ consulAgent := &testConsulAgent{
+ dataDir: dataDir,
+ testAgent: testAgent,
+ }
+ return consulAgent
+}
+
+func (consulAgent *testConsulAgent) close() {
+ consulAgent.testAgent.Shutdown()
+ os.RemoveAll(consulAgent.dataDir)
+}
+
+type testServer struct {
+ listener net.Listener
+ wg sync.WaitGroup
+ done chan struct{}
+}
+
+func newServer(host string, port int) *testServer {
+ addr := fmt.Sprintf("%s:%d", host, port)
+ tcpAddr, _ := net.ResolveTCPAddr("tcp", addr)
+ listener, _ := net.ListenTCP("tcp", tcpAddr)
+
+ server := &testServer{
+ listener: listener,
+ done: make(chan struct{}),
+ }
+
+ server.wg.Add(1)
+ go server.serve()
+ return server
+}
+
+func (server *testServer) serve() {
+ defer server.wg.Done()
+ for {
+ select {
+ case <-server.done:
+ return
+ default:
+ conn, err := server.listener.Accept()
+ if err != nil {
+ continue
+ }
+ conn.Write([]byte("Hello World"))
+ conn.Close()
+ }
+ }
+}
+
+func (server *testServer) close() {
+ close(server.done)
+ server.listener.Close()
+ server.wg.Wait()
+}
+
+type consulRegistryTestSuite struct {
+ t *testing.T
+ providerRegistry registry.Registry
+ consumerRegistry *consulRegistry
+ listener registry.Listener
+ providerUrl common.URL
+ consumerUrl common.URL
+}
+
+func newConsulRegistryTestSuite(t *testing.T) *consulRegistryTestSuite {
+ suite := &consulRegistryTestSuite{t: t}
+ return suite
+}
+
+func (suite *consulRegistryTestSuite) close() {
+ suite.listener.Close()
+ suite.providerRegistry.Destroy()
+ suite.consumerRegistry.Destroy()
+}
+
+// register -> subscribe -> unregister
+func test1(t *testing.T) {
+ consulAgent := newConsulAgent(t, registryPort)
+ defer consulAgent.close()
+
+ server := newServer(providerHost, providerPort)
+ defer server.close()
+
+ suite := newConsulRegistryTestSuite(t)
+ defer suite.close()
+
+ suite.testNewProviderRegistry()
+ suite.testRegister()
+ suite.testNewConsumerRegistry()
+ suite.testSubscribe()
+ suite.testListener(remoting.EventTypeAdd)
+ suite.testUnregister()
+ suite.testListener(remoting.EventTypeDel)
+}
+
+// subscribe -> register
+func test2(t *testing.T) {
+ consulAgent := newConsulAgent(t, registryPort)
+ defer consulAgent.close()
+
+ server := newServer(providerHost, providerPort)
+ defer server.close()
+
+ suite := newConsulRegistryTestSuite(t)
+ defer suite.close()
+
+ suite.testNewConsumerRegistry()
+ suite.testSubscribe()
+ suite.testNewProviderRegistry()
+ suite.testRegister()
+ suite.testListener(remoting.EventTypeAdd)
+}
+
+func TestConsulRegistry(t *testing.T) {
+ t.Run("test1", test1)
+ t.Run("test2", test2)
+}
diff --git a/registry/directory/directory.go b/registry/directory/directory.go
index accc99a..7ffc702 100644
--- a/registry/directory/directory.go
+++ b/registry/directory/directory.go
@@ -32,6 +32,9 @@
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/common/logger"
+ "github.com/apache/dubbo-go/config"
+ "github.com/apache/dubbo-go/config_center"
+ _ "github.com/apache/dubbo-go/config_center/configurator"
"github.com/apache/dubbo-go/protocol"
"github.com/apache/dubbo-go/protocol/protocolwrapper"
"github.com/apache/dubbo-go/registry"
@@ -50,11 +53,15 @@
type registryDirectory struct {
directory.BaseDirectory
- cacheInvokers []protocol.Invoker
- listenerLock sync.Mutex
- serviceType string
- registry registry.Registry
- cacheInvokersMap *sync.Map //use sync.map
+ cacheInvokers []protocol.Invoker
+ listenerLock sync.Mutex
+ serviceType string
+ registry registry.Registry
+ cacheInvokersMap *sync.Map //use sync.map
+ cacheOriginUrl *common.URL
+ configurators []config_center.Configurator
+ consumerConfigurationListener *consumerConfigurationListener
+ referenceConfigurationListener *referenceConfigurationListener
Options
}
@@ -69,87 +76,74 @@
if url.SubURL == nil {
return nil, perrors.Errorf("url is invalid, suburl can not be nil")
}
- return ®istryDirectory{
+ dir := ®istryDirectory{
BaseDirectory: directory.NewBaseDirectory(url),
cacheInvokers: []protocol.Invoker{},
cacheInvokersMap: &sync.Map{},
serviceType: url.SubURL.Service(),
registry: registry,
Options: options,
- }, nil
-}
-
-//subscribe from registry
-func (dir *registryDirectory) Subscribe(url common.URL) {
- for {
- if !dir.registry.IsAvailable() {
- logger.Warnf("event listener game over.")
- 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)
- }
-
- }
-
}
+ dir.consumerConfigurationListener = newConsumerConfigurationListener(dir)
+ return dir, nil
}
-//subscribe service from registry , and update the cacheServices
+//subscibe from registry
+func (dir *registryDirectory) Subscribe(url *common.URL) {
+ dir.consumerConfigurationListener.addNotifyListener(dir)
+ dir.referenceConfigurationListener = newReferenceConfigurationListener(dir, url)
+ dir.registry.Subscribe(url, dir)
+}
+
+func (dir *registryDirectory) Notify(event *registry.ServiceEvent) {
+ go dir.update(event)
+}
+
+//subscribe service from registry, and update the cacheServices
func (dir *registryDirectory) update(res *registry.ServiceEvent) {
if res == nil {
return
}
-
logger.Debugf("registry update, result{%s}", res)
-
logger.Debugf("update service name: %s!", res.Service)
-
dir.refreshInvokers(res)
}
func (dir *registryDirectory) refreshInvokers(res *registry.ServiceEvent) {
-
- switch res.Action {
- case remoting.EventTypeAdd:
- //dir.cacheService.EventTypeAdd(res.Path, dir.serviceTTL)
- dir.cacheInvoker(res.Service)
- case remoting.EventTypeDel:
- //dir.cacheService.EventTypeDel(res.Path, dir.serviceTTL)
- dir.uncacheInvoker(res.Service)
- logger.Infof("selector delete service url{%s}", res.Service)
- default:
- return
+ var url *common.URL
+ //judge is override or others
+ if res != nil {
+ url = &res.Service
+ //1.for override url in 2.6.x
+ if url.Protocol == constant.OVERRIDE_PROTOCOL ||
+ url.GetParam(constant.CATEGORY_KEY, constant.DEFAULT_CATEGORY) == constant.CONFIGURATORS_CATEGORY {
+ dir.configurators = append(dir.configurators, extension.GetDefaultConfigurator(url))
+ url = nil
+ } else if url.Protocol == constant.ROUTER_PROTOCOL || //2.for router
+ url.GetParam(constant.CATEGORY_KEY, constant.DEFAULT_CATEGORY) == constant.ROUTER_CATEGORY {
+ url = nil
+ //TODO: router
+ }
+ switch res.Action {
+ case remoting.EventTypeAdd, remoting.EventTypeUpdate:
+ //dir.cacheService.EventTypeAdd(res.Path, dir.serviceTTL)
+ dir.cacheInvoker(url)
+ case remoting.EventTypeDel:
+ //dir.cacheService.EventTypeDel(res.Path, dir.serviceTTL)
+ dir.uncacheInvoker(url)
+ logger.Infof("selector delete service url{%s}", res.Service)
+ default:
+ return
+ }
}
newInvokers := dir.toGroupInvokers()
-
dir.listenerLock.Lock()
defer dir.listenerLock.Unlock()
dir.cacheInvokers = newInvokers
}
func (dir *registryDirectory) toGroupInvokers() []protocol.Invoker {
-
newInvokersList := []protocol.Invoker{}
groupInvokersMap := make(map[string][]protocol.Invoker)
groupInvokersList := []protocol.Invoker{}
@@ -184,22 +178,40 @@
return groupInvokersList
}
-func (dir *registryDirectory) uncacheInvoker(url common.URL) {
+func (dir *registryDirectory) uncacheInvoker(url *common.URL) {
logger.Debugf("service will be deleted in cache invokers: invokers key is %s!", url.Key())
dir.cacheInvokersMap.Delete(url.Key())
}
-func (dir *registryDirectory) cacheInvoker(url common.URL) {
- referenceUrl := dir.GetUrl().SubURL
+func (dir *registryDirectory) cacheInvoker(url *common.URL) {
+ dir.overrideUrl(dir.GetDirectoryUrl())
+ referenceUrl := dir.GetDirectoryUrl().SubURL
+
+ if url == nil && dir.cacheOriginUrl != nil {
+ url = dir.cacheOriginUrl
+ } else {
+ dir.cacheOriginUrl = url
+ }
+ if url == nil {
+ logger.Error("URL is nil ,pls check if service url is subscribe successfully!")
+ return
+ }
//check the url's protocol is equal to the protocol which is configured in reference config or referenceUrl is not care about protocol
if url.Protocol == referenceUrl.Protocol || referenceUrl.Protocol == "" {
- url = common.MergeUrl(url, referenceUrl)
-
- if _, ok := dir.cacheInvokersMap.Load(url.Key()); !ok {
- logger.Debugf("service will be added in cache invokers: invokers key is %s!", url.Key())
- newInvoker := extension.GetProtocol(protocolwrapper.FILTER).Refer(url)
+ newUrl := common.MergeUrl(url, referenceUrl)
+ dir.overrideUrl(newUrl)
+ if cacheInvoker, ok := dir.cacheInvokersMap.Load(newUrl.Key()); !ok {
+ logger.Infof("service will be added in cache invokers: invokers url is %s!", newUrl)
+ newInvoker := extension.GetProtocol(protocolwrapper.FILTER).Refer(*newUrl)
if newInvoker != nil {
- dir.cacheInvokersMap.Store(url.Key(), newInvoker)
+ dir.cacheInvokersMap.Store(newUrl.Key(), newInvoker)
+ }
+ } else {
+ logger.Infof("service will be updated in cache invokers: new invoker url is %s, old invoker url is %s", newUrl, cacheInvoker.(protocol.Invoker).GetUrl())
+ newInvoker := extension.GetProtocol(protocolwrapper.FILTER).Refer(*newUrl)
+ if newInvoker != nil {
+ dir.cacheInvokersMap.Store(newUrl.Key(), newInvoker)
+ cacheInvoker.(protocol.Invoker).Destroy()
}
}
}
@@ -233,3 +245,58 @@
dir.cacheInvokers = []protocol.Invoker{}
})
}
+func (dir *registryDirectory) overrideUrl(targetUrl *common.URL) {
+ doOverrideUrl(dir.configurators, targetUrl)
+ doOverrideUrl(dir.consumerConfigurationListener.Configurators(), targetUrl)
+ doOverrideUrl(dir.referenceConfigurationListener.Configurators(), targetUrl)
+}
+
+func doOverrideUrl(configurators []config_center.Configurator, targetUrl *common.URL) {
+ for _, v := range configurators {
+ v.Configure(targetUrl)
+ }
+}
+
+type referenceConfigurationListener struct {
+ registry.BaseConfigurationListener
+ directory *registryDirectory
+ url *common.URL
+}
+
+func newReferenceConfigurationListener(dir *registryDirectory, url *common.URL) *referenceConfigurationListener {
+ listener := &referenceConfigurationListener{directory: dir, url: url}
+ listener.InitWith(
+ url.EncodedServiceKey()+constant.CONFIGURATORS_SUFFIX,
+ listener,
+ extension.GetDefaultConfiguratorFunc(),
+ )
+ return listener
+}
+
+func (l *referenceConfigurationListener) Process(event *config_center.ConfigChangeEvent) {
+ l.BaseConfigurationListener.Process(event)
+ l.directory.refreshInvokers(nil)
+}
+
+type consumerConfigurationListener struct {
+ registry.BaseConfigurationListener
+ listeners []registry.NotifyListener
+ directory *registryDirectory
+}
+
+func newConsumerConfigurationListener(dir *registryDirectory) *consumerConfigurationListener {
+ listener := &consumerConfigurationListener{directory: dir}
+ listener.InitWith(
+ config.GetConsumerConfig().ApplicationConfig.Name+constant.CONFIGURATORS_SUFFIX,
+ listener,
+ extension.GetDefaultConfiguratorFunc(),
+ )
+ return listener
+}
+func (l *consumerConfigurationListener) addNotifyListener(listener registry.NotifyListener) {
+ l.listeners = append(l.listeners, listener)
+}
+func (l *consumerConfigurationListener) Process(event *config_center.ConfigChangeEvent) {
+ l.BaseConfigurationListener.Process(event)
+ l.directory.refreshInvokers(nil)
+}
diff --git a/registry/directory/directory_test.go b/registry/directory/directory_test.go
index f31165d..b3c1d35 100644
--- a/registry/directory/directory_test.go
+++ b/registry/directory/directory_test.go
@@ -34,12 +34,16 @@
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
+ "github.com/apache/dubbo-go/config"
"github.com/apache/dubbo-go/protocol/invocation"
"github.com/apache/dubbo-go/protocol/protocolwrapper"
"github.com/apache/dubbo-go/registry"
"github.com/apache/dubbo-go/remoting"
)
+func init() {
+ config.SetConsumerConfig(config.ConsumerConfig{ApplicationConfig: &config.ApplicationConfig{Name: "test-application"}})
+}
func TestSubscribe(t *testing.T) {
registryDirectory, _ := normalRegistryDir()
@@ -47,14 +51,15 @@
assert.Len(t, registryDirectory.cacheInvokers, 3)
}
-func TestSubscribe_Delete(t *testing.T) {
- registryDirectory, mockRegistry := normalRegistryDir()
- time.Sleep(1e9)
- assert.Len(t, registryDirectory.cacheInvokers, 3)
- mockRegistry.MockEvent(®istry.ServiceEvent{Action: remoting.EventTypeDel, Service: *common.NewURLWithOptions(common.WithPath("TEST0"), common.WithProtocol("dubbo"))})
- time.Sleep(1e9)
- assert.Len(t, registryDirectory.cacheInvokers, 2)
-}
+////Deprecated! not support delete
+//func TestSubscribe_Delete(t *testing.T) {
+// registryDirectory, mockRegistry := normalRegistryDir()
+// time.Sleep(1e9)
+// assert.Len(t, registryDirectory.cacheInvokers, 3)
+// mockRegistry.MockEvent(®istry.ServiceEvent{Action: remoting.EventTypeDel, Service: *common.NewURLWithOptions(common.WithPath("TEST0"), common.WithProtocol("dubbo"))})
+// time.Sleep(1e9)
+// assert.Len(t, registryDirectory.cacheInvokers, 2)
+//}
func TestSubscribe_InvalidUrl(t *testing.T) {
url, _ := common.NewURL(context.TODO(), "mock://127.0.0.1:1111")
@@ -69,12 +74,12 @@
regurl, _ := common.NewURL(context.TODO(), "mock://127.0.0.1:1111")
suburl, _ := common.NewURL(context.TODO(), "dubbo://127.0.0.1:20000")
- suburl.Params.Set(constant.CLUSTER_KEY, "mock")
+ suburl.SetParam(constant.CLUSTER_KEY, "mock")
regurl.SubURL = &suburl
mockRegistry, _ := registry.NewMockRegistry(&common.URL{})
registryDirectory, _ := NewRegistryDirectory(®url, mockRegistry)
- go registryDirectory.Subscribe(*common.NewURLWithOptions(common.WithPath("testservice")))
+ go registryDirectory.Subscribe(common.NewURLWithOptions(common.WithPath("testservice")))
//for group1
urlmap := url.Values{}
@@ -117,19 +122,82 @@
assert.Equal(t, true, registryDirectory.IsAvailable())
}
+func Test_MergeProviderUrl(t *testing.T) {
+ registryDirectory, mockRegistry := normalRegistryDir(true)
+ providerUrl, _ := common.NewURL(context.TODO(), "dubbo://0.0.0.0:20000/org.apache.dubbo-go.mockService",
+ common.WithParamsValue(constant.CLUSTER_KEY, "mock1"),
+ common.WithParamsValue(constant.GROUP_KEY, "group"),
+ common.WithParamsValue(constant.VERSION_KEY, "1.0.0"))
+ mockRegistry.MockEvent(®istry.ServiceEvent{Action: remoting.EventTypeAdd, Service: providerUrl})
+ time.Sleep(1e9)
+ assert.Len(t, registryDirectory.cacheInvokers, 1)
+ if len(registryDirectory.cacheInvokers) > 0 {
+ assert.Equal(t, "mock", registryDirectory.cacheInvokers[0].GetUrl().GetParam(constant.CLUSTER_KEY, ""))
+ }
-func normalRegistryDir() (*registryDirectory, *registry.MockRegistry) {
+}
+
+func Test_MergeOverrideUrl(t *testing.T) {
+ registryDirectory, mockRegistry := normalRegistryDir(true)
+ providerUrl, _ := common.NewURL(context.TODO(), "dubbo://0.0.0.0:20000/org.apache.dubbo-go.mockService",
+ common.WithParamsValue(constant.CLUSTER_KEY, "mock"),
+ common.WithParamsValue(constant.GROUP_KEY, "group"),
+ common.WithParamsValue(constant.VERSION_KEY, "1.0.0"))
+ mockRegistry.MockEvent(®istry.ServiceEvent{Action: remoting.EventTypeAdd, Service: providerUrl})
+Loop1:
+ for {
+ if len(registryDirectory.cacheInvokers) > 0 {
+ overrideUrl, _ := common.NewURL(context.TODO(), "override://0.0.0.0:20000/org.apache.dubbo-go.mockService",
+ common.WithParamsValue(constant.CLUSTER_KEY, "mock1"),
+ common.WithParamsValue(constant.GROUP_KEY, "group"),
+ common.WithParamsValue(constant.VERSION_KEY, "1.0.0"))
+ mockRegistry.MockEvent(®istry.ServiceEvent{Action: remoting.EventTypeAdd, Service: overrideUrl})
+ Loop2:
+ for {
+ if len(registryDirectory.cacheInvokers) > 0 {
+ if "mock1" == registryDirectory.cacheInvokers[0].GetUrl().GetParam(constant.CLUSTER_KEY, "") {
+ assert.Len(t, registryDirectory.cacheInvokers, 1)
+ assert.True(t, true)
+ break Loop2
+ } else {
+ time.Sleep(500 * time.Millisecond)
+ }
+ }
+ }
+ break Loop1
+ }
+ }
+
+}
+
+func normalRegistryDir(noMockEvent ...bool) (*registryDirectory, *registry.MockRegistry) {
extension.SetProtocol(protocolwrapper.FILTER, protocolwrapper.NewMockProtocolFilter)
url, _ := common.NewURL(context.TODO(), "mock://127.0.0.1:1111")
- suburl, _ := common.NewURL(context.TODO(), "dubbo://127.0.0.1:20000")
+ suburl, _ := common.NewURL(
+ context.TODO(),
+ "dubbo://127.0.0.1:20000/org.apache.dubbo-go.mockService",
+ common.WithParamsValue(constant.CLUSTER_KEY, "mock"),
+ common.WithParamsValue(constant.GROUP_KEY, "group"),
+ common.WithParamsValue(constant.VERSION_KEY, "1.0.0"),
+ )
url.SubURL = &suburl
mockRegistry, _ := registry.NewMockRegistry(&common.URL{})
registryDirectory, _ := NewRegistryDirectory(&url, mockRegistry)
- go registryDirectory.Subscribe(*common.NewURLWithOptions(common.WithPath("testservice")))
- for i := 0; i < 3; i++ {
- mockRegistry.(*registry.MockRegistry).MockEvent(®istry.ServiceEvent{Action: remoting.EventTypeAdd, Service: *common.NewURLWithOptions(common.WithPath("TEST"+strconv.FormatInt(int64(i), 10)), common.WithProtocol("dubbo"))})
+ go registryDirectory.Subscribe(&suburl)
+ if len(noMockEvent) == 0 {
+ for i := 0; i < 3; i++ {
+ mockRegistry.(*registry.MockRegistry).MockEvent(
+ ®istry.ServiceEvent{
+ Action: remoting.EventTypeAdd,
+ Service: *common.NewURLWithOptions(
+ common.WithPath("TEST"+strconv.FormatInt(int64(i), 10)),
+ common.WithProtocol("dubbo"),
+ ),
+ },
+ )
+ }
}
return registryDirectory, mockRegistry.(*registry.MockRegistry)
}
diff --git a/registry/etcdv3/listener.go b/registry/etcdv3/listener.go
index a8f2fac..e0dc099 100644
--- a/registry/etcdv3/listener.go
+++ b/registry/etcdv3/listener.go
@@ -12,16 +12,17 @@
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/logger"
+ "github.com/apache/dubbo-go/config_center"
"github.com/apache/dubbo-go/registry"
"github.com/apache/dubbo-go/remoting"
)
type dataListener struct {
interestedURL []*common.URL
- listener remoting.ConfigurationListener
+ listener config_center.ConfigurationListener
}
-func NewRegistryDataListener(listener remoting.ConfigurationListener) *dataListener {
+func NewRegistryDataListener(listener config_center.ConfigurationListener) *dataListener {
return &dataListener{listener: listener, interestedURL: []*common.URL{}}
}
@@ -40,7 +41,13 @@
for _, v := range l.interestedURL {
if serviceURL.URLEqual(*v) {
- l.listener.Process(&remoting.ConfigChangeEvent{Key: eventType.Path, Value: serviceURL, ConfigType: eventType.Action})
+ l.listener.Process(
+ &config_center.ConfigChangeEvent{
+ Key: eventType.Path,
+ Value: serviceURL,
+ ConfigType: eventType.Action,
+ },
+ )
return true
}
}
@@ -50,15 +57,15 @@
type configurationListener struct {
registry *etcdV3Registry
- events chan *remoting.ConfigChangeEvent
+ events chan *config_center.ConfigChangeEvent
}
func NewConfigurationListener(reg *etcdV3Registry) *configurationListener {
// add a new waiter
reg.wg.Add(1)
- return &configurationListener{registry: reg, events: make(chan *remoting.ConfigChangeEvent, 32)}
+ return &configurationListener{registry: reg, events: make(chan *config_center.ConfigChangeEvent, 32)}
}
-func (l *configurationListener) Process(configType *remoting.ConfigChangeEvent) {
+func (l *configurationListener) Process(configType *config_center.ConfigChangeEvent) {
l.events <- configType
}
diff --git a/registry/etcdv3/listener_test.go b/registry/etcdv3/listener_test.go
index 0ac8fc4..00024d2 100644
--- a/registry/etcdv3/listener_test.go
+++ b/registry/etcdv3/listener_test.go
@@ -2,6 +2,7 @@
import (
"context"
+ "github.com/apache/dubbo-go/config_center"
"testing"
"time"
)
@@ -68,4 +69,4 @@
type MockDataListener struct{}
-func (*MockDataListener) Process(configType *remoting.ConfigChangeEvent) {}
+func (*MockDataListener) Process(configType *config_center.ConfigChangeEvent) {}
diff --git a/registry/etcdv3/registry.go b/registry/etcdv3/registry.go
index 5802142..8bb1ff4 100644
--- a/registry/etcdv3/registry.go
+++ b/registry/etcdv3/registry.go
@@ -30,7 +30,10 @@
localIP = ""
)
-const Name = "etcdv3"
+const (
+ Name = "etcdv3"
+ RegistryConnDelay = 3
+)
func init() {
processID = fmt.Sprintf("%d", os.Getpid())
@@ -257,10 +260,11 @@
}
params := url.Values{}
- for k, v := range svc.Params {
- params[k] = v
- }
+ svc.RangeParams(func(key, value string) bool {
+ params[key] = []string{value}
+ return true
+ })
params.Add("pid", processID)
params.Add("ip", localIP)
params.Add("anyhost", "true")
@@ -292,7 +296,7 @@
return nil
}
-func (r *etcdV3Registry) Subscribe(svc common.URL) (registry.Listener, error) {
+func (r *etcdV3Registry) subscribe(svc *common.URL) (registry.Listener, error) {
var (
configListener *configurationListener
@@ -318,8 +322,44 @@
}
//register the svc to dataListener
- r.dataListener.AddInterestedURL(&svc)
- go r.listener.ListenServiceEvent(fmt.Sprintf("/dubbo/%s/providers", svc.Service()), r.dataListener)
+ r.dataListener.AddInterestedURL(svc)
+ for _, v := range strings.Split(svc.GetParam(constant.CATEGORY_KEY, constant.DEFAULT_CATEGORY), ",") {
+ go r.listener.ListenServiceEvent(fmt.Sprintf("/dubbo/%s/"+v, svc.Service()), r.dataListener)
+ }
return configListener, nil
}
+
+//subscibe from registry
+func (r *etcdV3Registry) Subscribe(url *common.URL, notifyListener registry.NotifyListener) {
+ for {
+ if !r.IsAvailable() {
+ logger.Warnf("event listener game over.")
+ return
+ }
+
+ listener, err := r.subscribe(url)
+ if err != nil {
+ if !r.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()
+ return
+ } else {
+ logger.Infof("update begin, service event: %v", serviceEvent.String())
+ notifyListener.Notify(serviceEvent)
+ }
+
+ }
+
+ }
+}
diff --git a/registry/etcdv3/registry_test.go b/registry/etcdv3/registry_test.go
index 26204c7..6da9ad9 100644
--- a/registry/etcdv3/registry_test.go
+++ b/registry/etcdv3/registry_test.go
@@ -63,11 +63,11 @@
}
//consumer register
- regurl.Params.Set(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER))
+ regurl.SetParam(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER))
reg2 := initRegistry(t)
reg2.Register(url)
- listener, err := reg2.Subscribe(url)
+ listener, err := reg2.subscribe(&url)
if err != nil {
t.Fatal(err)
}
@@ -85,7 +85,7 @@
url, _ := common.NewURL(context.Background(), "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParamsValue(constant.CLUSTER_KEY, "mock"), common.WithMethods([]string{"GetUser", "AddUser"}))
reg := initRegistry(t)
- _, err := reg.Subscribe(url)
+ _, err := reg.subscribe(&url)
if err != nil {
t.Fatal(err)
}
diff --git a/registry/mock_registry.go b/registry/mock_registry.go
index 1fc700e..512c452 100644
--- a/registry/mock_registry.go
+++ b/registry/mock_registry.go
@@ -18,11 +18,16 @@
package registry
import (
+ "time"
+)
+
+import (
"go.uber.org/atomic"
)
import (
"github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/common/logger"
)
type MockRegistry struct {
@@ -53,9 +58,43 @@
return common.URL{}
}
-func (r *MockRegistry) Subscribe(common.URL) (Listener, error) {
+func (r *MockRegistry) subscribe(*common.URL) (Listener, error) {
return r.listener, nil
}
+func (r *MockRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) {
+ go func() {
+ for {
+ if !r.IsAvailable() {
+ logger.Warnf("event listener game over.")
+ time.Sleep(time.Duration(3) * time.Second)
+ return
+ }
+
+ listener, err := r.subscribe(url)
+ if err != nil {
+ if !r.IsAvailable() {
+ logger.Warnf("event listener game over.")
+ return
+ }
+ time.Sleep(time.Duration(3) * time.Second)
+ continue
+ }
+
+ for {
+ if serviceEvent, err := listener.Next(); err != nil {
+ listener.Close()
+ time.Sleep(time.Duration(3) * time.Second)
+ return
+ } else {
+ logger.Infof("update begin, service event: %v", serviceEvent.String())
+ notifyListener.Notify(serviceEvent)
+ }
+
+ }
+
+ }
+ }()
+}
type listener struct {
count int64
diff --git a/registry/nacos/listener.go b/registry/nacos/listener.go
index c42abd0..1f264ec 100644
--- a/registry/nacos/listener.go
+++ b/registry/nacos/listener.go
@@ -19,6 +19,7 @@
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/logger"
+ "github.com/apache/dubbo-go/config_center"
"github.com/apache/dubbo-go/registry"
"github.com/apache/dubbo-go/remoting"
)
@@ -26,7 +27,7 @@
type nacosListener struct {
namingClient naming_client.INamingClient
listenUrl common.URL
- events chan *remoting.ConfigChangeEvent
+ events chan *config_center.ConfigChangeEvent
instanceMap map[string]model.Instance
cacheLock sync.Mutex
done chan struct{}
@@ -36,7 +37,7 @@
func NewNacosListener(url common.URL, namingClient naming_client.INamingClient) (*nacosListener, error) {
listener := &nacosListener{
namingClient: namingClient,
- listenUrl: url, events: make(chan *remoting.ConfigChangeEvent, 32),
+ listenUrl: url, events: make(chan *config_center.ConfigChangeEvent, 32),
instanceMap: map[string]model.Instance{},
done: make(chan struct{}),
}
@@ -134,20 +135,20 @@
for i := range addInstances {
newUrl := generateUrl(addInstances[i])
if newUrl != nil {
- nl.process(&remoting.ConfigChangeEvent{Value: *newUrl, ConfigType: remoting.EventTypeAdd})
+ nl.process(&config_center.ConfigChangeEvent{Value: *newUrl, ConfigType: remoting.EventTypeAdd})
}
}
for i := range delInstances {
newUrl := generateUrl(delInstances[i])
if newUrl != nil {
- nl.process(&remoting.ConfigChangeEvent{Value: *newUrl, ConfigType: remoting.EventTypeDel})
+ nl.process(&config_center.ConfigChangeEvent{Value: *newUrl, ConfigType: remoting.EventTypeDel})
}
}
for i := range updateInstances {
newUrl := generateUrl(updateInstances[i])
if newUrl != nil {
- nl.process(&remoting.ConfigChangeEvent{Value: *newUrl, ConfigType: remoting.EvnetTypeUpdate})
+ nl.process(&config_center.ConfigChangeEvent{Value: *newUrl, ConfigType: remoting.EventTypeUpdate})
}
}
}
@@ -175,7 +176,7 @@
return nl.namingClient.Unsubscribe(nl.subscribeParam)
}
-func (nl *nacosListener) process(configType *remoting.ConfigChangeEvent) {
+func (nl *nacosListener) process(configType *config_center.ConfigChangeEvent) {
nl.events <- configType
}
diff --git a/registry/nacos/registry.go b/registry/nacos/registry.go
index bf86ead..f1a7826 100644
--- a/registry/nacos/registry.go
+++ b/registry/nacos/registry.go
@@ -7,6 +7,7 @@
"strings"
"time"
)
+
import (
"github.com/nacos-group/nacos-sdk-go/clients"
"github.com/nacos-group/nacos-sdk-go/clients/naming_client"
@@ -19,6 +20,7 @@
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
+ "github.com/apache/dubbo-go/common/logger"
"github.com/apache/dubbo-go/common/utils"
"github.com/apache/dubbo-go/registry"
)
@@ -27,6 +29,10 @@
localIP = ""
)
+const (
+ RegistryConnDelay = 3
+)
+
func init() {
localIP, _ = utils.GetLocalIP()
extension.SetRegistry(constant.NACOS_KEY, newNacosRegistry)
@@ -119,10 +125,13 @@
func createRegisterParam(url common.URL, serviceName string) vo.RegisterInstanceParam {
category := getCategory(url)
- params := make(map[string]string, len(url.Params)+3)
- for k := range url.Params {
- params[k] = url.Params.Get(k)
- }
+ params := make(map[string]string)
+
+ url.RangeParams(func(key, value string) bool {
+ params[key] = value
+ return true
+ })
+
params[constant.NACOS_CATEGORY_KEY] = category
params[constant.NACOS_PROTOCOL_KEY] = url.Protocol
params[constant.NACOS_PATH_KEY] = url.Path
@@ -159,10 +168,43 @@
return nil
}
-func (nr *nacosRegistry) Subscribe(conf common.URL) (registry.Listener, error) {
- return NewNacosListener(conf, nr.namingClient)
+func (nr *nacosRegistry) subscribe(conf *common.URL) (registry.Listener, error) {
+ return NewNacosListener(*conf, nr.namingClient)
}
+//subscibe from registry
+func (r *nacosRegistry) Subscribe(url *common.URL, notifyListener registry.NotifyListener) {
+ for {
+ if !r.IsAvailable() {
+ logger.Warnf("event listener game over.")
+ return
+ }
+
+ listener, err := r.subscribe(url)
+ if err != nil {
+ if !r.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()
+ return
+ } else {
+ logger.Infof("update begin, service event: %v", serviceEvent.String())
+ notifyListener.Notify(serviceEvent)
+ }
+
+ }
+
+ }
+}
func (nr *nacosRegistry) GetUrl() common.URL {
return *nr.URL
}
diff --git a/registry/nacos/registry_test.go b/registry/nacos/registry_test.go
index 9ce9dcf..023ff78 100644
--- a/registry/nacos/registry_test.go
+++ b/registry/nacos/registry_test.go
@@ -66,9 +66,9 @@
return
}
- regurl.Params.Set(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER))
+ regurl.SetParam(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER))
reg2, _ := newNacosRegistry(®url)
- listener, err := reg2.Subscribe(url)
+ listener, err := reg2.(*nacosRegistry).subscribe(&url)
assert.Nil(t, err)
if err != nil {
t.Errorf("subscribe error:%s \n", err.Error())
@@ -111,9 +111,9 @@
return
}
- regurl.Params.Set(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER))
+ regurl.SetParam(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER))
reg2, _ := newNacosRegistry(®url)
- listener, err := reg2.Subscribe(url1)
+ listener, err := reg2.(*nacosRegistry).subscribe(&url1)
assert.Nil(t, err)
if err != nil {
t.Errorf("subscribe error:%s \n", err.Error())
@@ -162,7 +162,7 @@
urlMap.Set(constant.NACOS_PATH_KEY, "")
url1, _ := common.NewURL(context.TODO(), "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider2", common.WithParams(urlMap), common.WithMethods([]string{"GetUser", "AddUser"}))
reg, _ := newNacosRegistry(®url)
- listener, err := reg.Subscribe(url1)
+ listener, err := reg.(*nacosRegistry).subscribe(&url1)
assert.Nil(t, err)
if err != nil {
t.Errorf("subscribe error:%s \n", err.Error())
diff --git a/registry/protocol/protocol.go b/registry/protocol/protocol.go
index ff33b5f..c746cf8 100644
--- a/registry/protocol/protocol.go
+++ b/registry/protocol/protocol.go
@@ -18,18 +18,28 @@
package protocol
import (
+ "strings"
"sync"
)
import (
+ "github.com/dubbogo/gost/container"
+)
+
+import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/common/logger"
+ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
+ "github.com/apache/dubbo-go/config"
+ "github.com/apache/dubbo-go/config_center"
+ _ "github.com/apache/dubbo-go/config_center/configurator"
"github.com/apache/dubbo-go/protocol"
"github.com/apache/dubbo-go/protocol/protocolwrapper"
"github.com/apache/dubbo-go/registry"
directory2 "github.com/apache/dubbo-go/registry/directory"
+ "github.com/apache/dubbo-go/remoting"
)
var (
@@ -39,20 +49,31 @@
type registryProtocol struct {
invokers []protocol.Invoker
// Registry Map<RegistryAddress, Registry>
- registries sync.Map
+ registries *sync.Map
//To solve the problem of RMI repeated exposure port conflicts, the services that have been exposed are no longer exposed.
//providerurl <--> exporter
- bounds sync.Map
+ bounds *sync.Map
+ overrideListeners *sync.Map
+ serviceConfigurationListeners *sync.Map
+ providerConfigurationListener *providerConfigurationListener
+ once sync.Once
}
func init() {
extension.SetProtocol("registry", GetProtocol)
}
+func getCacheKey(url *common.URL) string {
+ newUrl := url.Clone()
+ delKeys := container.NewSet("dynamic", "enabled")
+ newUrl.RemoveParams(delKeys)
+ return newUrl.String()
+}
+
func newRegistryProtocol() *registryProtocol {
return ®istryProtocol{
- registries: sync.Map{},
- bounds: sync.Map{},
+ registries: &sync.Map{},
+ bounds: &sync.Map{},
}
}
func getRegistry(regUrl *common.URL) registry.Registry {
@@ -63,6 +84,11 @@
}
return reg
}
+func (proto *registryProtocol) initConfigurationListeners() {
+ proto.overrideListeners = &sync.Map{}
+ proto.serviceConfigurationListeners = &sync.Map{}
+ proto.providerConfigurationListener = newProviderConfigurationListener(proto.overrideListeners)
+}
func (proto *registryProtocol) Refer(url common.URL) protocol.Invoker {
var registryUrl = url
@@ -71,6 +97,7 @@
protocol := registryUrl.GetParam(constant.REGISTRY_KEY, "")
registryUrl.Protocol = protocol
}
+
var reg registry.Registry
if regI, loaded := proto.registries.Load(registryUrl.Key()); !loaded {
@@ -83,14 +110,16 @@
//new registry directory for store service url from registry
directory, err := directory2.NewRegistryDirectory(®istryUrl, reg)
if err != nil {
- logger.Errorf("consumer service %v create registry directory error, error message is %s, and will return nil invoker!", serviceUrl.String(), err.Error())
+ logger.Errorf("consumer service %v create registry directory error, error message is %s, and will return nil invoker!",
+ serviceUrl.String(), err.Error())
return nil
}
err = reg.Register(*serviceUrl)
if err != nil {
- logger.Errorf("consumer service %v register registry %v error, error message is %s", serviceUrl.String(), registryUrl.String(), err.Error())
+ 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,25 +130,39 @@
}
func (proto *registryProtocol) Export(invoker protocol.Invoker) protocol.Exporter {
- registryUrl := proto.getRegistryUrl(invoker)
- providerUrl := proto.getProviderUrl(invoker)
+
+ proto.once.Do(func() {
+ proto.initConfigurationListeners()
+ })
+ registryUrl := getRegistryUrl(invoker)
+ providerUrl := getProviderUrl(invoker)
+
+ overriderUrl := getSubscribedOverrideUrl(providerUrl)
+ // Deprecated! subscribe to override rules in 2.6.x or before.
+ overrideSubscribeListener := newOverrideSubscribeListener(overriderUrl, invoker, proto)
+ proto.overrideListeners.Store(overriderUrl, overrideSubscribeListener)
+ proto.providerConfigurationListener.OverrideUrl(providerUrl)
+ serviceConfigurationListener := newServiceConfigurationListener(overrideSubscribeListener, providerUrl)
+ proto.serviceConfigurationListeners.Store(providerUrl.ServiceKey(), serviceConfigurationListener)
+ serviceConfigurationListener.OverrideUrl(providerUrl)
var reg registry.Registry
if regI, loaded := proto.registries.Load(registryUrl.Key()); !loaded {
- reg = getRegistry(®istryUrl)
+ reg = getRegistry(registryUrl)
proto.registries.Store(registryUrl.Key(), reg)
} else {
reg = regI.(registry.Registry)
}
- err := reg.Register(providerUrl)
+ err := reg.Register(*providerUrl)
if err != nil {
- logger.Errorf("provider service %v register registry %v error, error message is %s", providerUrl.Key(), registryUrl.Key(), err.Error())
+ logger.Errorf("provider service %v register registry %v error, error message is %s",
+ providerUrl.Key(), registryUrl.Key(), err.Error())
return nil
}
- key := providerUrl.Key()
+ key := getCacheKey(providerUrl)
logger.Infof("The cached exporter keys is %v !", key)
cachedExporter, loaded := proto.bounds.Load(key)
if loaded {
@@ -131,9 +174,125 @@
logger.Infof("The exporter has not been cached, and will return a new exporter!")
}
+ go reg.Subscribe(overriderUrl, overrideSubscribeListener)
return cachedExporter.(protocol.Exporter)
}
+func (proto *registryProtocol) reExport(invoker protocol.Invoker, newUrl *common.URL) {
+ url := getProviderUrl(invoker)
+ key := getCacheKey(url)
+ if oldExporter, loaded := proto.bounds.Load(key); loaded {
+ wrappedNewInvoker := newWrappedInvoker(invoker, newUrl)
+ oldExporter.(protocol.Exporter).Unexport()
+ proto.bounds.Delete(key)
+ proto.Export(wrappedNewInvoker)
+ //TODO: unregister & unsubscribe
+
+ }
+}
+
+type overrideSubscribeListener struct {
+ url *common.URL
+ originInvoker protocol.Invoker
+ protocol *registryProtocol
+ configurator config_center.Configurator
+}
+
+func newOverrideSubscribeListener(overriderUrl *common.URL, invoker protocol.Invoker, proto *registryProtocol) *overrideSubscribeListener {
+ return &overrideSubscribeListener{url: overriderUrl, originInvoker: invoker, protocol: proto}
+}
+func (nl *overrideSubscribeListener) Notify(event *registry.ServiceEvent) {
+ if isMatched(&(event.Service), nl.url) && event.Action == remoting.EventTypeAdd {
+ nl.configurator = extension.GetDefaultConfigurator(&(event.Service))
+ nl.doOverrideIfNecessary()
+ }
+}
+func (nl *overrideSubscribeListener) doOverrideIfNecessary() {
+ providerUrl := getProviderUrl(nl.originInvoker)
+ key := getCacheKey(providerUrl)
+ if exporter, ok := nl.protocol.bounds.Load(key); ok {
+ currentUrl := exporter.(protocol.Exporter).GetInvoker().GetUrl()
+ // Compatible with the 2.6.x
+ if nl.configurator != nil {
+ nl.configurator.Configure(providerUrl)
+ }
+ // provider application level management in 2.7.x
+ for _, v := range nl.protocol.providerConfigurationListener.Configurators() {
+ v.Configure(providerUrl)
+ }
+ // provider service level management in 2.7.x
+ if serviceListener, ok := nl.protocol.serviceConfigurationListeners.Load(providerUrl.ServiceKey()); ok {
+ listener := serviceListener.(*serviceConfigurationListener)
+ for _, v := range listener.Configurators() {
+ v.Configure(providerUrl)
+ }
+ }
+
+ if currentUrl.String() != providerUrl.String() {
+ newRegUrl := nl.originInvoker.GetUrl()
+ setProviderUrl(&newRegUrl, providerUrl)
+ nl.protocol.reExport(nl.originInvoker, &newRegUrl)
+ }
+ }
+}
+
+func isMatched(providerUrl *common.URL, consumerUrl *common.URL) bool {
+ // Compatible with the 2.6.x
+ if len(providerUrl.GetParam(constant.CATEGORY_KEY, "")) == 0 &&
+ providerUrl.Protocol == constant.OVERRIDE_PROTOCOL {
+ providerUrl.AddParam(constant.CATEGORY_KEY, constant.CONFIGURATORS_CATEGORY)
+ }
+ consumerInterface := consumerUrl.GetParam(constant.INTERFACE_KEY, consumerUrl.Path)
+ providerInterface := providerUrl.GetParam(constant.INTERFACE_KEY, providerUrl.Path)
+
+ if !(constant.ANY_VALUE == consumerInterface ||
+ constant.ANY_VALUE == providerInterface ||
+ providerInterface == consumerInterface) {
+ return false
+ }
+
+ if !isMatchCategory(providerUrl.GetParam(constant.CATEGORY_KEY, constant.DEFAULT_CATEGORY),
+ consumerUrl.GetParam(constant.CATEGORY_KEY, constant.DEFAULT_CATEGORY)) {
+ return false
+ }
+
+ if !providerUrl.GetParamBool(constant.ENABLED_KEY, true) &&
+ consumerUrl.GetParam(constant.ENABLED_KEY, "") != constant.ANY_VALUE {
+ return false
+ }
+ consumerGroup := consumerUrl.GetParam(constant.GROUP_KEY, "")
+ consumerVersion := consumerUrl.GetParam(constant.VERSION_KEY, "")
+ consumerClassifier := consumerUrl.GetParam(constant.CLASSIFIER_KEY, "")
+
+ providerGroup := providerUrl.GetParam(constant.GROUP_KEY, "")
+ providerVersion := providerUrl.GetParam(constant.VERSION_KEY, "")
+ providerClassifier := providerUrl.GetParam(constant.CLASSIFIER_KEY, "")
+ //todo: public static boolean isContains(String values, String value) {
+ // return isNotEmpty(values) && isContains(COMMA_SPLIT_PATTERN.split(values), value);
+ // }
+ return (consumerGroup == constant.ANY_VALUE || consumerGroup == providerGroup ||
+ strings.Contains(consumerGroup, providerGroup)) && (consumerVersion == constant.ANY_VALUE ||
+ consumerVersion == providerVersion) && (len(consumerClassifier) == 0 ||
+ consumerClassifier == constant.ANY_VALUE || consumerClassifier == providerClassifier)
+}
+func isMatchCategory(category string, categories string) bool {
+ if len(categories) == 0 {
+ return category == constant.DEFAULT_CATEGORY
+ } else if strings.Contains(categories, constant.ANY_VALUE) {
+ return true
+ } else if strings.Contains(categories, constant.REMOVE_VALUE_PREFIX) {
+ return !strings.Contains(categories, constant.REMOVE_VALUE_PREFIX+category)
+ } else {
+ return strings.Contains(categories, category)
+ }
+}
+func getSubscribedOverrideUrl(providerUrl *common.URL) *common.URL {
+ newUrl := providerUrl.Clone()
+ newUrl.Protocol = constant.PROVIDER_PROTOCOL
+ newUrl.SetParam(constant.CATEGORY_KEY, constant.CONFIGURATORS_CATEGORY)
+ newUrl.SetParam(constant.CHECK_KEY, "false")
+ return newUrl
+}
func (proto *registryProtocol) Destroy() {
for _, ivk := range proto.invokers {
@@ -158,7 +317,7 @@
})
}
-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
@@ -166,12 +325,16 @@
protocol := url.GetParam(constant.REGISTRY_KEY, "")
url.Protocol = protocol
}
- return url
+ return &url
}
-func (*registryProtocol) getProviderUrl(invoker protocol.Invoker) common.URL {
+func getProviderUrl(invoker protocol.Invoker) *common.URL {
url := invoker.GetUrl()
- return *url.SubURL
+ //be careful params maps in url is map type
+ return url.SubURL.Clone()
+}
+func setProviderUrl(regURL *common.URL, providerURL *common.URL) {
+ regURL.SubURL = providerURL
}
func GetProtocol() protocol.Protocol {
@@ -183,20 +346,63 @@
type wrappedInvoker struct {
invoker protocol.Invoker
- url common.URL
protocol.BaseInvoker
}
-func newWrappedInvoker(invoker protocol.Invoker, url common.URL) *wrappedInvoker {
+func newWrappedInvoker(invoker protocol.Invoker, url *common.URL) *wrappedInvoker {
return &wrappedInvoker{
invoker: invoker,
- url: url,
- BaseInvoker: *protocol.NewBaseInvoker(common.URL{}),
+ BaseInvoker: *protocol.NewBaseInvoker(*url),
}
}
-func (ivk *wrappedInvoker) GetUrl() common.URL {
- return ivk.url
+
+func (ivk *wrappedInvoker) Invoke(invocation protocol.Invocation) protocol.Result {
+ // get right url
+ ivk.invoker.(*proxy_factory.ProxyInvoker).BaseInvoker = *protocol.NewBaseInvoker(ivk.GetUrl())
+ return ivk.invoker.Invoke(invocation)
}
-func (ivk *wrappedInvoker) getInvoker() protocol.Invoker {
- return ivk.invoker
+
+type providerConfigurationListener struct {
+ registry.BaseConfigurationListener
+ overrideListeners *sync.Map
+}
+
+func newProviderConfigurationListener(overrideListeners *sync.Map) *providerConfigurationListener {
+ listener := &providerConfigurationListener{}
+ listener.overrideListeners = overrideListeners
+ listener.InitWith(
+ config.GetProviderConfig().ApplicationConfig.Name+constant.CONFIGURATORS_SUFFIX,
+ listener,
+ extension.GetDefaultConfiguratorFunc(),
+ )
+ return listener
+}
+
+func (listener *providerConfigurationListener) Process(event *config_center.ConfigChangeEvent) {
+ listener.BaseConfigurationListener.Process(event)
+ listener.overrideListeners.Range(func(key, value interface{}) bool {
+ value.(*overrideSubscribeListener).doOverrideIfNecessary()
+ return true
+ })
+}
+
+type serviceConfigurationListener struct {
+ registry.BaseConfigurationListener
+ overrideListener *overrideSubscribeListener
+ providerUrl *common.URL
+}
+
+func newServiceConfigurationListener(overrideListener *overrideSubscribeListener, providerUrl *common.URL) *serviceConfigurationListener {
+ listener := &serviceConfigurationListener{overrideListener: overrideListener, providerUrl: providerUrl}
+ listener.InitWith(
+ providerUrl.EncodedServiceKey()+constant.CONFIGURATORS_SUFFIX,
+ listener,
+ extension.GetDefaultConfiguratorFunc(),
+ )
+ return listener
+}
+
+func (listener *serviceConfigurationListener) Process(event *config_center.ConfigChangeEvent) {
+ listener.BaseConfigurationListener.Process(event)
+ listener.overrideListener.doOverrideIfNecessary()
}
diff --git a/registry/protocol/protocol_test.go b/registry/protocol/protocol_test.go
index 418f1f6..0c19da5 100644
--- a/registry/protocol/protocol_test.go
+++ b/registry/protocol/protocol_test.go
@@ -20,6 +20,7 @@
import (
"context"
"testing"
+ "time"
)
import (
@@ -29,13 +30,21 @@
import (
cluster "github.com/apache/dubbo-go/cluster/cluster_impl"
"github.com/apache/dubbo-go/common"
+ common_cfg "github.com/apache/dubbo-go/common/config"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
+ "github.com/apache/dubbo-go/config"
+ "github.com/apache/dubbo-go/config_center"
+ "github.com/apache/dubbo-go/config_center/configurator"
"github.com/apache/dubbo-go/protocol"
"github.com/apache/dubbo-go/protocol/protocolwrapper"
"github.com/apache/dubbo-go/registry"
+ "github.com/apache/dubbo-go/remoting"
)
+func init() {
+ config.SetProviderConfig(config.ProviderConfig{ApplicationConfig: &config.ApplicationConfig{Name: "test-application"}})
+}
func referNormal(t *testing.T, regProtocol *registryProtocol) {
extension.SetProtocol("registry", GetProtocol)
extension.SetRegistry("mock", registry.NewMockRegistry)
@@ -43,7 +52,11 @@
extension.SetCluster("mock", cluster.NewMockCluster)
url, _ := common.NewURL(context.TODO(), "mock://127.0.0.1:1111")
- suburl, _ := common.NewURL(context.TODO(), "dubbo://127.0.0.1:20000//", common.WithParamsValue(constant.CLUSTER_KEY, "mock"))
+ suburl, _ := common.NewURL(
+ context.TODO(),
+ "dubbo://127.0.0.1:20000//",
+ common.WithParamsValue(constant.CLUSTER_KEY, "mock"),
+ )
url.SubURL = &suburl
@@ -53,6 +66,9 @@
}
func TestRefer(t *testing.T) {
+ config.SetConsumerConfig(
+ config.ConsumerConfig{
+ ApplicationConfig: &config.ApplicationConfig{Name: "test-application"}})
regProtocol := newRegistryProtocol()
referNormal(t, regProtocol)
}
@@ -61,7 +77,11 @@
regProtocol := newRegistryProtocol()
referNormal(t, regProtocol)
url2, _ := common.NewURL(context.TODO(), "mock://127.0.0.1:2222")
- suburl2, _ := common.NewURL(context.TODO(), "dubbo://127.0.0.1:20000//", common.WithParamsValue(constant.CLUSTER_KEY, "mock"))
+ suburl2, _ := common.NewURL(
+ context.TODO(),
+ "dubbo://127.0.0.1:20000//",
+ common.WithParamsValue(constant.CLUSTER_KEY, "mock"),
+ )
url2.SubURL = &suburl2
@@ -79,7 +99,11 @@
referNormal(t, regProtocol)
url2, _ := common.NewURL(context.TODO(), "mock://127.0.0.1:1111")
- suburl2, _ := common.NewURL(context.TODO(), "dubbo://127.0.0.1:20000//", common.WithParamsValue(constant.CLUSTER_KEY, "mock"))
+ suburl2, _ := common.NewURL(
+ context.TODO(),
+ "dubbo://127.0.0.1:20000//",
+ common.WithParamsValue(constant.CLUSTER_KEY, "mock"),
+ )
url2.SubURL = &suburl2
@@ -92,12 +116,18 @@
assert.Equal(t, count, 1)
}
-func exporterNormal(t *testing.T, regProtocol *registryProtocol) {
+func exporterNormal(t *testing.T, regProtocol *registryProtocol) *common.URL {
extension.SetProtocol("registry", GetProtocol)
extension.SetRegistry("mock", registry.NewMockRegistry)
extension.SetProtocol(protocolwrapper.FILTER, protocolwrapper.NewMockProtocolFilter)
url, _ := common.NewURL(context.TODO(), "mock://127.0.0.1:1111")
- suburl, _ := common.NewURL(context.TODO(), "dubbo://127.0.0.1:20000//", common.WithParamsValue(constant.CLUSTER_KEY, "mock"))
+ suburl, _ := common.NewURL(
+ context.TODO(),
+ "dubbo://127.0.0.1:20000/org.apache.dubbo-go.mockService",
+ common.WithParamsValue(constant.CLUSTER_KEY, "mock"),
+ common.WithParamsValue(constant.GROUP_KEY, "group"),
+ common.WithParamsValue(constant.VERSION_KEY, "1.0.0"),
+ )
url.SubURL = &suburl
invoker := protocol.NewBaseInvoker(url)
@@ -105,9 +135,11 @@
assert.IsType(t, &protocol.BaseExporter{}, exporter)
assert.Equal(t, exporter.GetInvoker().GetUrl().String(), suburl.String())
+ return &url
}
func TestExporter(t *testing.T) {
+
regProtocol := newRegistryProtocol()
exporterNormal(t, regProtocol)
}
@@ -117,7 +149,11 @@
exporterNormal(t, regProtocol)
url2, _ := common.NewURL(context.TODO(), "mock://127.0.0.1:2222")
- suburl2, _ := common.NewURL(context.TODO(), "jsonrpc://127.0.0.1:20000//", common.WithParamsValue(constant.CLUSTER_KEY, "mock"))
+ suburl2, _ := common.NewURL(
+ context.TODO(),
+ "jsonrpc://127.0.0.1:20000//",
+ common.WithParamsValue(constant.CLUSTER_KEY, "mock"),
+ )
url2.SubURL = &suburl2
invoker2 := protocol.NewBaseInvoker(url2)
@@ -143,7 +179,13 @@
exporterNormal(t, regProtocol)
url2, _ := common.NewURL(context.TODO(), "mock://127.0.0.1:1111")
- suburl2, _ := common.NewURL(context.TODO(), "dubbo://127.0.0.1:20000//", common.WithParamsValue(constant.CLUSTER_KEY, "mock"))
+ suburl2, _ := common.NewURL(
+ context.TODO(),
+ "dubbo://127.0.0.1:20000/org.apache.dubbo-go.mockService",
+ common.WithParamsValue(constant.CLUSTER_KEY, "mock"),
+ common.WithParamsValue(constant.GROUP_KEY, "group"),
+ common.WithParamsValue(constant.VERSION_KEY, "1.0.0"),
+ )
url2.SubURL = &suburl2
invoker2 := protocol.NewBaseInvoker(url2)
@@ -186,3 +228,66 @@
})
assert.Equal(t, count2, 0)
}
+
+func TestExportWithOverrideListener(t *testing.T) {
+ extension.SetDefaultConfigurator(configurator.NewMockConfigurator)
+
+ regProtocol := newRegistryProtocol()
+ url := exporterNormal(t, regProtocol)
+ var reg *registry.MockRegistry
+ if regI, loaded := regProtocol.registries.Load(url.Key()); loaded {
+ reg = regI.(*registry.MockRegistry)
+ } else {
+ assert.Fail(t, "regProtocol.registries.Load can not be loaded")
+ return
+ }
+ overrideUrl, _ := common.NewURL(
+ context.Background(),
+ "override://0:0:0:0/org.apache.dubbo-go.mockService?cluster=mock1&&group=group&&version=1.0.0",
+ )
+ event := ®istry.ServiceEvent{Action: remoting.EventTypeAdd, Service: overrideUrl}
+ reg.MockEvent(event)
+ time.Sleep(1e9)
+ newUrl := url.SubURL.Clone()
+ newUrl.SetParam(constant.CLUSTER_KEY, "mock1")
+ v2, _ := regProtocol.bounds.Load(getCacheKey(newUrl))
+ assert.NotNil(t, v2)
+}
+
+func TestExportWithServiceConfig(t *testing.T) {
+ extension.SetDefaultConfigurator(configurator.NewMockConfigurator)
+ ccUrl, _ := common.NewURL(context.TODO(), "mock://127.0.0.1:1111")
+ dc, _ := (&config_center.MockDynamicConfigurationFactory{}).GetDynamicConfiguration(&ccUrl)
+ common_cfg.GetEnvInstance().SetDynamicConfiguration(dc)
+ regProtocol := newRegistryProtocol()
+ url := exporterNormal(t, regProtocol)
+ if _, loaded := regProtocol.registries.Load(url.Key()); !loaded {
+ assert.Fail(t, "regProtocol.registries.Load can not be loaded")
+ return
+ }
+ dc.(*config_center.MockDynamicConfiguration).MockServiceConfigEvent()
+
+ newUrl := url.SubURL.Clone()
+ newUrl.SetParam(constant.CLUSTER_KEY, "mock1")
+ v2, _ := regProtocol.bounds.Load(getCacheKey(newUrl))
+ assert.NotNil(t, v2)
+}
+
+func TestExportWithApplicationConfig(t *testing.T) {
+ extension.SetDefaultConfigurator(configurator.NewMockConfigurator)
+ ccUrl, _ := common.NewURL(context.TODO(), "mock://127.0.0.1:1111")
+ dc, _ := (&config_center.MockDynamicConfigurationFactory{}).GetDynamicConfiguration(&ccUrl)
+ common_cfg.GetEnvInstance().SetDynamicConfiguration(dc)
+ regProtocol := newRegistryProtocol()
+ url := exporterNormal(t, regProtocol)
+ if _, loaded := regProtocol.registries.Load(url.Key()); !loaded {
+ assert.Fail(t, "regProtocol.registries.Load can not be loaded")
+ return
+ }
+ dc.(*config_center.MockDynamicConfiguration).MockApplicationConfigEvent()
+
+ newUrl := url.SubURL.Clone()
+ newUrl.SetParam(constant.CLUSTER_KEY, "mock1")
+ v2, _ := regProtocol.bounds.Load(getCacheKey(newUrl))
+ assert.NotNil(t, v2)
+}
diff --git a/registry/registry.go b/registry/registry.go
index b41ac53..c7279a2 100644
--- a/registry/registry.go
+++ b/registry/registry.go
@@ -28,10 +28,21 @@
//And it is also used for service consumer calling , register services cared about ,for dubbo's admin monitoring.
Register(url common.URL) error
- //used for service consumer ,start subscribe service event from registry
- Subscribe(common.URL) (Listener, error)
+ //When creating new registry extension,pls select one of the following modes.
+ //Will remove in dubbogo version v1.1.0
+ //mode1 : return Listener with Next function which can return subscribe service event from registry
+ //Deprecated!
+ //subscribe(common.URL) (Listener, error)
+
+ //Will relace mode1 in dubbogo version v1.1.0
+ //mode2 : callback mode, subscribe with notify(notify listener).
+ Subscribe(*common.URL, NotifyListener)
+}
+type NotifyListener interface {
+ Notify(*ServiceEvent)
}
+//Deprecated!
type Listener interface {
Next() (*ServiceEvent, error)
Close()
diff --git a/registry/zookeeper/listener.go b/registry/zookeeper/listener.go
index 7d58cee..857421f 100644
--- a/registry/zookeeper/listener.go
+++ b/registry/zookeeper/listener.go
@@ -21,12 +21,15 @@
"context"
"strings"
)
+
import (
perrors "github.com/pkg/errors"
)
+
import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/logger"
+ "github.com/apache/dubbo-go/config_center"
"github.com/apache/dubbo-go/registry"
"github.com/apache/dubbo-go/remoting"
zk "github.com/apache/dubbo-go/remoting/zookeeper"
@@ -34,10 +37,10 @@
type RegistryDataListener struct {
interestedURL []*common.URL
- listener remoting.ConfigurationListener
+ listener config_center.ConfigurationListener
}
-func NewRegistryDataListener(listener remoting.ConfigurationListener) *RegistryDataListener {
+func NewRegistryDataListener(listener config_center.ConfigurationListener) *RegistryDataListener {
return &RegistryDataListener{listener: listener, interestedURL: []*common.URL{}}
}
func (l *RegistryDataListener) AddInterestedURL(url *common.URL) {
@@ -59,7 +62,7 @@
}
for _, v := range l.interestedURL {
if serviceURL.URLEqual(*v) {
- l.listener.Process(&remoting.ConfigChangeEvent{Value: serviceURL, ConfigType: eventType.Action})
+ l.listener.Process(&config_center.ConfigChangeEvent{Value: serviceURL, ConfigType: eventType.Action})
return true
}
}
@@ -70,14 +73,14 @@
type RegistryConfigurationListener struct {
client *zk.ZookeeperClient
registry *zkRegistry
- events chan *remoting.ConfigChangeEvent
+ events chan *config_center.ConfigChangeEvent
}
func NewRegistryConfigurationListener(client *zk.ZookeeperClient, reg *zkRegistry) *RegistryConfigurationListener {
reg.wg.Add(1)
- return &RegistryConfigurationListener{client: client, registry: reg, events: make(chan *remoting.ConfigChangeEvent, 32)}
+ return &RegistryConfigurationListener{client: client, registry: reg, events: make(chan *config_center.ConfigChangeEvent, 32)}
}
-func (l *RegistryConfigurationListener) Process(configType *remoting.ConfigChangeEvent) {
+func (l *RegistryConfigurationListener) Process(configType *config_center.ConfigChangeEvent) {
l.events <- configType
}
diff --git a/registry/zookeeper/listener_test.go b/registry/zookeeper/listener_test.go
index 7ebc32b..910d47b 100644
--- a/registry/zookeeper/listener_test.go
+++ b/registry/zookeeper/listener_test.go
@@ -1,13 +1,37 @@
+/*
+ * 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 zookeeper
import (
"context"
- "github.com/apache/dubbo-go/common"
- "github.com/apache/dubbo-go/remoting"
- "github.com/stretchr/testify/assert"
"testing"
)
+import (
+ "github.com/stretchr/testify/assert"
+)
+
+import (
+ "github.com/apache/dubbo-go/common"
+ "github.com/apache/dubbo-go/config_center"
+ "github.com/apache/dubbo-go/remoting"
+)
+
func Test_DataChange(t *testing.T) {
listener := NewRegistryDataListener(&MockDataListener{})
url, _ := common.NewURL(context.TODO(), "jsonrpc%3A%2F%2F127.0.0.1%3A20001%2Fcom.ikurento.user.UserProvider%3Fanyhost%3Dtrue%26app.version%3D0.0.1%26application%3DBDTService%26category%3Dproviders%26cluster%3Dfailover%26dubbo%3Ddubbo-provider-golang-2.6.0%26environment%3Ddev%26group%3D%26interface%3Dcom.ikurento.user.UserProvider%26ip%3D10.32.20.124%26loadbalance%3Drandom%26methods.GetUser.loadbalance%3Drandom%26methods.GetUser.retries%3D1%26methods.GetUser.weight%3D0%26module%3Ddubbogo%2Buser-info%2Bserver%26name%3DBDTService%26organization%3Dikurento.com%26owner%3DZX%26pid%3D74500%26retries%3D0%26service.filter%3Decho%26side%3Dprovider%26timestamp%3D1560155407%26version%3D%26warmup%3D100")
@@ -19,5 +43,5 @@
type MockDataListener struct {
}
-func (*MockDataListener) Process(configType *remoting.ConfigChangeEvent) {
+func (*MockDataListener) Process(configType *config_center.ConfigChangeEvent) {
}
diff --git a/registry/zookeeper/registry.go b/registry/zookeeper/registry.go
index ff57eb6..e14541d 100644
--- a/registry/zookeeper/registry.go
+++ b/registry/zookeeper/registry.go
@@ -44,7 +44,8 @@
)
const (
- RegistryZkClient = "zk registry"
+ RegistryZkClient = "zk registry"
+ RegistryConnDelay = 3
)
var (
@@ -80,7 +81,6 @@
configListener *RegistryConfigurationListener
//for provider
zkPath map[string]int // key = protocol://ip:port/interface
-
}
func newZkRegistry(url *common.URL) (registry.Registry, error) {
@@ -271,9 +271,11 @@
return perrors.WithStack(err)
}
params = url.Values{}
- for k, v := range c.Params {
- params[k] = v
- }
+
+ c.RangeParams(func(key, value string) bool {
+ params.Add(key, value)
+ return true
+ })
params.Add("pid", processID)
params.Add("ip", localIP)
@@ -393,11 +395,44 @@
return nil
}
-func (r *zkRegistry) Subscribe(conf common.URL) (registry.Listener, error) {
+func (r *zkRegistry) subscribe(conf *common.URL) (registry.Listener, error) {
return r.getListener(conf)
}
-func (r *zkRegistry) getListener(conf common.URL) (*RegistryConfigurationListener, error) {
+//subscibe from registry
+func (r *zkRegistry) Subscribe(url *common.URL, notifyListener registry.NotifyListener) {
+ for {
+ if !r.IsAvailable() {
+ logger.Warnf("event listener game over.")
+ return
+ }
+
+ listener, err := r.subscribe(url)
+ if err != nil {
+ if !r.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()
+ return
+ } else {
+ logger.Infof("update begin, service event: %v", serviceEvent.String())
+ notifyListener.Notify(serviceEvent)
+ }
+
+ }
+
+ }
+}
+func (r *zkRegistry) getListener(conf *common.URL) (*RegistryConfigurationListener, error) {
var (
zkListener *RegistryConfigurationListener
)
@@ -422,9 +457,10 @@
}
//Interested register to dataconfig.
- r.dataListener.AddInterestedURL(&conf)
-
- go r.listener.ListenServiceEvent(fmt.Sprintf("/dubbo/%s/providers", conf.Service()), r.dataListener)
+ r.dataListener.AddInterestedURL(conf)
+ for _, v := range strings.Split(conf.GetParam(constant.CATEGORY_KEY, constant.DEFAULT_CATEGORY), ",") {
+ go r.listener.ListenServiceEvent(fmt.Sprintf("/dubbo/%s/"+v, conf.Service()), r.dataListener)
+ }
return zkListener, nil
}
diff --git a/registry/zookeeper/registry_test.go b/registry/zookeeper/registry_test.go
index 2b5e2f8..841c38d 100644
--- a/registry/zookeeper/registry_test.go
+++ b/registry/zookeeper/registry_test.go
@@ -60,11 +60,11 @@
}
//consumer register
- regurl.Params.Set(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER))
+ regurl.SetParam(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER))
_, reg2, _ := newMockZkRegistry(®url, zookeeper.WithTestCluster(ts))
reg2.Register(url)
- listener, _ := reg2.Subscribe(url)
+ listener, _ := reg2.subscribe(&url)
serviceEvent, _ := listener.Next()
assert.NoError(t, err)
@@ -85,7 +85,7 @@
assert.NoError(t, err)
err = reg.Register(url)
assert.NoError(t, err)
- _, err = reg.Subscribe(url)
+ _, err = reg.subscribe(&url)
assert.NoError(t, err)
//listener.Close()
diff --git a/remoting/etcdv3/listener.go b/remoting/etcdv3/listener.go
index 59273af..f540191 100644
--- a/remoting/etcdv3/listener.go
+++ b/remoting/etcdv3/listener.go
@@ -100,7 +100,7 @@
logger.Infof("etcd get event (key{%s}) = event{EventNodeDataChanged}", event.Kv.Key)
listener.DataChange(remoting.Event{
Path: string(event.Kv.Key),
- Action: remoting.EvnetTypeUpdate,
+ Action: remoting.EventTypeUpdate,
Content: string(event.Kv.Value),
})
}
diff --git a/remoting/listener.go b/remoting/listener.go
index fd566f3..8d1e357 100644
--- a/remoting/listener.go
+++ b/remoting/listener.go
@@ -17,26 +17,14 @@
package remoting
-import "fmt"
-
-type ConfigurationListener interface {
- Process(*ConfigChangeEvent)
-}
+import (
+ "fmt"
+)
type DataListener interface {
DataChange(eventType Event) bool //bool is return for interface implement is interesting
}
-type ConfigChangeEvent struct {
- Key string
- Value interface{}
- ConfigType EventType
-}
-
-func (c ConfigChangeEvent) String() string {
- return fmt.Sprintf("ConfigChangeEvent{key = %v , value = %v , changeType = %v}", c.Key, c.Value, c.ConfigType)
-}
-
//////////////////////////////////////////
// event type
//////////////////////////////////////////
@@ -46,7 +34,7 @@
const (
EventTypeAdd = iota
EventTypeDel
- EvnetTypeUpdate
+ EventTypeUpdate
)
var serviceEventTypeStrings = [...]string{
diff --git a/remoting/zookeeper/listener.go b/remoting/zookeeper/listener.go
index b8da16d..9521ea7 100644
--- a/remoting/zookeeper/listener.go
+++ b/remoting/zookeeper/listener.go
@@ -47,9 +47,11 @@
pathMap: make(map[string]struct{}),
}
}
+
func (l *ZkEventListener) SetClient(client *ZookeeperClient) {
l.client = client
}
+
func (l *ZkEventListener) ListenServiceNodeEvent(zkPath string, listener ...remoting.DataListener) bool {
l.wg.Add(1)
defer l.wg.Done()
@@ -70,9 +72,8 @@
logger.Warnf("zk.ExistW(key{%s}) = event{EventNodeDataChanged}", zkPath)
if len(listener) > 0 {
content, _, _ := l.client.Conn.Get(zkEvent.Path)
- listener[0].DataChange(remoting.Event{Path: zkEvent.Path, Action: remoting.EvnetTypeUpdate, Content: string(content)})
+ listener[0].DataChange(remoting.Event{Path: zkEvent.Path, Action: remoting.EventTypeUpdate, Content: string(content)})
}
-
case zk.EventNodeCreated:
logger.Warnf("zk.ExistW(key{%s}) = event{EventNodeCreated}", zkPath)
if len(listener) > 0 {
@@ -100,7 +101,6 @@
return true
}
}
-
return false
}
@@ -130,14 +130,14 @@
continue
}
// listen l service node
- go func(node string) {
+ go func(node string, zkPath string, listener remoting.DataListener) {
logger.Infof("delete zkNode{%s}", node)
if l.ListenServiceNodeEvent(node, listener) {
logger.Infof("delete content{%s}", node)
listener.DataChange(remoting.Event{Path: zkPath, Action: remoting.EventTypeDel})
}
logger.Warnf("listenSelf(zk path{%s}) goroutine exit now", zkPath)
- }(newNode)
+ }(newNode, zkPath, listener)
}
// old node was deleted
@@ -205,11 +205,10 @@
}
failTimes = 0
for _, c := range children {
-
// listen l service node
dubboPath := path.Join(zkPath, c)
- //Save the path to avoid listen repeatly
+ //Save the path to avoid listen repeatedly
l.pathMapLock.Lock()
_, ok := l.pathMap[dubboPath]
l.pathMapLock.Unlock()
@@ -231,14 +230,14 @@
continue
}
logger.Infof("listen dubbo service key{%s}", dubboPath)
- go func(zkPath string) {
- if l.ListenServiceNodeEvent(dubboPath) {
- listener.DataChange(remoting.Event{Path: dubboPath, Action: remoting.EventTypeDel})
+ go func(zkPath string, listener remoting.DataListener) {
+ if l.ListenServiceNodeEvent(zkPath) {
+ listener.DataChange(remoting.Event{Path: zkPath, Action: remoting.EventTypeDel})
}
logger.Warnf("listenSelf(zk path{%s}) goroutine exit now", zkPath)
- }(dubboPath)
+ }(dubboPath, listener)
- //liten sub path recursive
+ //listen sub path recursive
go func(zkPath string, listener remoting.DataListener) {
l.listenDirEvent(zkPath, listener)
logger.Warnf("listenDirEvent(zkPath{%s}) goroutine exit now", zkPath)
@@ -263,7 +262,7 @@
return time.Duration(sec) * time.Second
}
-// this func is invoked by ZkConsumerRegistry::Registe/ZkConsumerRegistry::get/ZkConsumerRegistry::getListener
+// this func is invoked by ZkConsumerRegistry::Register/ZkConsumerRegistry::get/ZkConsumerRegistry::getListener
// registry.go:Listen -> listenServiceEvent -> listenDirEvent -> ListenServiceNodeEvent
// |
// --------> ListenServiceNodeEvent
@@ -294,7 +293,6 @@
}
for _, c := range children {
-
// listen l service node
dubboPath = path.Join(zkPath, c)
content, _, err := l.client.Conn.Get(dubboPath)
@@ -305,12 +303,12 @@
continue
}
logger.Infof("listen dubbo service key{%s}", dubboPath)
- go func(zkPath string) {
- if l.ListenServiceNodeEvent(dubboPath) {
- listener.DataChange(remoting.Event{Path: dubboPath, Action: remoting.EventTypeDel})
+ go func(zkPath string, listener remoting.DataListener) {
+ if l.ListenServiceNodeEvent(zkPath) {
+ listener.DataChange(remoting.Event{Path: zkPath, Action: remoting.EventTypeDel})
}
logger.Warnf("listenSelf(zk path{%s}) goroutine exit now", zkPath)
- }(dubboPath)
+ }(dubboPath, listener)
}
logger.Infof("listen dubbo path{%s}", zkPath)
diff --git a/remoting/zookeeper/listener_test.go b/remoting/zookeeper/listener_test.go
index 8b13333..a90fbad 100644
--- a/remoting/zookeeper/listener_test.go
+++ b/remoting/zookeeper/listener_test.go
@@ -117,6 +117,8 @@
m.eventList = append(m.eventList, eventType)
if eventType.Content == m.changedData {
m.wait.Done()
+ m.client.Close()
+
}
return true
}