diff --git a/.gitignore b/.gitignore index 3769d10aa12348464cb315fd336bf6b7234069cc..f369c2833aeacbff3aa85a6cd1cdc25520928209 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 @@ coverage.txt 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 0000000000000000000000000000000000000000..cdfca4fb6d5d7106ed0c56e40cf40647607c3015 --- /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 e9ba4dde7f8a5c1cc402cbf3e1c644f3e5cf00d1..e76f9d9dd705daad997776153b1060f5bf8c2a1d 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 833d2783f6a8ebd7506cc775754fa2730ccc9284..25c72836cf7f47665da641a8285c6c3099ee2f8b 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,6 @@ --- Apache Dubbo Go Implementation. - - -Apache/Dubbo-go image, licensed under [Creative Commons 3.0 Attributions license](https://creativecommons.org/licenses/by/3.0/). ## License @@ -34,19 +31,19 @@ Finished List: - 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 @@ The subdirectory examples shows how to use dubbo-go. Please read the [examples/R ## 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 3b8ddff433f818c40b94e4a6303cd2c2aab02255..e34cf6a61991830dab582f70dda8ad70ec67e547 100644 --- a/README_CN.md +++ b/README_CN.md @@ -5,9 +5,6 @@ --- 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 @@ Apache License, Version 2.0 - 浼犺緭鍗忚: 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 @@ TODO ## 杩愯鍗曟祴 +### 鍑嗗 + +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 0000000000000000000000000000000000000000..a10df71a7eeb2eadb9d86574dc374b14a4f74e05 --- /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 0000000000000000000000000000000000000000..7acee76ce5991ac1d06bff6a6325f083904f10b9 --- /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 027461ccb7f32d6383d756ac986295b6300f249c..c8dbeda09f62e88b51dd4ad2b6b09d5715f0b224 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 @@ func newFailbackClusterInvoker(directory cluster.Directory) protocol.Invoker { 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 3dd8c41dfb7b7512d7c81fa6d7f8a7c35cec0dcb..70db6d4c1cdf5150d607d6c5250dfb3da631e95a 100644 --- a/cluster/cluster_impl/failover_cluster_invoker.go +++ b/cluster/cluster_impl/failover_cluster_invoker.go @@ -17,6 +17,10 @@ package cluster_impl +import ( + "strconv" +) + import ( perrors "github.com/pkg/errors" ) @@ -24,6 +28,7 @@ import ( 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 @@ func (invoker *failoverClusterInvoker) Invoke(invocation protocol.Invocation) pr 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 dc039db8de41ab6722b20f99c5a0c5536a42a7e6..78b799320dfa58d55e531c658ec5eb0e69306cff 100644 --- a/cluster/cluster_impl/failover_cluster_test.go +++ b/cluster/cluster_impl/failover_cluster_test.go @@ -118,14 +118,14 @@ func normalInvoke(t *testing.T, successCount int, urlParam url.Values, invocatio } 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_FailoverInvokeFail(t *testing.T) { 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 @@ func Test_FailoverInvoke2(t *testing.T) { 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 b2011977140f34d7e86d1414b7ced2d7cda23e9b..1d59b51cc36858b80fb43c1d76e368e89e26ae36 100644 --- a/cluster/directory/base_directory.go +++ b/cluster/directory/base_directory.go @@ -42,6 +42,9 @@ func NewBaseDirectory(url *common.URL) BaseDirectory { 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 39c5620f02d607bb68430e17a206a1649ee31c54..aa69f3cc207ae7465bc6d5472bc075d0902c8978 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 e261884b55971d95ccfbfdc34e32a07dc256fcca..0b8e89c7349afb056309b5a70d91aa5cce309aa0 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 8709d69a78263ab99501c4f6db78e78c47d2955b..931f0460917d68d3bd7adcd6a6bc1b49c7d3bba8 100644 --- a/common/config/environment.go +++ b/common/config/environment.go @@ -23,15 +23,21 @@ import ( "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 @@ func GetEnvInstance() *Environment { }) return instance } +func NewEnvInstance() { + instance = &Environment{configCenterFirst: true} +} //func (env *Environment) SetConfigCenterFirst() { // env.configCenterFirst = true @@ -60,23 +69,34 @@ func (env *Environment) UpdateExternalConfigMap(externalMap map[string]string) { } } +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 ab7cafae891a4f6832f9db9d297e6f5fdc19ad4b..2d84dc4ae31ef74fdcf2a37d7acb4a3e4cf36a09 100644 --- a/common/config/environment_test.go +++ b/common/config/environment_test.go @@ -19,6 +19,7 @@ package config import ( "testing" ) + import ( "github.com/stretchr/testify/assert" ) @@ -38,7 +39,7 @@ func TestEnvironment_UpdateExternalConfigMap(t *testing.T) { 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 d103c6aadc0f76d4c4d82fedb89ea2f21f5eb7aa..405920e20f4afadddf88b26e3fc169c149a9f2e6 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 ( ) 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 ed60c24b633fa62bbdf5b45931b286c6bbcd932b..abb78c987b44f827cea93150df0848a7d1557dec 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -22,15 +22,22 @@ const ( ) 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 ( ) 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 0000000000000000000000000000000000000000..40d134f474ae792afb76f1d8e3f56d172bfd07e2 --- /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 f364292b07850d1ef48f008eeb12261bf4b274a5..6f27aafaebf87147116e74272cc229657f436201 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 1665a7346e09016570dd36c56d231d3706b96a54..bafba60b400ec59d99e2d68ecf4d067c906ba6fb 100644 --- a/common/proxy/proxy_factory/default.go +++ b/common/proxy/proxy_factory/default.go @@ -17,10 +17,20 @@ 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 @@ func (factory *DefaultProxyFactory) GetProxy(invoker protocol.Invoker, url *comm 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 fb31129ed0fc1d695d2552901ffa1ca8737fce39..bf58ca188c1769b81ed475f06852d0f4229ab97d 100644 --- a/common/url.go +++ b/common/url.go @@ -31,7 +31,10 @@ import ( ) 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 @@ type baseUrl struct { 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 WithMethods(methods []string) option { 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 @@ func WithLocation(location string) option { 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 @@ func NewURL(ctx context.Context, urlString string, opts ...option) (URL, error) 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 @@ func (c URL) URLEqual(url URL) bool { if cKey != urlKey { return false } + if url.GetParam(constant.ENABLED_KEY, "true") != "true" && url.GetParam(constant.ENABLED_KEY, "") != constant.ANY_VALUE { + return false + } + //TODO :may need add interface key any value condition + if !isMatchCategory(url.GetParam(constant.CATEGORY_KEY, constant.DEFAULT_CATEGORY), c.GetParam(constant.CATEGORY_KEY, constant.DEFAULT_CATEGORY)) { + return false + } return true } - +func isMatchCategory(category1 string, category2 string) bool { + if len(category2) == 0 { + return category1 == constant.DEFAULT_CATEGORY + } else if strings.Contains(category2, constant.ANY_VALUE) { + return true + } else if strings.Contains(category2, constant.REMOVE_VALUE_PREFIX) { + return !strings.Contains(category2, constant.REMOVE_VALUE_PREFIX+category1) + } else { + 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 @@ func (c URL) ServiceKey() string { 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) Service() string { 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 @@ func (c URL) GetRawParam(key string) string { case "path": return c.Path default: - return c.Params.Get(key) + return c.GetParam(key, "") } } @@ -330,7 +403,7 @@ func (c URL) GetParamBool(s string, d bool) bool { 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) GetParamBool(s string, d bool) bool { 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) GetParamInt(s string, d int64) int64 { 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) GetMethodParamInt64(method string, key string, d int64) int64 { 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 @@ func (c URL) ToMap() map[string]string { // 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){} - //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]) - } - } - //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) - } - }) +func MergeUrl(serviceUrl *URL, referenceUrl *URL) *URL { + mergedUrl := serviceUrl.Clone() - //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) + //iterator the referenceUrl if serviceUrl not have the key ,merge in + referenceUrl.RangeParams(func(key, value string) bool { + if v := mergedUrl.GetParam(key, ""); len(v) == 0 { + mergedUrl.SetParam(key, value) } + return true }) + //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 @@ func MergeUrl(serviceUrl URL, referenceUrl *URL) URL { 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 143e31cb34f2ec1da7efc910a6b4133f0f4789b5..41fd374a4d8a4ad3e15de1080fe46d426620909f 100644 --- a/common/url_test.go +++ b/common/url_test.go @@ -52,11 +52,11 @@ func TestNewURLWithOptions(t *testing.T) { 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 @@ func TestURL(t *testing.T) { 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 @@ func TestURLWithoutSchema(t *testing.T) { 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_URLEqual(t *testing.T) { 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_GetParam(t *testing.T) { 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_GetParamInt(t *testing.T) { 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 @@ func TestURL_GetParamAndDecoded(t *testing.T) { 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_ToMap(t *testing.T) { 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_GetMethodParamInt(t *testing.T) { 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 TestURL_GetMethodParam(t *testing.T) { 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 41d7b9e2e57d3e8ca0e2818da518737b5cf39b3f..47a250231756a63735eedef3f4990bb7e038e748 100644 --- a/common/utils/net.go +++ b/common/utils/net.go @@ -19,6 +19,7 @@ package utils import ( "net" + "strings" ) import ( @@ -37,44 +38,39 @@ func init() { } } -// 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 @@ func isPrivateIP(ipAddr string) bool { } 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 af4ffd6acf4813c4e5496df64bcc31943b06a16f..fcd4d38c9b55963c32d58fdd1b80375083a76d8c 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) Id() string { 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 54ad8aba368c7d9477faad6fbd97c5dccd32dca1..264eeda3cc20da1b097a24dc35cf4f9b2291eeeb 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -20,10 +20,13 @@ import ( "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 @@ func (c *BaseConfig) prepareEnvironment() error { 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 @@ func (c *BaseConfig) prepareEnvironment() error { 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 + + for _, pfx := range strings.Split(prefix, "|") { + + retPrefixs = append(retPrefixs, pfx) - if idStr != "" { - return prefix + idStr + "." - } else { - return prefix } -} + 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 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC } - 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 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC 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 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC //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 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC 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 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC } } } + setBaseValue(f) } } @@ -214,8 +293,13 @@ func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryC } 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 d07d983f64ed33fcac73f8430737dfb2f01c40c3..6dc3749e55f7efbfb1177079f613360cd0d4cc33 100644 --- a/config/base_config_test.go +++ b/config/base_config_test.go @@ -92,7 +92,7 @@ func Test_refresh(t *testing.T) { Protocol: "mock", Cluster: "failover", Loadbalance: "random", - Retries: 3, + Retries: "3", Group: "huadong_idc", Version: "1.0.0", Methods: []*MethodConfig{ @@ -100,14 +100,14 @@ func Test_refresh(t *testing.T) { 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 @@ func Test_refresh(t *testing.T) { 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 @@ func Test_refreshProvider(t *testing.T) { Protocol: "mock", Cluster: "failover", Loadbalance: "random", - Retries: 3, + Retries: "3", Group: "huadong_idc", Version: "1.0.0", Methods: []*MethodConfig{ @@ -196,13 +448,13 @@ func Test_refreshProvider(t *testing.T) { 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 @@ func Test_refreshProvider(t *testing.T) { 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 @@ func Test_startConfigCenter(t *testing.T) { }} 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 47efce1265aa8949202938917bd6439c58ec80f0..ed43558956a181e669a1a8936182b65a2fb2766c 100644 --- a/config/config_center_config.go +++ b/config/config_center_config.go @@ -22,15 +22,31 @@ import ( "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 c5127c8c43622e7b26c998eb54e1b1803e6575ec..0b48761fd63b713b66f7b1b92f62b682dda5c927 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -54,6 +54,19 @@ func init() { 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 @@ func Load() { 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 @@ func Load() { 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 @@ func Load() { 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 107fea0b1d737f7be92d3e0042b6eebb7add78ed..498f82678070d194e3ffe1539064be7aec19f719 100644 --- a/config/config_loader_test.go +++ b/config/config_loader_test.go @@ -29,6 +29,8 @@ import ( 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 TestConfigLoader(t *testing.T) { } 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 TestLoad(t *testing.T) { } func TestWithNoRegLoad(t *testing.T) { - doInit() - doinit() + doInitConsumer() + doInitProvider() providerConfig.Services["MockService"].Registry = "" consumerConfig.References["MockService"].Registry = "" ms := &MockService{} @@ -145,3 +175,60 @@ func TestConfigLoaderWithConfigCenter(t *testing.T) { 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 90837344cae7cead935308e77d350868015f89d4..6bc574a546ebad548aaa15ce7dc9bcf68b95c3a1 100644 --- a/config/config_utils.go +++ b/config/config_utils.go @@ -21,6 +21,7 @@ import ( "regexp" "strings" ) + import ( "github.com/apache/dubbo-go/common/constant" ) diff --git a/config/consumer_config.go b/config/consumer_config.go index 737339a0ad195201327eb4fac3445b18eb4bbf26..b1ebdd5d8e082bf836071460e2a330632e07335c 100644 --- a/config/consumer_config.go +++ b/config/consumer_config.go @@ -22,10 +22,13 @@ import ( "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 @@ type ConsumerConfig struct { 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 @@ type ConsumerConfig struct { 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 95479d1b6586683632ede12e9ce469eb5268fb00..ac9242a230816711ab84a074473890b6f96c2b11 100644 --- a/config/method_config.go +++ b/config/method_config.go @@ -16,6 +16,10 @@ */ package config +import ( + "github.com/creasty/defaults" +) + import ( "github.com/apache/dubbo-go/common/constant" ) @@ -24,7 +28,7 @@ type MethodConfig struct { 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 @@ func (c *MethodConfig) Prefix() string { 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 6440f3090ddbb0dbbf8564ae816e3e951f60512d..b71423670c893402773ca2092d3d7a889a347439 100644 --- a/config/protocol_config.go +++ b/config/protocol_config.go @@ -19,6 +19,7 @@ package config import ( "strings" ) + import ( "github.com/apache/dubbo-go/common/constant" ) diff --git a/config/provider_config.go b/config/provider_config.go index a504eea237dc47f66c4ed27d334ce5eea5c87d45..00faa1d0ab1b65a7a39d7d3548e5b89b0f250aba 100644 --- a/config/provider_config.go +++ b/config/provider_config.go @@ -23,6 +23,7 @@ import ( ) import ( + "github.com/creasty/defaults" perrors "github.com/pkg/errors" "gopkg.in/yaml.v2" ) @@ -41,11 +42,24 @@ type ProviderConfig struct { 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 0000000000000000000000000000000000000000..db4b5f9906efb25cdb0ad8bf91f412f4510f5af5 --- /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 f90e3aabd3a68b8dc7a7509331d301ea3a252f92..26976f1ccfad2185a4d3fe6b51dad411eb176099 100644 --- a/config/reference_config.go +++ b/config/reference_config.go @@ -25,6 +25,10 @@ import ( "time" ) +import ( + "github.com/creasty/defaults" +) + import ( "github.com/apache/dubbo-go/cluster/directory" "github.com/apache/dubbo-go/common" @@ -43,11 +47,11 @@ type ReferenceConfig struct { 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 NewReferenceConfig(id string, ctx context.Context) *ReferenceConfig { } 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 @@ func (refconfig *ReferenceConfig) UnmarshalYAML(unmarshal func(interface{}) erro } *refconfig = ReferenceConfig(raw) + if err := defaults.Set(refconfig); err != nil { + return err + } + return nil } @@ -97,8 +106,8 @@ func (refconfig *ReferenceConfig) Refer() { 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 @@ func (refconfig *ReferenceConfig) getUrlMap() url.Values { 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 @@ func (refconfig *ReferenceConfig) getUrlMap() url.Values { 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 774fece29f5158b6840b3384b5c56846cc4da37b..a81dbf06cef7d275cf6af4a7f651ff8d1600a3c9 100644 --- a/config/reference_config_test.go +++ b/config/reference_config_test.go @@ -20,8 +20,6 @@ package config import ( "sync" "testing" - - "github.com/apache/dubbo-go/common/constant" ) import ( @@ -31,13 +29,14 @@ import ( 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 @@ func doInit() { Protocol: "mock", Cluster: "failover", Loadbalance: "random", - Retries: 3, + Retries: "3", + Group: "huadong_idc", + Version: "1.0.0", + Methods: []*MethodConfig{ + { + Name: "GetUser", + Retries: "2", + Loadbalance: "random", + }, + { + Name: "GetUser1", + 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, + Retries: "2", Loadbalance: "random", }, { Name: "GetUser1", - Retries: 2, + Retries: "2", Loadbalance: "random", }, }, @@ -112,7 +156,7 @@ func doInit() { } func Test_ReferMultireg(t *testing.T) { - doInit() + doInitConsumer() extension.SetProtocol("registry", GetProtocol) extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster) @@ -125,7 +169,7 @@ func Test_ReferMultireg(t *testing.T) { } func Test_Refer(t *testing.T) { - doInit() + doInitConsumer() extension.SetProtocol("registry", GetProtocol) extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster) @@ -138,7 +182,7 @@ func Test_Refer(t *testing.T) { 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_ReferP2P(t *testing.T) { } 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_ReferMultiP2P(t *testing.T) { } 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_ReferMultiP2PWithReg(t *testing.T) { } 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_Implement(t *testing.T) { } 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 0abdab810f3cfa835f7d1f21e395cd2a2812a051..9ffa41eb5b5b3b5ae4dc9f77812c0aef5ce9835f 100644 --- a/config/registry_config.go +++ b/config/registry_config.go @@ -24,6 +24,10 @@ import ( "strings" ) +import ( + "github.com/creasty/defaults" +) + import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" @@ -42,8 +46,19 @@ type RegistryConfig struct { 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 @@ func loadRegistries(targetRegistries string, registries map[string]*RegistryConf 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 @@ func (regconfig *RegistryConfig) getUrlMap(roleType common.RoleType) url.Values } 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 f600a21a0117572349aaf4de1bdee5e1270f67b4..45d38b29cc7089dabc5d7b7e34390ee48a58dc97 100644 --- a/config/registry_config_test.go +++ b/config/registry_config_test.go @@ -20,11 +20,15 @@ import ( "fmt" "testing" ) + import ( - "github.com/apache/dubbo-go/common" "github.com/stretchr/testify/assert" ) +import ( + "github.com/apache/dubbo-go/common" +) + func Test_loadRegistries(t *testing.T) { target := "shanghai1" regs := map[string]*RegistryConfig{ diff --git a/config/service_config.go b/config/service_config.go index 8b4a7d1b2251be206085a54a8676944aa3158609..ce15c61eb3ce9c1bf64f629df3d2c52e300d1a2c 100644 --- a/config/service_config.go +++ b/config/service_config.go @@ -28,6 +28,7 @@ import ( ) import ( + "github.com/creasty/defaults" perrors "github.com/pkg/errors" "go.uber.org/atomic" ) @@ -45,7 +46,7 @@ type ServiceConfig struct { 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 @@ type ServiceConfig struct { 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 @@ func (c *ServiceConfig) Prefix() string { 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 @@ func (srvconfig *ServiceConfig) Export() error { 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 @@ func (srvconfig *ServiceConfig) Export() error { if exporter == nil { panic(perrors.New(fmt.Sprintf("Registry protocol new exporter error,registry is {%v},url is {%v}", regUrl, url))) } - srvconfig.exporters = append(srvconfig.exporters, exporter) } } else { invoker := extension.GetProxyFactory(providerConfig.ProxyFactory).GetInvoker(*url) @@ -137,7 +150,6 @@ func (srvconfig *ServiceConfig) Export() error { if exporter == nil { panic(perrors.New(fmt.Sprintf("Filter protocol without registry new exporter error,url is {%v}", url))) } - srvconfig.exporters = append(srvconfig.exporters, exporter) } } @@ -160,7 +172,7 @@ func (srvconfig *ServiceConfig) getUrlMap() url.Values { 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 @@ func (srvconfig *ServiceConfig) getUrlMap() url.Values { 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 e111c8d110a14a039f3ab1a6c14f8044847f87e5..8ae67533bd1cdd1f9170efd762de51d371d0ad38 100644 --- a/config/service_config_test.go +++ b/config/service_config_test.go @@ -21,15 +21,11 @@ import ( "testing" ) -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 @@ func doinit() { 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", + Loadbalance: "random", + Weight: 200, + }, + { + Name: "GetUser1", + 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, + Retries: "2", Loadbalance: "random", Weight: 200, }, { Name: "GetUser1", - Retries: 2, + Retries: "2", Loadbalance: "random", Weight: 200, }, @@ -109,16 +155,13 @@ func doinit() { } 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 372873abbb258e03acfe8e9e00d03aa2f77fb9a9..9fd50bb4d35a40d8532c9a644a86ad6834f8e89b 100644 --- a/config/testdata/consumer_config.yml +++ b/config/testdata/consumer_config.yml @@ -8,7 +8,7 @@ request_timeout : "100ms" connect_timeout : "100ms" check: true # application config -application_config: +application: organization : "ikurento.com" name : "BDTService" module : "dubbogo user-info client" @@ -43,7 +43,7 @@ references: 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 c6505e4492887cc6602ab0b2ee9a9fbd9fdce9c9..0550cc89741b6a490aaba9ff8906d7dda1b3ed49 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 @@ references: 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 b4d897fda2b78e30dd912eab9f5a43bbcef9f595..5e57c7ddf6e82152e4f207b2d06df1443766717c 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 @@ registries : 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 @@ protocol_conf: 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 @@ protocol_conf: 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 e135860c208ff4d386a1abd658049e0e0aac73a3..5cbefe08111a048cec1902fbf9563cf78552a730 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/examples/general/dubbo/go-server/profiles/release/server.yml b/config/testdata/provider_config_withoutProtocol.yml similarity index 57% rename from examples/general/dubbo/go-server/profiles/release/server.yml rename to config/testdata/provider_config_withoutProtocol.yml index 6890ed3bdb5048b02578ca8eba1620464378463c..2f65868d4948db9a8b99c500014ea1307569d86f 100644 --- a/examples/general/dubbo/go-server/profiles/release/server.yml +++ b/config/testdata/provider_config_withoutProtocol.yml @@ -1,14 +1,14 @@ # dubbo server yaml configure file - +filter: "" # application config -application_config: +application: organization : "ikurento.com" name : "BDTService" module : "dubbogo user-info server" version : "0.0.1" owner : "ZX" - environment : "release" + environment : "dev" registries : "hangzhouzk": @@ -27,55 +27,40 @@ registries : services: "UserProvider": - # 鍙互鎸囧畾澶氫釜registry锛屼娇鐢ㄩ€楀彿闅斿紑;涓嶆寚瀹氶粯璁ゅ悜鎵€鏈夋敞鍐屼腑蹇冩敞鍐� - registry: "hangzhouzk" - protocol : "dubbo" - # 鐩稿綋浜巇ubbo.xml涓殑interface + 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" - "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": + "dubbo": name: "dubbo" - # ip : "127.0.0.1" - port: 20000 - + # 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 diff --git a/config_center/configuration_listener.go b/config_center/configuration_listener.go new file mode 100644 index 0000000000000000000000000000000000000000..1419bcdd0ce10ec15d0c24c2439bb02747ce5391 --- /dev/null +++ b/config_center/configuration_listener.go @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package config_center + +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 ab02789c9267786c900b57c312b1346ee2653fde..0000000000000000000000000000000000000000 --- 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 3c84fd70b03df06184365e132a174dfc640da1c2..0000000000000000000000000000000000000000 --- 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/jsonrpc/with-configcenter-go-client/app/version.go b/config_center/configurator.go similarity index 84% rename from examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/app/version.go rename to config_center/configurator.go index c6138584f1ddeab3a4927774f44f9e78a8f08da7..3ba293ec60302b76becce357f49b2baa543f69cd 100644 --- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/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 0000000000000000000000000000000000000000..1f03d107c8f588cfd4c23c9086bb0fbe42e05fff --- /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 0000000000000000000000000000000000000000..660c6ee315b299a9cf73d9399f572361adbafbd3 --- /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 0000000000000000000000000000000000000000..a585f4217f81a5d600ec9a48c12b3b47ff2d5322 --- /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 3b829507b1cfbcb687b194ac971c9b827c1c3e8b..1028b26d963cfcb02636113abc3e482bb22192a0 100644 --- a/config_center/dynamic_configuration.go +++ b/config_center/dynamic_configuration.go @@ -20,8 +20,9 @@ package config_center import ( "time" ) + import ( - "github.com/apache/dubbo-go/remoting" + "github.com/apache/dubbo-go/config_center/parser" ) ////////////////////////////////////////// @@ -31,10 +32,10 @@ const DEFAULT_GROUP = "dubbo" 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 a6c7267a4fdd68fda0bde80f16edae1d97e58a51..47b509231d225491e6791e295a707756256f61d5 100644 --- a/config_center/mock_dynamic_config.go +++ b/config_center/mock_dynamic_config.go @@ -20,23 +20,33 @@ package config_center 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 @@ func (f *MockDynamicConfigurationFactory) GetDynamicConfiguration(url *common.UR 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 0000000000000000000000000000000000000000..1ce6594017ddc3cf76ba01c985b01a97e5ec91f3 --- /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/config_center/parser/configuration_parser_test.go b/config_center/parser/configuration_parser_test.go new file mode 100644 index 0000000000000000000000000000000000000000..7a59ea9b48b8b8d2a84735a416bcba1bb9ec8652 --- /dev/null +++ b/config_center/parser/configuration_parser_test.go @@ -0,0 +1,34 @@ +/* + * 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 ( + "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 c1c7e27b14a5bbe651faddb0c2ff5341195f716e..611f4b9785c38eac4181750eefcabfb39607135d 100644 --- a/config_center/zookeeper/factory.go +++ b/config_center/zookeeper/factory.go @@ -20,10 +20,12 @@ package zookeeper 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 @@ func (f *zookeeperDynamicConfigurationFactory) GetDynamicConfiguration(url *comm 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 f2827b2bb693fc1943116686f8056c0edaeadc99..84e4b54e237fabb5775bfd0dfeb7043f1794a7ae 100644 --- a/config_center/zookeeper/impl.go +++ b/config_center/zookeeper/impl.go @@ -22,16 +22,18 @@ import ( "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 @@ type zookeeperDynamicConfiguration struct { 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 newMockZookeeperDynamicConfiguration(url *common.URL, opts ...zookeeper.Opt } -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 @@ func (c *zookeeperDynamicConfiguration) GetConfigs(key string, opts ...config_ce 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 26b899e82d7f1878d13e7dab113524be09ebde34..2f620457f75b7e35f713423e3841d0272cbd0730 100644 --- a/config_center/zookeeper/impl_test.go +++ b/config_center/zookeeper/impl_test.go @@ -31,13 +31,13 @@ import ( 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 @@ type mockDataListener struct { 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 c79c05c9bcf8ee86d0921ac62e7812ed00c9f5c1..7128b6f5a39e243840a1076f9fc506d94c7ed2ed 100644 --- a/config_center/zookeeper/listener.go +++ b/config_center/zookeeper/listener.go @@ -21,7 +21,9 @@ import ( "strings" "sync" ) + import ( + "github.com/apache/dubbo-go/config_center" "github.com/apache/dubbo-go/remoting" ) @@ -33,21 +35,21 @@ type CacheListener struct { 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 @@ func (l *CacheListener) DataChange(event remoting.Event) bool { 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 497926f1d3822f7b7d33640fa18cbc2bd65bdbb9..d520c5cceecd30ea6d4cae9bf416ae079b3a3f84 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 -java server -```bash -cd dubbo/java-server -sh build.sh -``` + A simplest example. It contain 'go-client', 'go-server', 'java-server' of dubbo protocol. -java client -```bash -cd dubbo/java-client -sh build.sh -``` +* general -go server + 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. -* sh ./assembly/\[os]/\[environment].sh -```bash -cd dubbo/go-server -# $ARCH = [linux, mac, windows] and $ENV = [dev, release, test] -sh ./assembly/$ARCH/$ENV.sh -``` +* generic -go client -```bash -cd dubbo/go-client -# $ARCH = [linux, mac, windows] and $ENV = [dev, release, test] -sh ./assembly/$ARCH/$ENV.sh -``` + 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. -#### Run by these command: +## How to build and run + +> Take `helloworld` as an example java server + ```bash -cd dubbo/java-server/target +cd helloworld/dubbo/java-server +sh build.sh + +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 d27af7a31778403d518e6454de7ebab4b9b5cdf7..0000000000000000000000000000000000000000 --- 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 c8e7bd0b053f797f3a5320451f08dcc590832330..48b7b0ce95f11f21f1c94095c3c4fea3c4232f9d 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 @@ references: cluster: "failover" methods : - name: "GetUser" - retries: 3 + retries: "3" protocol_conf: dubbo: diff --git a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/dev/log.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/dev/log.yml deleted file mode 100644 index 59fa4279ad85272c4c49d532beaf23b74d00f58a..0000000000000000000000000000000000000000 --- a/examples/configcenter/zookeeper/dubbo/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/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 c8e7bd0b053f797f3a5320451f08dcc590832330..0000000000000000000000000000000000000000 --- 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 e0514be020eedf594d99d112183cdd5ce199e46d..0000000000000000000000000000000000000000 --- 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 c8e7bd0b053f797f3a5320451f08dcc590832330..0000000000000000000000000000000000000000 --- 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-server/app/user.go b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/user.go deleted file mode 100644 index 0e4d05766887ae41440313b49ba4dc859a09ed35..0000000000000000000000000000000000000000 --- 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 90077c2471d7d5553ddea6402c7e2c06867cba8e..0000000000000000000000000000000000000000 --- 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 1f0827eb512b9bcb3c2428f8e0b50d76f65743ef..0000000000000000000000000000000000000000 --- 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 89a95ce679ca711824a2de0888686be79d96f505..0000000000000000000000000000000000000000 --- 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++绋嬪簭琚玸trip鐨勬晥鏋滐級锛� - # -w鍘绘帀DWARF璋冭瘯淇℃伅锛屽緱鍒扮殑绋嬪簭灏变笉鑳界敤gdb璋冭瘯浜嗐€�-s鍜�-w涔熷彲浠ュ垎寮€浣跨敤锛屼竴鑸潵璇村鏋滀笉鎵撶畻鐢╣db璋冭瘯锛� - # -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 d830ac98c2b9328791d00d5160d487b1a12b5fed..0000000000000000000000000000000000000000 --- 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 99303800b0fbcd7f8dfea668dcf395f126fb99f6..0000000000000000000000000000000000000000 --- 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 87144bb973095acaf8c17b0ec3bf42f643d0b95f..0000000000000000000000000000000000000000 --- 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 3a7659b2d57e0e2502950d76ec6c938abf2b7513..0000000000000000000000000000000000000000 --- 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 1c4bce4bf825fe401823ec33025e004a476ccaaf..0000000000000000000000000000000000000000 --- 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 69206e32fed343eb87c04190b509b16482125542..0000000000000000000000000000000000000000 --- 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 011fb41148f205bc329118a3c75e52854c0ecfd3..0000000000000000000000000000000000000000 --- 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 679a26a7dc77a9bc0ccbf119eac3caba252cadc9..0000000000000000000000000000000000000000 --- 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 4a36de0f3a26b804601de703c62a8062bd0623f4..0000000000000000000000000000000000000000 --- 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 59fa4279ad85272c4c49d532beaf23b74d00f58a..0000000000000000000000000000000000000000 --- 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 cdaaca4c3803cf6126f00d67631dd1507d14505c..219b92aebf1262dbbccf6291301387447589e500 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 @@ services: 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 e0514be020eedf594d99d112183cdd5ce199e46d..0000000000000000000000000000000000000000 --- 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 cdaaca4c3803cf6126f00d67631dd1507d14505c..0000000000000000000000000000000000000000 --- 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" - # 鐩稿綋浜巇ubbo.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/server.yml b/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/test/server.yml deleted file mode 100644 index cdaaca4c3803cf6126f00d67631dd1507d14505c..0000000000000000000000000000000000000000 --- 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" - # 鐩稿綋浜巇ubbo.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 5b1634788c455f6b8f0fb964f25a07b525492cf0..0000000000000000000000000000000000000000 --- 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 fef665bb3d14709ffd584cbb184c18ffe8d87580..0000000000000000000000000000000000000000 --- 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/assembly/bin/load.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/assembly/bin/load.sh deleted file mode 100644 index ffa240b29d9e76761a151e7462092b86908de6f6..0000000000000000000000000000000000000000 --- 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 e10868f4d292765c7eeb2e8bb8b1684a44f56a14..0000000000000000000000000000000000000000 --- 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 c9a9e87c73ef45195d6f70acccf9374ee6cb906b..0000000000000000000000000000000000000000 --- 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++绋嬪簭琚玸trip鐨勬晥鏋滐級锛� - # -w鍘绘帀DWARF璋冭瘯淇℃伅锛屽緱鍒扮殑绋嬪簭灏变笉鑳界敤gdb璋冭瘯浜嗐€�-s鍜�-w涔熷彲浠ュ垎寮€浣跨敤锛屼竴鑸潵璇村鏋滀笉鎵撶畻鐢╣db璋冭瘯锛� - # -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 eada737c8d0939d4237a6d218fc2a07efdbff381..0000000000000000000000000000000000000000 --- 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 10eb3d73f8760d394537b90b7aeff83ca2b243ed..0000000000000000000000000000000000000000 --- 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 78b650c0d49483f9f6862532afa5c483b618475a..0000000000000000000000000000000000000000 --- 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 c8284769909e62f0142c29e3a63177bf2826593f..0000000000000000000000000000000000000000 --- 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 91c2dfee79b1499b640420191174f980eac187bb..0000000000000000000000000000000000000000 --- 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 a7853f5e2d51df8e3e9509621952c44bca0d1a2d..0000000000000000000000000000000000000000 --- 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 10a3866c0f4ed8e1070c4d5641259c04073df6cb..0000000000000000000000000000000000000000 --- 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 21af573fa3842d47959d5726b11b81d5fff5b8df..0000000000000000000000000000000000000000 --- 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 2104da8b5909957c165eedc2f7d6866a890e9e6d..0000000000000000000000000000000000000000 --- 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 3770f52b8329010cd098c8e13cfe6df3fd37cfb6..0000000000000000000000000000000000000000 --- 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/release/client.yml b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/release/client.yml deleted file mode 100644 index 3770f52b8329010cd098c8e13cfe6df3fd37cfb6..0000000000000000000000000000000000000000 --- 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 e0514be020eedf594d99d112183cdd5ce199e46d..0000000000000000000000000000000000000000 --- 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 3770f52b8329010cd098c8e13cfe6df3fd37cfb6..0000000000000000000000000000000000000000 --- 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 baee0b7248484e425f88f35ab128212c931ff85e..0000000000000000000000000000000000000000 --- 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 9ab9e58cb4d469dda347519674a8eef85b429fce..0000000000000000000000000000000000000000 --- 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/assembly/bin/load.sh b/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/assembly/bin/load.sh deleted file mode 100644 index 90077c2471d7d5553ddea6402c7e2c06867cba8e..0000000000000000000000000000000000000000 --- 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 1f0827eb512b9bcb3c2428f8e0b50d76f65743ef..0000000000000000000000000000000000000000 --- 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 89a95ce679ca711824a2de0888686be79d96f505..0000000000000000000000000000000000000000 --- 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++绋嬪簭琚玸trip鐨勬晥鏋滐級锛� - # -w鍘绘帀DWARF璋冭瘯淇℃伅锛屽緱鍒扮殑绋嬪簭灏变笉鑳界敤gdb璋冭瘯浜嗐€�-s鍜�-w涔熷彲浠ュ垎寮€浣跨敤锛屼竴鑸潵璇村鏋滀笉鎵撶畻鐢╣db璋冭瘯锛� - # -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 d830ac98c2b9328791d00d5160d487b1a12b5fed..0000000000000000000000000000000000000000 --- 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 99303800b0fbcd7f8dfea668dcf395f126fb99f6..0000000000000000000000000000000000000000 --- 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 87144bb973095acaf8c17b0ec3bf42f643d0b95f..0000000000000000000000000000000000000000 --- 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 3a7659b2d57e0e2502950d76ec6c938abf2b7513..0000000000000000000000000000000000000000 --- 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 1c4bce4bf825fe401823ec33025e004a476ccaaf..0000000000000000000000000000000000000000 --- 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 69206e32fed343eb87c04190b509b16482125542..0000000000000000000000000000000000000000 --- 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 011fb41148f205bc329118a3c75e52854c0ecfd3..0000000000000000000000000000000000000000 --- 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 679a26a7dc77a9bc0ccbf119eac3caba252cadc9..0000000000000000000000000000000000000000 --- 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 4a36de0f3a26b804601de703c62a8062bd0623f4..0000000000000000000000000000000000000000 --- 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 59fa4279ad85272c4c49d532beaf23b74d00f58a..0000000000000000000000000000000000000000 --- 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 5c2a2fe2cbe4855bc5ba037a038968142263d235..0000000000000000000000000000000000000000 --- 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" - # 鐩稿綋浜巇ubbo.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 e0514be020eedf594d99d112183cdd5ce199e46d..0000000000000000000000000000000000000000 --- 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 82c9fa66ade831a73d63f117223290261ecd0975..0000000000000000000000000000000000000000 --- 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" - # 鐩稿綋浜巇ubbo.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 baee0b7248484e425f88f35ab128212c931ff85e..0000000000000000000000000000000000000000 --- 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 82c9fa66ade831a73d63f117223290261ecd0975..0000000000000000000000000000000000000000 --- 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" - # 鐩稿綋浜巇ubbo.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 0000000000000000000000000000000000000000..bb475526e8c1ccc6c9cc2365caa2a06b2f69d997 --- /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 0000000000000000000000000000000000000000..73a9bc9c3cddb7fc23cae2cd8d776bc68ef26af8 --- /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 7442c64c71abf47db9c15d85c6bcd2ced8057e46..556ac2b1121f40d9fa3774f29beb6bdb510991bf 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 @@ application_config: 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 @@ protocol_conf: 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 @@ protocol_conf: 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/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/test/log.yml b/examples/consul/go-client/config/log.yml similarity index 100% rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-client/profiles/test/log.yml rename to examples/consul/go-client/config/log.yml diff --git a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/version.go b/examples/consul/go-client/service.go similarity index 73% rename from examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/version.go rename to examples/consul/go-client/service.go index c6138584f1ddeab3a4927774f44f9e78a8f08da7..0f7cca59857f0b66e8fab51c0ec95e3adfead44a 100644 --- a/examples/configcenter/zookeeper/jsonrpc/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/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/test/log.yml b/examples/consul/go-server/config/log.yml similarity index 100% rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/profiles/test/log.yml rename 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 4786e83669046babbfc4758829155d8f4ce3a438..f3c169ab782be9d94c7258c65474e2cafde0e1cb 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" - # 鐩稿綋浜巇ubbo.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 0a0e72915fef0ca4613f78a87fa1057152c1cc9a..0e1e1f608e4f112e4e47f74682156103345f80e3 100644 --- a/examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-server/app/server.go +++ b/examples/consul/go-server/server.go @@ -31,23 +31,18 @@ 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/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 @@ func initSignal() { 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/consul/go-server/service.go b/examples/consul/go-server/service.go new file mode 100644 index 0000000000000000000000000000000000000000..7c08ec99b93ce1d383fad3e717b4fdf2da0b5d6c --- /dev/null +++ b/examples/consul/go-server/service.go @@ -0,0 +1,36 @@ +/* + * 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 ( + "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 0000000000000000000000000000000000000000..0bbcf418ec53691d6895a6ea8eeb56a264f2b735 --- /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 0000000000000000000000000000000000000000..3e54e77d492416b439c8fe441dae492eb019229a --- /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 88% 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 c6138584f1ddeab3a4927774f44f9e78a8f08da7..4eb2d8c10ae76a3f15ab2619cc369ff3564b97af 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 0000000000000000000000000000000000000000..d9880bf2c4625dbebe0225502ebf42f98b36d896 --- /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 0000000000000000000000000000000000000000..097fa4309c1811750de0164bfaf2ebf354615d57 --- /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 0000000000000000000000000000000000000000..0bbcf418ec53691d6895a6ea8eeb56a264f2b735 --- /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 0000000000000000000000000000000000000000..07a1e5bc414a6a5d3688ff9ed2624f34d3622d59 --- /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 0000000000000000000000000000000000000000..de6b5b53355d72f678355de5773aeb1f00ec1751 --- /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 0000000000000000000000000000000000000000..61c5e9039c1eaaad0dcebaa0c43653eb23f2f92b --- /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 0000000000000000000000000000000000000000..91c7b0b912f4fb27e6d108d2975bcd8a6d08f4a4 --- /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 0000000000000000000000000000000000000000..097fa4309c1811750de0164bfaf2ebf354615d57 --- /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 e839b0b2776d8e3b2aba2756d2a622bea2b8e88d..f3ac4b99ab0abdd472056682ce8f4b3c4b41bc8b 100644 --- a/examples/general/dubbo/go-client/app/client.go +++ b/examples/general/dubbo/go-client/app/client.go @@ -33,9 +33,9 @@ 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/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 @@ func initSignal() { 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 @@ func test1() { 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 @@ func test1() { } 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 @@ func test1() { } 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 @@ func test1() { } 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 @@ func test1() { } 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 @@ func test2() { 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 @@ func test2() { } 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 @@ func test2() { } 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 @@ func test2() { } 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 ff696688416dc1e77f87d7831922894979d78da2..002da1ddb34f1fe6bfb7122e631153823960f8f5 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 @@ request_timeout : "3s" connect_timeout : "3s" # application config -application_config: +application: organization : "ikurento.com" name : "BDTService" module : "dubbogo user-info client" @@ -39,7 +39,7 @@ references: cluster: "failover" methods : - name: "GetUser" - retries: 3 + retries: "3" "UserProvider1": registry: "hangzhouzk" protocol: "dubbo" @@ -48,7 +48,7 @@ references: cluster: "failover" methods: - name: "GetUser" - retries: 3 + retries: "3" "UserProvider2": registry: "hangzhouzk" protocol: "dubbo" @@ -58,7 +58,7 @@ references: 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 e0514be020eedf594d99d112183cdd5ce199e46d..0000000000000000000000000000000000000000 --- 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/log.yml b/examples/general/dubbo/go-client/profiles/test/log.yml deleted file mode 100644 index baee0b7248484e425f88f35ab128212c931ff85e..0000000000000000000000000000000000000000 --- a/examples/general/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/general/dubbo/go-server/app/server.go b/examples/general/dubbo/go-server/app/server.go index ac92b879b15cb88ebc71fc5df90675b01760c899..0ffd6309c607168d75073c296eb60d21dadbca2d 100644 --- a/examples/general/dubbo/go-server/app/server.go +++ b/examples/general/dubbo/go-server/app/server.go @@ -74,7 +74,7 @@ func initSignal() { 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 79c2cb2cc22a1b626a631009a0a4c6f29a8f9127..c936e12828e3850f23a7a20e5e5361f820e04676 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 @@ services: cluster: "failover" methods: - name: "GetUser" - retries: 1 + retries: "1" loadbalance: "random" "UserProvider1": registry: "hangzhouzk" @@ -50,7 +50,7 @@ services: cluster: "failover" methods: - name: "GetUser" - retries: 1 + retries: "1" loadbalance: "random" "UserProvider2": registry: "hangzhouzk" @@ -63,7 +63,7 @@ services: 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 e0514be020eedf594d99d112183cdd5ce199e46d..0000000000000000000000000000000000000000 --- 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/test/log.yml b/examples/general/dubbo/go-server/profiles/test/log.yml deleted file mode 100644 index baee0b7248484e425f88f35ab128212c931ff85e..0000000000000000000000000000000000000000 --- 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 b6dd41da448d7531a3c5f4f24a8f460e5d1775bc..0000000000000000000000000000000000000000 --- 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" - # 鐩稿綋浜巇ubbo.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 140dff072e88cf54f6a87698f026f9875025a9b5..a330d9829aef7efff15a3d9ce004b22843890705 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 9dfd6850c1786379861638517b08fb1a81beea7e..67c6264ea925bb60e38241f0a51e1ce7842b1d90 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 854d5135a5065f58ec1fdf32c215ca516bd4aee9..041d7c336558c9ea662ed2db3a3b9301c9eec4a2 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 8c1322860245e874e06ee33584cb6b4d08a68058..9b811e9f78a3db3cb742ce5870b5d68b55bd681c 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 6efa582d5f0aee9013fdbc2270b547f69322d20c..e2068f92350ae1cd2e4c75cd16aad5f2d9d52994 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 abbe586de94a26c9d1a71892b38844662ae4863a..0248af70cc08aec6a327b2373234aabc1db5fca4 100644 --- a/examples/general/jsonrpc/go-client/app/client.go +++ b/examples/general/jsonrpc/go-client/app/client.go @@ -73,7 +73,7 @@ func initSignal() { 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 @@ func test() { 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 788e06eecd6014eefaf12913b6394e5e0a95efdf..98c5c820e1af2d96702dbae27abf9af1d5129497 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 @@ request_timeout : "3s" connect_timeout : "3s" # application config -application_config: +application: organization : "ikurento.com" name : "BDTService" module : "dubbogo user-info client" @@ -38,7 +38,7 @@ references: cluster: "failover" methods : - name: "GetUser" - retries: 3 + retries: "3" "UserProvider1": registry: "hangzhouzk" protocol: "jsonrpc" @@ -47,7 +47,7 @@ references: cluster: "failover" methods: - name: "GetUser" - retries: 3 + retries: "3" "UserProvider2": registry: "hangzhouzk" protocol: "jsonrpc" @@ -57,4 +57,4 @@ references: 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 0084e5b04d48fea480f22df8e031eb91e1d6e835..0000000000000000000000000000000000000000 --- 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 e0514be020eedf594d99d112183cdd5ce199e46d..0000000000000000000000000000000000000000 --- 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 3efdedad4ab8acffb9d8724273deb8c12117837d..0000000000000000000000000000000000000000 --- 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 baee0b7248484e425f88f35ab128212c931ff85e..0000000000000000000000000000000000000000 --- 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 e36b6efe9d115d8352f09f1f5011ea00d92f0d13..de4aaed0bd56a112633ff9c4aba1c79d21b49920 100644 --- a/examples/general/jsonrpc/go-server/app/server.go +++ b/examples/general/jsonrpc/go-server/app/server.go @@ -64,7 +64,7 @@ func initSignal() { 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 4d74d2ef6fed9b0206729717d7b7081a3eadec96..f4a2766f48309ec9191810fd60b393d472574ce8 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 @@ services: cluster: "failover" methods: - name: "GetUser" - retries: 1 + retries: "1" loadbalance: "random" "UserProvider1": registry: "hangzhouzk" @@ -48,7 +48,7 @@ services: cluster: "failover" methods: - name: "GetUser" - retries: 1 + retries: "1" loadbalance: "random" "UserProvider2": registry: "hangzhouzk" @@ -61,7 +61,7 @@ services: 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 e0514be020eedf594d99d112183cdd5ce199e46d..0000000000000000000000000000000000000000 --- 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 3f7d2fdfff208801a6b89e7a90350e57133f31c3..0000000000000000000000000000000000000000 --- 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" - # 鐩稿綋浜巇ubbo.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 baee0b7248484e425f88f35ab128212c931ff85e..0000000000000000000000000000000000000000 --- 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 dd0637e7970281236b92e37888c554d83d87de96..0000000000000000000000000000000000000000 --- 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" - # 鐩稿綋浜巇ubbo.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 8d5a1bc5fa6cb186fcf456d385f8dad16b750ea3..dbd4665f5cd8e6740094c00f3cb089a932bb3e51 100644 --- a/examples/generic/go-client/app/client.go +++ b/examples/generic/go-client/app/client.go @@ -35,10 +35,6 @@ import ( _ "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 963a67fdf30f5f64ddaab290451f743266a75af1..9b226e24456e850f1b31fc0501e04d573cec35fd 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 ffa240b29d9e76761a151e7462092b86908de6f6..176a202ab8810701ac8208db0ab764f2e215d71d 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 e10868f4d292765c7eeb2e8bb8b1684a44f56a14..97eee47429e978927a03c3fb2876b3d40bfa4269 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 c9a9e87c73ef45195d6f70acccf9374ee6cb906b..0f0b22f5f42a01fffa48efa4cae5d953fb44d7ed 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 eada737c8d0939d4237a6d218fc2a07efdbff381..4f659a7c383853b45b7d80d516c10e0c51e6cede 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 c8284769909e62f0142c29e3a63177bf2826593f..0d21ec4aab54676837e0a909467cbf56f6bfc275 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 a7853f5e2d51df8e3e9509621952c44bca0d1a2d..2fac89d0f6b9feb95b79359b38078135f15d90e3 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 f4e3180aa88cbbdffd519d70b3cc83b2e2b6674a..26752fb2569d2074cc1eaf53027ea8e6ad7e554a 100644 --- a/examples/generic/go-client/profiles/dev/client.yml +++ b/examples/generic/go-client/profiles/dev/client.yml @@ -8,7 +8,7 @@ request_timeout : "3s" 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 5a21bca6c93336a8888b55a6a7e81f9240c709a5..0000000000000000000000000000000000000000 --- 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 e0514be020eedf594d99d112183cdd5ce199e46d..0000000000000000000000000000000000000000 --- 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 baee0b7248484e425f88f35ab128212c931ff85e..0000000000000000000000000000000000000000 --- 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 851957ade66f7eb492f9be278bf0b6f98eed729a..1038cd7ff7f65a2a07ce21414732ab891aef67ff 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 b3c3bbf7568a33d1001a6f2dcaa96604b91013ef..4ebe64b937bfcccf0ee97c948c76329272a9cca5 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 ffa240b29d9e76761a151e7462092b86908de6f6..176a202ab8810701ac8208db0ab764f2e215d71d 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 e10868f4d292765c7eeb2e8bb8b1684a44f56a14..97eee47429e978927a03c3fb2876b3d40bfa4269 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 c9a9e87c73ef45195d6f70acccf9374ee6cb906b..0f0b22f5f42a01fffa48efa4cae5d953fb44d7ed 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 10eb3d73f8760d394537b90b7aeff83ca2b243ed..13b19f48a8ccb448041feb636fa6b3cc4c9997a7 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 78b650c0d49483f9f6862532afa5c483b618475a..c6c31b3b7985d3b91fdeab39c2cd9954968fb227 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 10a3866c0f4ed8e1070c4d5641259c04073df6cb..6487b307887e0e8266bb7fc5b92914806128847f 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 fed05b09734c41ef7b53ad2d88a953f997d50735..6fcc678342d17c6a58ad0a11754fb396514f501b 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 @@ request_timeout : "3s" connect_timeout : "3s" # application config -application_config: +application: organization : "ikurento.com" name : "BDTService" module : "dubbogo user-info client" @@ -34,7 +34,7 @@ references: 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 02bf722754632f12d0e8e7cab3979ce360ffd7c7..0000000000000000000000000000000000000000 --- 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 e0514be020eedf594d99d112183cdd5ce199e46d..0000000000000000000000000000000000000000 --- 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 417a388c6cfb38a6a1563e9c4ab8856e4b2f30f8..0000000000000000000000000000000000000000 --- 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 baee0b7248484e425f88f35ab128212c931ff85e..0000000000000000000000000000000000000000 --- 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 f02a6ba05e8723410c985823caafe88192f5af7e..dc3a40f14f43e8dce616b3cd79a5a6b6fde38580 100644 --- a/examples/helloworld/dubbo/go-server/app/server.go +++ b/examples/helloworld/dubbo/go-server/app/server.go @@ -64,7 +64,7 @@ func initSignal() { 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 90077c2471d7d5553ddea6402c7e2c06867cba8e..2e127ac652ec2b418d74efa1abfd159250cb44d1 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 be7eedeaa3fd186f4cd2ea264b31429165e55bf1..8e8594a1ce478b36d48b09e65ab63506b31a2c3c 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 @@ services: 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 e0514be020eedf594d99d112183cdd5ce199e46d..0000000000000000000000000000000000000000 --- 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 baee0b7248484e425f88f35ab128212c931ff85e..0000000000000000000000000000000000000000 --- 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 ba6eb2b8005a4dc2d655f44ec38b93a01072d4f1..0000000000000000000000000000000000000000 --- 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" - # 鐩稿綋浜巇ubbo.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 00c9fddf3f897c90082f0a8ad3f76f9016733390..98a2e100f18d195b8f0b44eb07080eaa9097af79 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 3fca067a7353605bd59a2ebf1d22b7bdd25acf1f..edd01dc870b3bb16ffd7525387e994ea11da9b8e 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/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/server.go b/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/client.go similarity index 51% rename from examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/server.go rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/app/client.go index cd982992171fdf674e560bfb4ed280c1951cccde..e759465f002ed68e6f6faf217f99352b98b3d13a 100644 --- a/examples/configcenter/zookeeper/dubbo/with-configcenter-go-server/app/server.go +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/client.go @@ -18,69 +18,81 @@ package main import ( + "context" "fmt" - "os" - "os/signal" - "syscall" "time" ) import ( - hessian "github.com/apache/dubbo-go-hessian2" + "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) + _ "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_PROVIDER_FILE_PATH="xxx" +// export CONF_CONSUMER_FILE_PATH="xxx" // export APP_LOG_CONF_FILE="xxx" func main() { - // ------for hessian2------ 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) - 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) - }) + 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) - // The program exits normally or timeout forcibly exits. - fmt.Println("provider app exit now...") - return - } + 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 0000000000000000000000000000000000000000..0e86988fd787e0df941b62ad038746b412baf314 --- /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 5bddf1e19f59be1b7fae917cffddfde4d362f44e..affa5418a701842e890f9e2498c2ef7a769532bd 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 @@ import ( 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 @@ type User struct { Name string Age int32 Time time.Time - Sex Gender // notice: java enum Object <--> go string + Sex Gender // 娉ㄦ剰姝ゅ锛宩ava enum Object <--> go string } func (u User) String() string { @@ -111,3 +117,33 @@ type UserProvider struct { 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/general/dubbo/go-client/profiles/test/client.yml b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/dev/client.yml similarity index 54% rename from examples/general/dubbo/go-client/profiles/test/client.yml rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/dev/client.yml index c8b5c58691a0b35b55adb8f27cd1108433655b45..8602b3a190aa6b89497b6d0095334ef6ad9ea216 100644 --- a/examples/general/dubbo/go-client/profiles/test/client.yml +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/dev/client.yml @@ -8,16 +8,17 @@ request_timeout : "3s" connect_timeout : "3s" # application config -application_config: +application: organization : "ikurento.com" name : "BDTService" module : "dubbogo user-info client" version : "0.0.1" owner : "ZX" - environment : "test" + environment : "dev" registries : "hangzhouzk": + # 瀵瑰簲java閰嶇疆涓璦ddress灞炴€х殑zookeeper <dubbo:registry address="zookeeper://127.0.0.1:2181"/> protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2181" @@ -34,31 +35,13 @@ references: "UserProvider": # 鍙互鎸囧畾澶氫釜registry锛屼娇鐢ㄩ€楀彿闅斿紑;涓嶆寚瀹氶粯璁ゅ悜鎵€鏈夋敞鍐屼腑蹇冩敞鍐� registry: "hangzhouzk" + filter: "example_fallback,hystrix_consumer" 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 + - name: "GetUser" + retries: "3" protocol_conf: dubbo: @@ -66,6 +49,7 @@ protocol_conf: connection_number: 2 heartbeat_period: "5s" session_timeout: "20s" + fail_fast_timeout: "5s" pool_size: 64 pool_ttl: 600 getty_session_param: @@ -75,9 +59,40 @@ protocol_conf: 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/jsonrpc/with-configcenter-go-client/profiles/dev/log.yml b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/dev/log.yml similarity index 94% rename from examples/configcenter/zookeeper/jsonrpc/with-configcenter-go-client/profiles/dev/log.yml rename to examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/dev/log.yml index 59fa4279ad85272c4c49d532beaf23b74d00f58a..3ed242d290148743b198e32c5823ad9aae233e8b 100644 --- a/examples/configcenter/zookeeper/jsonrpc/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 d7dad74cf3f5ccadf39372335bc1efb22f497523..36a4e1a767ab7170ce8e5bebf2cfa4403f6ad4ff 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 5eb5a37fa500bd8c180d879240d1c1e367df31ce..18e42c8cb2b15acb27573c5e24f11a8b69e0d496 100644 --- a/filter/impl/echo_filter.go +++ b/filter/impl/echo_filter.go @@ -43,7 +43,8 @@ func (ef *EchoFilter) Invoke(invoker protocol.Invoker, invocation protocol.Invoc 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 12cb4c7fa59ac4f1f7c1466f385ea9e9b59567b5..35aadb11a444bda56109e238b17267f71ec2606b 100644 --- a/filter/impl/generic_filter.go +++ b/filter/impl/generic_filter.go @@ -83,11 +83,7 @@ func struct2MapAll(obj interface{}) interface{} { 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 @@ func struct2MapAll(obj interface{}) interface{} { 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 a71a9db95759a143186fe9a1a4fb0c861c8949e8..9797c40df1f57017241675013620a53320e475ad 100644 --- a/filter/impl/generic_filter_test.go +++ b/filter/impl/generic_filter_test.go @@ -87,3 +87,35 @@ func Test_struct2MapAll_Slice(t *testing.T) { 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 0000000000000000000000000000000000000000..3fd9f87168616b69d5ec72460767890d6956c154 --- /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 0000000000000000000000000000000000000000..d3a5183ede25d8a325bb1c73020edddd2ffbc638 --- /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 0000000000000000000000000000000000000000..d10dff5b761d0fbe40ff3a14a93ee8962d000e02 --- /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 0000000000000000000000000000000000000000..1473f274037699260725ff9ebb1b3d1377efb326 --- /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 8ced5e0edfe1ba3bb0c36af4963c1d107b7a109a..09948c93c582feca5a3c8ee8df379e03bb6a4e84 100644 --- a/go.mod +++ b/go.mod @@ -2,37 +2,41 @@ module github.com/apache/dubbo-go 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 dd8fc7a825c63eae394ede0797f33c58250bd526..1452a762985e615d49a40df33d8ee8166940a4c7 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 h1:JOrtw2xFKzlg+ 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.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y 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 h1:sgU 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/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb 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/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ 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 6ac5e7215429338aa7cabb646b3afd3f1a136b68..4927f51cf7c964ac9bb26c1089231b4bdcc65157 100644 --- a/protocol/dubbo/client.go +++ b/protocol/dubbo/client.go @@ -59,7 +59,7 @@ func init() { return } dubboConf := protocolConf.(map[interface{}]interface{})[DUBBO] - if protocolConf == nil { + if dubboConf == nil { logger.Warnf("dubboConf is nil") return } @@ -150,46 +150,74 @@ func NewClient(opt Options) *Client { return c } +type Request struct { + addr string + svcUrl common.URL + method string + args interface{} + atta map[string]string +} + +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(addr string, svcUrl common.URL, method string, args interface{}) error { +func (c *Client) CallOneway(request *Request) error { - return perrors.WithStack(c.call(CT_OneWay, addr, svcUrl, method, args, nil, nil)) + return perrors.WithStack(c.call(CT_OneWay, request, NewResponse(nil, nil), nil)) } -// 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 { +// 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 @@ func (c *Client) call(ct CallType, addr string, svcUrl common.URL, method string 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 @@ func (c *Client) transfer(session getty.Session, pkg *DubboPackage, 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 cd961d382933443e37a08c21b4e4de5edb971860..eb1f15c862a910120e118c06bf9b572e93f58832 100644 --- a/protocol/dubbo/client_test.go +++ b/protocol/dubbo/client_test.go @@ -33,6 +33,7 @@ import ( 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 @@ func TestClient_CallOneway(t *testing.T) { 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 @@ func TestClient_Call(t *testing.T) { } 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 @@ func TestClient_AsyncCall(t *testing.T) { 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 @@ func InitTest(t *testing.T) (protocol.Protocol, common.URL) { "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 98c29a4e5bc576f7e37f74c0c0abbbab4687717b..a878ffd91e29d6949870ec25fed9481f301b435a 100644 --- a/protocol/dubbo/codec.go +++ b/protocol/dubbo/codec.go @@ -91,9 +91,8 @@ func (p *DubboPackage) Unmarshal(buf *bytes.Buffer, opts ...interface{}) error { 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 @@ type PendingResponse struct { 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 @@ func (r PendingResponse) GetCallResponse() CallResponse { 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 52bb1fc130bb2dad866799f01c43d11ffd10a220..c192c2294db5597517ace011224e34f8affefb1f 100644 --- a/protocol/dubbo/codec_test.go +++ b/protocol/dubbo/codec_test.go @@ -64,11 +64,11 @@ func TestDubboPackage_MarshalAndUnmarshal(t *testing.T) { 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 46b3dcc8463d8406c494d80149b28f0dba7444d0..bc321a97a4271c147d9317145d9f1aa76ca27902 100644 --- a/protocol/dubbo/dubbo_invoker.go +++ b/protocol/dubbo/dubbo_invoker.go @@ -34,7 +34,11 @@ import ( 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 @@ func (di *DubboInvoker) Invoke(invocation protocol.Invocation) protocol.Result { ) 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 @@ func (di *DubboInvoker) Invoke(invocation protocol.Invocation) protocol.Result { 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 09a4c128b600e605de616a65027da9b2ce6fcb20..0a765356f7353829c8486fddba986e3a444441a1 100644 --- a/protocol/dubbo/dubbo_invoker_test.go +++ b/protocol/dubbo/dubbo_invoker_test.go @@ -49,12 +49,13 @@ func TestDubboInvoker_Invoke(t *testing.T) { 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 @@ func TestDubboInvoker_Invoke(t *testing.T) { 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 @@ func TestDubboInvoker_Invoke(t *testing.T) { 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 4438a0b3d0e32127536b818806d190a2d2a5a2ba..59d1ea05160696754b46dfead5713684aa7a94f7 100644 --- a/protocol/dubbo/dubbo_protocol.go +++ b/protocol/dubbo/dubbo_protocol.go @@ -17,13 +17,16 @@ 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 26ce4a1906d5d6fe425f23984586914c293f47a4..a6b0bc1df3cf2eb46e07c9dab149d04f62f78012 100644 --- a/protocol/dubbo/dubbo_protocol_test.go +++ b/protocol/dubbo/dubbo_protocol_test.go @@ -19,7 +19,6 @@ package dubbo import ( "context" - "github.com/apache/dubbo-go/common/constant" "testing" ) @@ -29,6 +28,7 @@ import ( 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 aa208284825665dae4c23f871117a7f34c548d16..1a7b002819271d7841e4749881d2ab379f9a7240 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 @@ func (h *RpcClientHandler) OnMessage(session getty.Session, pkg interface{}) { pendingResponse.err = p.Err } + pendingResponse.response.atta = p.Body.(*Response).atta + if pendingResponse.callback == nil { pendingResponse.done <- struct{}{} } else { @@ -209,6 +209,28 @@ func (h *RpcServerHandler) OnMessage(session getty.Session, pkg interface{}) { 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 @@ func (h *RpcServerHandler) OnMessage(session getty.Session, pkg interface{}) { } 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) OnCron(session getty.Session) { } } -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 a8bb6522bfa77867965c9ba625a087fc0c17cc9f..d619a2f8fe78524b3d704cb9de280ebbf534eb12 100644 --- a/protocol/dubbo/pool.go +++ b/protocol/dubbo/pool.go @@ -22,6 +22,7 @@ import ( "math/rand" "net" "sync" + "sync/atomic" "time" ) @@ -38,7 +39,7 @@ type gettyRPCClient struct { 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 @@ func newGettyRPCClientConn(pool *gettyRPCClientPool, protocol, addr string) (*ge 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 @@ func (c *gettyRPCClient) addSession(session getty.Session) { } 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 @@ func (c *gettyRPCClient) removeSession(session getty.Session) { } 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) isAvailable() bool { } 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 @@ func (c *gettyRPCClient) close() error { } 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 @@ func newGettyRPCClientConnPool(rpcClient *Client, size int, ttl time.Duration) * rpcClient: rpcClient, size: size, ttl: int64(ttl.Seconds()), - conns: []*gettyRPCClient{}, + conns: make([]*gettyRPCClient, 0, 16), } } @@ -268,7 +284,7 @@ func (p *gettyRPCClientPool) close() { p.conns = nil p.Unlock() for _, conn := range conns { - conn.close() + conn.safeClose() } } @@ -286,11 +302,12 @@ func (p *gettyRPCClientPool) getGettyRpcClient(protocol, addr string) (*gettyRPC 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) getGettyRpcClient(protocol, addr string) (*gettyRPC } 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) remove(conn *gettyRPCClient) { } } } + +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 8c6c8a5a53af4df9a89eae5db5752eb07f3aa446..a57c29f890cc76aa57b316aba8bead1bb76cf6ff 100644 --- a/protocol/dubbo/readwriter.go +++ b/protocol/dubbo/readwriter.go @@ -23,7 +23,7 @@ import ( ) 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 @@ func (p *RpcClientPackageHandler) Read(ss getty.Session, data []byte) (interface } 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 @@ func (p *RpcServerPackageHandler) Read(ss getty.Session, data []byte) (interface 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 @@ func (p *RpcServerPackageHandler) Read(ss getty.Session, data []byte) (interface 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 8daeee05e2ccc115aad590c2ed80a269360482d5..5f93a794d253bb8a0af3dae42ea7aa627751bbdb 100644 --- a/protocol/dubbo/server.go +++ b/protocol/dubbo/server.go @@ -48,7 +48,7 @@ func init() { 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 1f446803fd6c5f174f51e3fe9496c49ae4991691..9be55e247a730460a3adee5622fa978ef2defbfb 100644 --- a/protocol/jsonrpc/http_test.go +++ b/protocol/jsonrpc/http_test.go @@ -32,6 +32,7 @@ import ( 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 @@ func TestHTTPClient_Call(t *testing.T) { "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 bc88759bf522a35a30e8585429f1db614c3a15ce..8c910339858f4960ad0e394ae6271863d7654adc 100644 --- a/protocol/jsonrpc/jsonrpc_invoker_test.go +++ b/protocol/jsonrpc/jsonrpc_invoker_test.go @@ -29,6 +29,7 @@ import ( 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 @@ func TestJsonrpcInvoker_Invoke(t *testing.T) { "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 6b3a39c68b4fdb417e8d2efaec4a43806acb2219..dc85e0f5e76fd07dbcd11646ae529c98e5323a15 100644 --- a/protocol/jsonrpc/server.go +++ b/protocol/jsonrpc/server.go @@ -25,7 +25,6 @@ import ( "io/ioutil" "net" "net/http" - "reflect" "runtime" "runtime/debug" "sync" @@ -330,13 +329,16 @@ func serveRequest(ctx context.Context, 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 @@ func serveRequest(ctx context.Context, 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 b1392fff511dba2e2cbedf2547d6be2d4276a912..7c58fabea3cccf5a39e1622fedd4a3a297e05983 100644 --- a/protocol/protocolwrapper/protocol_filter_wrapper.go +++ b/protocol/protocolwrapper/protocol_filter_wrapper.go @@ -62,7 +62,7 @@ func (pfw *ProtocolFilterWrapper) Destroy() { } 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 8a332490f71ead601d151fe5e27390eadcc1cbd8..dc376313549c24da1cc6cb64a42e8445ef4fe346 100644 --- a/protocol/protocolwrapper/protocol_filter_wrapper_test.go +++ b/protocol/protocolwrapper/protocol_filter_wrapper_test.go @@ -30,7 +30,8 @@ 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/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 @@ func TestProtocolFilterWrapper_Export(t *testing.T) { 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 @@ func TestProtocolFilterWrapper_Refer(t *testing.T) { 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 78796b6beaf24dac33d7e0210703a9027f9fe568..3a8bfbc87f285e0e86269d44c47d6771566d97b1 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 0000000000000000000000000000000000000000..925baa2198d9917824c1be78b7cd0c2f93bfb894 --- /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 0000000000000000000000000000000000000000..b047a4c08c9f6c809ed3dca8bd0d06ceaa576cae --- /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/registry/consul/listener_test.go b/registry/consul/listener_test.go new file mode 100644 index 0000000000000000000000000000000000000000..7dccbaa9f590e08d9aab539789b8348999672fde --- /dev/null +++ b/registry/consul/listener_test.go @@ -0,0 +1,33 @@ +/* + * 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" +) + +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 0000000000000000000000000000000000000000..1fd3e54e96c446f59dd31ab30575eef5b455b72f --- /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 0000000000000000000000000000000000000000..ff8c2e23163e85b128436bde001455f316b28dc6 --- /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 0000000000000000000000000000000000000000..ee17fcc0df43228e26b40f3ac3f992147fc33d6e --- /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 0000000000000000000000000000000000000000..d66600b773ee78b43ac3da4edf8849d0019c744d --- /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 accc99a458962d046fd4eb7be7cb09a1af616b0e..7ffc702248bfe26f82105be6a7220b86d3c3ae51 100644 --- a/registry/directory/directory.go +++ b/registry/directory/directory.go @@ -32,6 +32,9 @@ import ( "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 Option func(*Options) 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 @@ func NewRegistryDirectory(url *common.URL, registry registry.Registry, opts ...O 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 + } + dir.consumerConfigurationListener = newConsumerConfigurationListener(dir) + return dir, 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) - } - - } +//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 +//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 @@ func (dir *registryDirectory) toGroupInvokers() []protocol.Invoker { 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(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(url.Key(), newInvoker) + dir.cacheInvokersMap.Store(newUrl.Key(), newInvoker) + cacheInvoker.(protocol.Invoker).Destroy() } } } @@ -233,3 +245,58 @@ func (dir *registryDirectory) Destroy() { 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 f31165d0a2e32c89b3d15df3df4e2048dadcb5e5..b3c1d35aaa66b3437ff89807fba2df0a383921cb 100644 --- a/registry/directory/directory_test.go +++ b/registry/directory/directory_test.go @@ -34,12 +34,16 @@ 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/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 @@ func TestSubscribe(t *testing.T) { 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 @@ func TestSubscribe_Group(t *testing.T) { 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{} @@ -116,20 +121,83 @@ func Test_List(t *testing.T) { assert.Len(t, registryDirectory.List(&invocation.RPCInvocation{}), 3) 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 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() (*registryDirectory, *registry.MockRegistry) { +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 a8f2facc1aa43db4daea77c03f332df16f302431..e0dc09908567ffcd8b8f77a9627c83876906e792 100644 --- a/registry/etcdv3/listener.go +++ b/registry/etcdv3/listener.go @@ -12,16 +12,17 @@ import ( 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 @@ func (l *dataListener) DataChange(eventType remoting.Event) bool { 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 @@ func (l *dataListener) DataChange(eventType remoting.Event) bool { 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 0ac8fc475e454e737e0ea03301709457561e961c..00024d28949f8b517d49f45ce6f16422d67b0a6b 100644 --- a/registry/etcdv3/listener_test.go +++ b/registry/etcdv3/listener_test.go @@ -2,6 +2,7 @@ package etcdv3 import ( "context" + "github.com/apache/dubbo-go/config_center" "testing" "time" ) @@ -68,4 +69,4 @@ func TestRegistrySuite(t *testing.T) { 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 5802142989e5d8297f027ddecff3d7780070729f..8bb1ff430eb8e674666266af5169bba4b4e22d30 100644 --- a/registry/etcdv3/registry.go +++ b/registry/etcdv3/registry.go @@ -30,7 +30,10 @@ var ( localIP = "" ) -const Name = "etcdv3" +const ( + Name = "etcdv3" + RegistryConnDelay = 3 +) func init() { processID = fmt.Sprintf("%d", os.Getpid()) @@ -257,10 +260,11 @@ func (r *etcdV3Registry) registerProvider(svc common.URL) error { } 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 @@ func (r *etcdV3Registry) registerProvider(svc common.URL) error { 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 @@ func (r *etcdV3Registry) Subscribe(svc common.URL) (registry.Listener, error) { } //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 26204c74ad4305278e33d9c8b50199cfa578bf8a..6da9ad9d7d13bb0b6f8d1dab9b582669735ceec8 100644 --- a/registry/etcdv3/registry_test.go +++ b/registry/etcdv3/registry_test.go @@ -63,11 +63,11 @@ func (suite *RegistryTestSuite) TestSubscribe() { } //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 @@ func (suite *RegistryTestSuite) TestConsumerDestory() { 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 1fc700edb7cf37eb2613c90d458c58d278507faf..512c452e39082d619ffceae7f82d28127fbe2975 100644 --- a/registry/mock_registry.go +++ b/registry/mock_registry.go @@ -17,12 +17,17 @@ 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 @@ func (r *MockRegistry) GetUrl() common.URL { 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 c42abd0bb16573da33c20c150896f85b3a7edfd0..1f264ec9e4ba9b8e970eba7da3b46d8792831dea 100644 --- a/registry/nacos/listener.go +++ b/registry/nacos/listener.go @@ -19,6 +19,7 @@ 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/registry" "github.com/apache/dubbo-go/remoting" ) @@ -26,7 +27,7 @@ import ( 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 @@ type nacosListener struct { 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 @@ func (nl *nacosListener) Callback(services []model.SubscribeService, err error) 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 @@ func (nl *nacosListener) stopListen() error { 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 bf86ead7a31f5873078b9dc4acd3f0dcf6aec783..f1a78264ce431745181ca6f633eda642cf90a31e 100644 --- a/registry/nacos/registry.go +++ b/registry/nacos/registry.go @@ -7,6 +7,7 @@ import ( "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 @@ 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/utils" "github.com/apache/dubbo-go/registry" ) @@ -27,6 +29,10 @@ var ( localIP = "" ) +const ( + RegistryConnDelay = 3 +) + func init() { localIP, _ = utils.GetLocalIP() extension.SetRegistry(constant.NACOS_KEY, newNacosRegistry) @@ -119,10 +125,13 @@ func appendParam(target *bytes.Buffer, url common.URL, key string) { 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 @@ func (nr *nacosRegistry) Register(url common.URL) error { 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 9ce9dcfe4d9f7d3974a3d07e093f59888e73a91d..023ff788091c0c0f7c83ab213d8ab52006cfdc81 100644 --- a/registry/nacos/registry_test.go +++ b/registry/nacos/registry_test.go @@ -66,9 +66,9 @@ func TestNacosRegistry_Subscribe(t *testing.T) { 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 @@ func TestNacosRegistry_Subscribe_del(t *testing.T) { 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 @@ func TestNacosListener_Close(t *testing.T) { 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 ff33b5fe6e063257c12035f3262e0daae874363e..c746cf8ef291bd198274971aad23e91ba6443e36 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 @@ var ( 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 @@ func getRegistry(regUrl *common.URL) registry.Registry { } 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 @@ func (proto *registryProtocol) Refer(url common.URL) protocol.Invoker { protocol := registryUrl.GetParam(constant.REGISTRY_KEY, "") registryUrl.Protocol = protocol } + var reg registry.Registry if regI, loaded := proto.registries.Load(registryUrl.Key()); !loaded { @@ -83,14 +110,16 @@ func (proto *registryProtocol) Refer(url common.URL) protocol.Invoker { //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) Refer(url common.URL) protocol.Invoker { } 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 @@ func (proto *registryProtocol) Export(invoker protocol.Invoker) protocol.Exporte 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 (proto *registryProtocol) Destroy() { }) } -func (*registryProtocol) getRegistryUrl(invoker protocol.Invoker) common.URL { +func getRegistryUrl(invoker protocol.Invoker) *common.URL { //here add * for return a new url url := invoker.GetUrl() //if the protocol == registry ,set protocol the registry value in url.params @@ -166,12 +325,16 @@ func (*registryProtocol) getRegistryUrl(invoker protocol.Invoker) common.URL { 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 @@ func GetProtocol() protocol.Protocol { 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) +} + +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 (ivk *wrappedInvoker) getInvoker() protocol.Invoker { - return ivk.invoker + +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 418f1f6779679b6eb93a74ff7689ca8e76f2c0af..0c19da59df6e4fd2f663f9e8d541165fe26c3ffa 100644 --- a/registry/protocol/protocol_test.go +++ b/registry/protocol/protocol_test.go @@ -20,6 +20,7 @@ package protocol import ( "context" "testing" + "time" ) import ( @@ -29,13 +30,21 @@ import ( 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 @@ func referNormal(t *testing.T, regProtocol *registryProtocol) { 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 referNormal(t *testing.T, regProtocol *registryProtocol) { } func TestRefer(t *testing.T) { + config.SetConsumerConfig( + config.ConsumerConfig{ + ApplicationConfig: &config.ApplicationConfig{Name: "test-application"}}) regProtocol := newRegistryProtocol() referNormal(t, regProtocol) } @@ -61,7 +77,11 @@ func TestMultiRegRefer(t *testing.T) { 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 @@ func TestOneRegRefer(t *testing.T) { 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 @@ func TestOneRegRefer(t *testing.T) { 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 @@ func exporterNormal(t *testing.T, regProtocol *registryProtocol) { 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 @@ func TestMultiRegAndMultiProtoExporter(t *testing.T) { 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 @@ func TestOneRegAndProtoExporter(t *testing.T) { 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 @@ func TestDestry(t *testing.T) { }) 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 b41ac534ba7daa588bd47d3327383047358033bc..c7279a29e1f423ca200aa2bf9390c127efcf10cb 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -28,10 +28,21 @@ type Registry interface { //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 7d58cee1220b9aedba353d929ca1e936cf9366f2..857421f07706d6bdfec5a3ec21ba674627633458 100644 --- a/registry/zookeeper/listener.go +++ b/registry/zookeeper/listener.go @@ -21,12 +21,15 @@ import ( "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 @@ import ( 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 @@ func (l *RegistryDataListener) DataChange(eventType remoting.Event) bool { } 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 @@ func (l *RegistryDataListener) DataChange(eventType remoting.Event) bool { 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 7ebc32b8a50bcb38d5ac859e4216065559fbd4e5..910d47b7e4e3d27c6f7245777cba1f46adc8e318 100644 --- a/registry/zookeeper/listener_test.go +++ b/registry/zookeeper/listener_test.go @@ -1,11 +1,35 @@ +/* + * 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" + "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" - "github.com/stretchr/testify/assert" - "testing" ) func Test_DataChange(t *testing.T) { @@ -19,5 +43,5 @@ func Test_DataChange(t *testing.T) { 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 ff57eb638aa8919720b9eeed1cb4603cc2928cf2..e14541dd04691bf89825b1d77d79932ad54f7720 100644 --- a/registry/zookeeper/registry.go +++ b/registry/zookeeper/registry.go @@ -44,7 +44,8 @@ import ( ) const ( - RegistryZkClient = "zk registry" + RegistryZkClient = "zk registry" + RegistryConnDelay = 3 ) var ( @@ -80,7 +81,6 @@ type zkRegistry struct { 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 @@ func (r *zkRegistry) register(c common.URL) error { 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 @@ func (r *zkRegistry) registerTempZookeeperNode(root string, node string) error { 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 @@ func (r *zkRegistry) getListener(conf common.URL) (*RegistryConfigurationListene } //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 2b5e2f8f7caf749be28bf3ff6e5d14980d70f2f4..841c38da7fbf1830b6f7c55809fc50d52468ef46 100644 --- a/registry/zookeeper/registry_test.go +++ b/registry/zookeeper/registry_test.go @@ -60,11 +60,11 @@ func Test_Subscribe(t *testing.T) { } //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 @@ func Test_ConsumerDestory(t *testing.T) { 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 59273af554a63e5fc907ba5a30bb1e18bb22c0f5..f5401917e208f41d3ea84e47c46f535b344e2784 100644 --- a/remoting/etcdv3/listener.go +++ b/remoting/etcdv3/listener.go @@ -100,7 +100,7 @@ func (l *EventListener) handleEvents(event *clientv3.Event, listeners ...remotin 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 fd566f353857943acd620af5da21e85054dff646..8d1e357d37ff92e7bf60121133998dc1745c9af8 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 @@ type EventType int const ( EventTypeAdd = iota EventTypeDel - EvnetTypeUpdate + EventTypeUpdate ) var serviceEventTypeStrings = [...]string{ diff --git a/remoting/zookeeper/listener.go b/remoting/zookeeper/listener.go index b8da16dcb2a2856b43f4cbd5f292568bb40f8a68..9521ea749027582c015ac998a6f6f68d350cc3bc 100644 --- a/remoting/zookeeper/listener.go +++ b/remoting/zookeeper/listener.go @@ -47,9 +47,11 @@ func NewZkEventListener(client *ZookeeperClient) *ZkEventListener { 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 @@ func (l *ZkEventListener) ListenServiceNodeEvent(zkPath string, listener ...remo 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 @@ func (l *ZkEventListener) handleZkNodeEvent(zkPath string, children []string, li return true } } - return false } @@ -130,14 +130,14 @@ func (l *ZkEventListener) handleZkNodeEvent(zkPath string, children []string, li 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 @@ func (l *ZkEventListener) listenDirEvent(zkPath string, listener remoting.DataLi } 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 @@ func (l *ZkEventListener) listenDirEvent(zkPath string, listener remoting.DataLi 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 @@ func timeSecondDuration(sec int) time.Duration { 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 @@ func (l *ZkEventListener) ListenServiceEvent(zkPath string, listener remoting.Da } for _, c := range children { - // listen l service node dubboPath = path.Join(zkPath, c) content, _, err := l.client.Conn.Get(dubboPath) @@ -305,12 +303,12 @@ func (l *ZkEventListener) ListenServiceEvent(zkPath string, listener remoting.Da 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 8b133336e7242da6505132836748880259bf5e1d..a90fbad05ae787f36d38607b0a73374d874e6994 100644 --- a/remoting/zookeeper/listener_test.go +++ b/remoting/zookeeper/listener_test.go @@ -117,6 +117,8 @@ func (m *mockDataListener) DataChange(eventType remoting.Event) bool { m.eventList = append(m.eventList, eventType) if eventType.Content == m.changedData { m.wait.Done() + m.client.Close() + } return true }