diff --git a/.asf.yaml b/.asf.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8d84e695a59e8064cf06a2f8879564efd5588d44 --- /dev/null +++ b/.asf.yaml @@ -0,0 +1,5 @@ +notifications: + commits: commits@dubbo.apache.org + issues: notifications@dubbo.apache.org + pullrequests: notifications@dubbo.apache.org + jira_options: link label link label diff --git a/.travis.yml b/.travis.yml index 1b46f5d872932b7ed307ceaf802c95997b2800e6..566c88ece05bd80175eea2d1de8fd061a279e273 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,23 +1,32 @@ -language: go +dist: trusty +sudo: required +# define the dependence env +language: go os: - linux - go: - "1.13" - +services: + - docker env: - GO111MODULE=on - install: true +# define ci-stage script: + # license-check + - echo 'start license check' - go fmt ./... && [[ -z `git status -s` ]] - sh before_validate_license.sh - chmod u+x /tmp/tools/license/license-header-checker - /tmp/tools/license/license-header-checker -v -a -r -i vendor /tmp/tools/license/license.txt . go && [[ -z `git status -s` ]] + # unit-test + - echo 'start unit-test' - chmod u+x before_ut.sh && ./before_ut.sh - go mod vendor && go test ./... -coverprofile=coverage.txt -covermode=atomic + # integrate-test + - chmod +x integrate_test.sh && ./integrate_test.sh after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/cluster/cluster_impl/available_cluster_invoker_test.go b/cluster/cluster_impl/available_cluster_invoker_test.go index c2cebd3843d453a2d46d031e711e0efebd240fda..61d1c934522008e4d9bc46bbd57eb6fed6bf00f9 100644 --- a/cluster/cluster_impl/available_cluster_invoker_test.go +++ b/cluster/cluster_impl/available_cluster_invoker_test.go @@ -42,7 +42,7 @@ var ( availableUrl, _ = common.NewURL("dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider") ) -func registerAvailable(t *testing.T, invoker *mock.MockInvoker) protocol.Invoker { +func registerAvailable(invoker *mock.MockInvoker) protocol.Invoker { extension.SetLoadbalance("random", loadbalance.NewRandomLoadBalance) availableCluster := NewAvailableCluster() @@ -60,7 +60,7 @@ func TestAvailableClusterInvokerSuccess(t *testing.T) { defer ctrl.Finish() invoker := mock.NewMockInvoker(ctrl) - clusterInvoker := registerAvailable(t, invoker) + clusterInvoker := registerAvailable(invoker) mockResult := &protocol.RPCResult{Rest: rest{tried: 0, success: true}} invoker.EXPECT().IsAvailable().Return(true) @@ -76,7 +76,7 @@ func TestAvailableClusterInvokerNoAvail(t *testing.T) { defer ctrl.Finish() invoker := mock.NewMockInvoker(ctrl) - clusterInvoker := registerAvailable(t, invoker) + clusterInvoker := registerAvailable(invoker) invoker.EXPECT().IsAvailable().Return(false) diff --git a/cluster/cluster_impl/base_cluster_invoker.go b/cluster/cluster_impl/base_cluster_invoker.go index 12799994125c4bf5d968dfc811cda374effbf85c..cabd6c5f17cd3a3310054c0ff7b9a9877d581345 100644 --- a/cluster/cluster_impl/base_cluster_invoker.go +++ b/cluster/cluster_impl/base_cluster_invoker.go @@ -87,7 +87,6 @@ func (invoker *baseClusterInvoker) checkWhetherDestroyed() error { } func (invoker *baseClusterInvoker) doSelect(lb cluster.LoadBalance, invocation protocol.Invocation, invokers []protocol.Invoker, invoked []protocol.Invoker) protocol.Invoker { - var selectedInvoker protocol.Invoker url := invokers[0].GetUrl() sticky := url.GetParamBool(constant.STICKY_KEY, false) diff --git a/cluster/cluster_impl/failover_cluster_test.go b/cluster/cluster_impl/failover_cluster_test.go index 1be21067a6a9045cb6ae6f84655d516fea1f844b..ee7d48f3497772db3143b1ae62a30f66f99faa58 100644 --- a/cluster/cluster_impl/failover_cluster_test.go +++ b/cluster/cluster_impl/failover_cluster_test.go @@ -107,8 +107,8 @@ func normalInvoke(t *testing.T, successCount int, urlParam url.Values, invocatio invokers := []protocol.Invoker{} for i := 0; i < 10; i++ { - url, _ := common.NewURL(fmt.Sprintf("dubbo://192.168.1.%v:20000/com.ikurento.user.UserProvider", i), common.WithParams(urlParam)) - invokers = append(invokers, NewMockInvoker(url, successCount)) + newUrl, _ := common.NewURL(fmt.Sprintf("dubbo://192.168.1.%v:20000/com.ikurento.user.UserProvider", i), common.WithParams(urlParam)) + invokers = append(invokers, NewMockInvoker(newUrl, successCount)) } staticDir := directory.NewStaticDirectory(invokers) diff --git a/cluster/directory/base_directory.go b/cluster/directory/base_directory.go index a3e207f3022a4d882d1b90f2756b51ab4e0b2775..3ede3d8c0ab3691603ac69c10202155e0a331d26 100644 --- a/cluster/directory/base_directory.go +++ b/cluster/directory/base_directory.go @@ -89,7 +89,7 @@ func (dir *BaseDirectory) SetRouters(urls []*common.URL) { factory := extension.GetRouterFactory(url.Protocol) r, err := factory.NewRouter(url) if err != nil { - logger.Errorf("Create router fail. router key: %s, error: %v", routerKey, url.Service(), err) + logger.Errorf("Create router fail. router key: %s, url:%s, error: %+v", routerKey, url.Service(), err) return } routers = append(routers, r) diff --git a/cluster/directory/base_directory_test.go b/cluster/directory/base_directory_test.go index d5993959f1d37f343a612e2bee305461d49535d0..6dc55b39407c9e88d18a65b5ec02fa866571624b 100644 --- a/cluster/directory/base_directory_test.go +++ b/cluster/directory/base_directory_test.go @@ -19,7 +19,6 @@ package directory import ( "encoding/base64" - "fmt" "testing" ) @@ -35,7 +34,7 @@ import ( ) func TestNewBaseDirectory(t *testing.T) { - url, _ := common.NewURL(fmt.Sprintf("dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider")) + url, _ := common.NewURL("dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider") directory := NewBaseDirectory(&url) assert.NotNil(t, directory) @@ -46,7 +45,7 @@ func TestNewBaseDirectory(t *testing.T) { } func TestBuildRouterChain(t *testing.T) { - url, _ := common.NewURL(fmt.Sprintf("dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider")) + url, _ := common.NewURL("dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider") directory := NewBaseDirectory(&url) assert.NotNil(t, directory) diff --git a/cluster/directory/static_directory.go b/cluster/directory/static_directory.go index 9f600fedc40cf29a40abca6c11652935f20473b4..87f51356495dbd0a956c42bf4f34022b4d21ad4d 100644 --- a/cluster/directory/static_directory.go +++ b/cluster/directory/static_directory.go @@ -61,7 +61,7 @@ func (dir *staticDirectory) IsAvailable() bool { // List List invokers func (dir *staticDirectory) List(invocation protocol.Invocation) []protocol.Invoker { l := len(dir.invokers) - invokers := make([]protocol.Invoker, l, l) + invokers := make([]protocol.Invoker, l) copy(invokers, dir.invokers) routerChain := dir.RouterChain() diff --git a/cluster/loadbalance/consistent_hash.go b/cluster/loadbalance/consistent_hash.go index 957c110663d6c56ada15543d372e210fa83bf74b..492434431f7382545cb747fa3611c6b18279fa4d 100644 --- a/cluster/loadbalance/consistent_hash.go +++ b/cluster/loadbalance/consistent_hash.go @@ -27,7 +27,9 @@ import ( "strconv" "strings" ) - +import ( + gxsort "github.com/dubbogo/gost/sort" +) import ( "github.com/apache/dubbo-go/cluster" "github.com/apache/dubbo-go/common/constant" @@ -40,7 +42,7 @@ const ( ConsistentHash = "consistenthash" // HashNodes ... HashNodes = "hash.nodes" - // HashArguments ... + // HashArguments key of hash arguments in url HashArguments = "hash.arguments" ) @@ -53,16 +55,16 @@ func init() { extension.SetLoadbalance(ConsistentHash, NewConsistentHashLoadBalance) } -// ConsistentHashLoadBalance ... +// ConsistentHashLoadBalance implementation of load balancing: using consistent hashing type ConsistentHashLoadBalance struct { } -// NewConsistentHashLoadBalance ... +// NewConsistentHashLoadBalance creates NewConsistentHashLoadBalance func NewConsistentHashLoadBalance() cluster.LoadBalance { return &ConsistentHashLoadBalance{} } -// Select ... +// Select gets invoker based on load balancing strategy func (lb *ConsistentHashLoadBalance) Select(invokers []protocol.Invoker, invocation protocol.Invocation) protocol.Invoker { methodName := invocation.MethodName() key := invokers[0].GetUrl().ServiceKey() + "." + methodName @@ -85,27 +87,12 @@ func (lb *ConsistentHashLoadBalance) Select(invokers []protocol.Invoker, invocat return selector.Select(invocation) } -// Uint32Slice ... -type Uint32Slice []uint32 - -func (s Uint32Slice) Len() int { - return len(s) -} - -func (s Uint32Slice) Less(i, j int) bool { - return s[i] < s[j] -} - -func (s Uint32Slice) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -// ConsistentHashSelector ... +// ConsistentHashSelector implementation of Selector:get invoker based on load balancing strategy type ConsistentHashSelector struct { hashCode uint32 replicaNum int virtualInvokers map[uint32]protocol.Invoker - keys Uint32Slice + keys gxsort.Uint32Slice argumentIndex []int } @@ -141,7 +128,7 @@ func newConsistentHashSelector(invokers []protocol.Invoker, methodName string, return selector } -// Select ... +// Select gets invoker based on load balancing strategy func (c *ConsistentHashSelector) Select(invocation protocol.Invocation) protocol.Invoker { key := c.toKey(invocation.Arguments()) digest := md5.Sum([]byte(key)) diff --git a/common/config/environment.go b/common/config/environment.go index 071af31152ba4ce3c579f70aa23df59d718ce506..446c46aa1ef71a68aa024bf83dd9088cf03677f2 100644 --- a/common/config/environment.go +++ b/common/config/environment.go @@ -46,7 +46,7 @@ var ( once sync.Once ) -// GetEnvInstance ... +// GetEnvInstance gets env instance by singleton func GetEnvInstance() *Environment { once.Do(func() { instance = &Environment{configCenterFirst: true} @@ -54,7 +54,7 @@ func GetEnvInstance() *Environment { return instance } -// NewEnvInstance ... +// NewEnvInstance creates Environment instance func NewEnvInstance() { instance = &Environment{configCenterFirst: true} } @@ -67,21 +67,22 @@ func NewEnvInstance() { // return env.configCenterFirst //} -// UpdateExternalConfigMap ... +// UpdateExternalConfigMap updates env externalConfigMap field func (env *Environment) UpdateExternalConfigMap(externalMap map[string]string) { for k, v := range externalMap { env.externalConfigMap.Store(k, v) } } -// UpdateAppExternalConfigMap ... +// UpdateAppExternalConfigMap updates env appExternalConfigMap field func (env *Environment) UpdateAppExternalConfigMap(externalMap map[string]string) { for k, v := range externalMap { env.appExternalConfigMap.Store(k, v) } } -// Configuration ... +// Configuration puts externalConfigMap and appExternalConfigMap into list +// List represents a doubly linked list. func (env *Environment) Configuration() *list.List { cfgList := list.New() // The sequence would be: SystemConfiguration -> ExternalConfiguration -> AppExternalConfiguration -> AbstractConfig -> PropertiesConfiguration @@ -90,17 +91,17 @@ func (env *Environment) Configuration() *list.List { return cfgList } -// SetDynamicConfiguration ... +// SetDynamicConfiguration sets value for dynamicConfiguration func (env *Environment) SetDynamicConfiguration(dc config_center.DynamicConfiguration) { env.dynamicConfiguration = dc } -// GetDynamicConfiguration ... +// GetDynamicConfiguration gets dynamicConfiguration func (env *Environment) GetDynamicConfiguration() config_center.DynamicConfiguration { return env.dynamicConfiguration } -// InmemoryConfiguration ... +// InmemoryConfiguration stores config in memory type InmemoryConfiguration struct { store *sync.Map } @@ -109,7 +110,7 @@ func newInmemoryConfiguration(p *sync.Map) *InmemoryConfiguration { return &InmemoryConfiguration{store: p} } -// GetProperty ... +// GetProperty gets value from InmemoryConfiguration instance by @key func (conf *InmemoryConfiguration) GetProperty(key string) (bool, string) { if conf.store == nil { return false, "" @@ -123,7 +124,7 @@ func (conf *InmemoryConfiguration) GetProperty(key string) (bool, string) { return false, "" } -// GetSubProperty ... +// GetSubProperty gets sub property from InmemoryConfiguration instance by @subkey func (conf *InmemoryConfiguration) GetSubProperty(subKey string) map[string]struct{} { if conf.store == nil { return nil diff --git a/common/constant/key.go b/common/constant/key.go index eafed2eeeb88e0606ac92766c8dd84ff6b42b58e..15496628ebef49517abc2e6811822a34b94caddf 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -187,6 +187,9 @@ const ( // ForceUseTag is the tag in attachment ForceUseTag = "dubbo.force.tag" Tagkey = "dubbo.tag" + + // Attachment key in context in invoker + AttachmentKey = "attachment" ) const ( diff --git a/common/extension/auth.go b/common/extension/auth.go index d7900045d3f7db9e2587e4e92e377325c74971b3..7caae00e84fd80666ff79b599e12f8516e23209c 100644 --- a/common/extension/auth.go +++ b/common/extension/auth.go @@ -26,12 +26,12 @@ var ( accesskeyStorages = make(map[string]func() filter.AccessKeyStorage) ) -// SetAuthenticator put the fcn into map with name +// SetAuthenticator puts the @fcn into map with name func SetAuthenticator(name string, fcn func() filter.Authenticator) { authenticators[name] = fcn } -// GetAuthenticator find the Authenticator with name +// GetAuthenticator finds the Authenticator with @name // if not found, it will panic func GetAuthenticator(name string) filter.Authenticator { if authenticators[name] == nil { @@ -40,12 +40,12 @@ func GetAuthenticator(name string) filter.Authenticator { return authenticators[name]() } -// SetAccesskeyStorages will set the fcn into map with this name +// SetAccesskeyStorages will set the @fcn into map with this name func SetAccesskeyStorages(name string, fcn func() filter.AccessKeyStorage) { accesskeyStorages[name] = fcn } -// GetAccesskeyStorages find the storage with the name. +// GetAccesskeyStorages finds the storage with the @name. // If not found, it will panic. func GetAccesskeyStorages(name string) filter.AccessKeyStorage { if accesskeyStorages[name] == nil { diff --git a/common/extension/cluster.go b/common/extension/cluster.go index b2d81f6b1e56bb487b1d408b878308f6dfe042e4..8be27a1ca3aaf93dd54201c4ff7081478c746f0f 100644 --- a/common/extension/cluster.go +++ b/common/extension/cluster.go @@ -25,12 +25,13 @@ var ( clusters = make(map[string]func() cluster.Cluster) ) -// SetCluster ... +// SetCluster sets the cluster fault-tolerant mode with @name +// For example: available/failfast/broadcast/failfast/failsafe/... func SetCluster(name string, fcn func() cluster.Cluster) { clusters[name] = fcn } -// GetCluster ... +// GetCluster finds the cluster fault-tolerant mode with @name func GetCluster(name string) cluster.Cluster { if clusters[name] == nil { panic("cluster for " + name + " is not existing, make sure you have import the package.") diff --git a/common/extension/config_center.go b/common/extension/config_center.go index 03d27db46c94b0ea0e212646077d97f948a8e328..3cbced8d3bbcdb3dc7f9af800fa36681d6dc063d 100644 --- a/common/extension/config_center.go +++ b/common/extension/config_center.go @@ -26,12 +26,12 @@ var ( configCenters = make(map[string]func(config *common.URL) (config_center.DynamicConfiguration, error)) ) -// SetConfigCenter ... +// SetConfigCenter sets the DynamicConfiguration with @name func SetConfigCenter(name string, v func(config *common.URL) (config_center.DynamicConfiguration, error)) { configCenters[name] = v } -// GetConfigCenter ... +// GetConfigCenter finds the DynamicConfiguration with @name func GetConfigCenter(name string, config *common.URL) (config_center.DynamicConfiguration, error) { if configCenters[name] == nil { panic("config center for " + name + " is not existing, make sure you have import the package.") diff --git a/common/extension/config_center_factory.go b/common/extension/config_center_factory.go index 85913fdce1ed3472c2bd9eb4aadbb0f631481dbd..dff89752296c6d2441d043ec628aa13ad219e698 100644 --- a/common/extension/config_center_factory.go +++ b/common/extension/config_center_factory.go @@ -25,12 +25,12 @@ var ( configCenterFactories = make(map[string]func() config_center.DynamicConfigurationFactory) ) -// SetConfigCenterFactory ... +// SetConfigCenterFactory sets the DynamicConfigurationFactory with @name func SetConfigCenterFactory(name string, v func() config_center.DynamicConfigurationFactory) { configCenterFactories[name] = v } -// GetConfigCenterFactory ... +// GetConfigCenterFactory finds the DynamicConfigurationFactory with @name func GetConfigCenterFactory(name string) config_center.DynamicConfigurationFactory { if configCenterFactories[name] == nil { panic("config center for " + name + " is not existing, make sure you have import the package.") diff --git a/common/extension/config_reader.go b/common/extension/config_reader.go index aced5b0281ff9313461425e5ec6d70d562c6c947..5e13d8629fd145dac680619a427c68b29226b051 100644 --- a/common/extension/config_reader.go +++ b/common/extension/config_reader.go @@ -26,12 +26,12 @@ var ( defaults = make(map[string]string) ) -// SetConfigReaders set a creator of config reader. +// SetConfigReaders sets a creator of config reader with @name func SetConfigReaders(name string, v func() interfaces.ConfigReader) { configReaders[name] = v } -// GetConfigReaders get a config reader by name. +// GetConfigReaders gets a config reader with @name func GetConfigReaders(name string) interfaces.ConfigReader { if configReaders[name] == nil { panic("config reader for " + name + " is not existing, make sure you have imported the package.") @@ -39,12 +39,12 @@ func GetConfigReaders(name string) interfaces.ConfigReader { return configReaders[name]() } -// SetDefaultConfigReader set {name} to default config reader for {module} +// SetDefaultConfigReader sets @name for @module in default config reader func SetDefaultConfigReader(module, name string) { defaults[module] = name } -// GetDefaultConfigReader +// GetDefaultConfigReader gets default config reader func GetDefaultConfigReader() map[string]string { return defaults } diff --git a/common/extension/configurator.go b/common/extension/configurator.go index de98f8a260ea1f3a2e2a1f32c82dc869585e2789..dc2bea73afb79aaab36e2ce7cc9675169a446eb7 100644 --- a/common/extension/configurator.go +++ b/common/extension/configurator.go @@ -23,7 +23,7 @@ import ( ) const ( - // DefaultKey ... + // DefaultKey for default Configurator DefaultKey = "default" ) @@ -33,12 +33,12 @@ var ( configurator = make(map[string]getConfiguratorFunc) ) -// SetConfigurator ... +// SetConfigurator sets the getConfiguratorFunc with @name func SetConfigurator(name string, v getConfiguratorFunc) { configurator[name] = v } -// GetConfigurator ... +// GetConfigurator finds the Configurator with @name 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.") @@ -47,12 +47,12 @@ func GetConfigurator(name string, url *common.URL) config_center.Configurator { } -// SetDefaultConfigurator ... +// SetDefaultConfigurator sets the default Configurator func SetDefaultConfigurator(v getConfiguratorFunc) { configurator[DefaultKey] = v } -// GetDefaultConfigurator ... +// GetDefaultConfigurator gets default configurator 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.") @@ -61,7 +61,7 @@ func GetDefaultConfigurator(url *common.URL) config_center.Configurator { } -// GetDefaultConfiguratorFunc ... +// GetDefaultConfiguratorFunc gets default configurator function func GetDefaultConfiguratorFunc() getConfiguratorFunc { if configurator[DefaultKey] == nil { panic("configurator for default is not existing, make sure you have import the package.") diff --git a/common/extension/filter.go b/common/extension/filter.go index deea2d908bc2741e0f15ecc36e9d4fc5975e531e..96059c4363060c41f14ececb466ca62bdaefb1a9 100644 --- a/common/extension/filter.go +++ b/common/extension/filter.go @@ -26,12 +26,13 @@ var ( rejectedExecutionHandler = make(map[string]func() filter.RejectedExecutionHandler) ) -// SetFilter ... +// SetFilter sets the filter extension with @name +// For example: hystrix/metrics/token/tracing/limit/... func SetFilter(name string, v func() filter.Filter) { filters[name] = v } -// GetFilter ... +// GetFilter finds the filter extension with @name func GetFilter(name string) filter.Filter { if filters[name] == nil { panic("filter for " + name + " is not existing, make sure you have imported the package.") @@ -39,12 +40,12 @@ func GetFilter(name string) filter.Filter { return filters[name]() } -// SetRejectedExecutionHandler ... +// SetRejectedExecutionHandler sets the RejectedExecutionHandler with @name func SetRejectedExecutionHandler(name string, creator func() filter.RejectedExecutionHandler) { rejectedExecutionHandler[name] = creator } -// GetRejectedExecutionHandler ... +// GetRejectedExecutionHandler finds the RejectedExecutionHandler with @name func GetRejectedExecutionHandler(name string) filter.RejectedExecutionHandler { creator, ok := rejectedExecutionHandler[name] if !ok { diff --git a/common/extension/graceful_shutdown.go b/common/extension/graceful_shutdown.go index 3abd75c0aa328f3553c3d83340ae440b8dfe3356..cb55419aabbce26b41e5b10f49268f6b3ace516d 100644 --- a/common/extension/graceful_shutdown.go +++ b/common/extension/graceful_shutdown.go @@ -49,7 +49,7 @@ func AddCustomShutdownCallback(callback func()) { customShutdownCallbacks.PushBack(callback) } -// GetAllCustomShutdownCallbacks ... +// GetAllCustomShutdownCallbacks gets all custom shutdown callbacks func GetAllCustomShutdownCallbacks() *list.List { return customShutdownCallbacks } diff --git a/common/extension/health_checker.go b/common/extension/health_checker.go index 365c5d0910812efb00eb94408bb226115b037c02..548d4dc761b31773a2a39ccb0ae3de1d7ab39eb4 100644 --- a/common/extension/health_checker.go +++ b/common/extension/health_checker.go @@ -26,12 +26,12 @@ var ( healthCheckers = make(map[string]func(url *common.URL) router.HealthChecker) ) -// SethealthChecker set the HealthChecker with name +// SethealthChecker sets the HealthChecker with @name func SethealthChecker(name string, fcn func(url *common.URL) router.HealthChecker) { healthCheckers[name] = fcn } -// GetHealthChecker get the HealthChecker with name +// GetHealthChecker gets the HealthChecker with @name func GetHealthChecker(name string, url *common.URL) router.HealthChecker { if healthCheckers[name] == nil { panic("healthCheckers for " + name + " is not existing, make sure you have import the package.") diff --git a/common/extension/loadbalance.go b/common/extension/loadbalance.go index 0d557a4640ed892a18ad59a3247763ab5807a593..aa19141014a6c42df0c17dad05301997f67fbd79 100644 --- a/common/extension/loadbalance.go +++ b/common/extension/loadbalance.go @@ -25,12 +25,13 @@ var ( loadbalances = make(map[string]func() cluster.LoadBalance) ) -// SetLoadbalance ... +// SetLoadbalance sets the loadbalance extension with @name +// For example: random/round_robin/consistent_hash/least_active/... func SetLoadbalance(name string, fcn func() cluster.LoadBalance) { loadbalances[name] = fcn } -// GetLoadbalance ... +// GetLoadbalance finds the loadbalance extension with @name func GetLoadbalance(name string) cluster.LoadBalance { if loadbalances[name] == nil { panic("loadbalance for " + name + " is not existing, make sure you have import the package.") diff --git a/common/extension/metadata_report_factory.go b/common/extension/metadata_report_factory.go index 89dab0409987d8959b5761771c8893abaf88673b..593318d01beec1f89d8194c6d4bd18a15c798a0e 100644 --- a/common/extension/metadata_report_factory.go +++ b/common/extension/metadata_report_factory.go @@ -25,12 +25,12 @@ var ( metaDataReportFactories = make(map[string]func() factory.MetadataReportFactory, 8) ) -// SetMetadataReportFactory ... +// SetMetadataReportFactory sets the MetadataReportFactory with @name func SetMetadataReportFactory(name string, v func() factory.MetadataReportFactory) { metaDataReportFactories[name] = v } -// GetMetadataReportFactory ... +// GetMetadataReportFactory finds the MetadataReportFactory with @name func GetMetadataReportFactory(name string) factory.MetadataReportFactory { if metaDataReportFactories[name] == nil { panic("metadata report for " + name + " is not existing, make sure you have import the package.") diff --git a/common/extension/metrics.go b/common/extension/metrics.go index 42fca7a2db36614fcef31dd5ba7324a156164d4f..60cf6bac2384c7367094adad83e01f7dcf64a33d 100644 --- a/common/extension/metrics.go +++ b/common/extension/metrics.go @@ -27,12 +27,12 @@ var ( metricReporterMap = make(map[string]func() metrics.Reporter, 4) ) -// SetMetricReporter set a reporter with the name +// SetMetricReporter sets a reporter with the @name func SetMetricReporter(name string, reporterFunc func() metrics.Reporter) { metricReporterMap[name] = reporterFunc } -// GetMetricReporter find the reporter with name. +// GetMetricReporter finds the reporter with @name. // if not found, it will panic. // we should know that this method usually is called when system starts, so we should panic func GetMetricReporter(name string) metrics.Reporter { diff --git a/common/extension/protocol.go b/common/extension/protocol.go index 009687a17ace8cea567248af655e04604d09d9b8..c89dd08fae5d12b384d6ca4e797343fe79897bbd 100644 --- a/common/extension/protocol.go +++ b/common/extension/protocol.go @@ -25,12 +25,12 @@ var ( protocols = make(map[string]func() protocol.Protocol) ) -// SetProtocol ... +// SetProtocol sets the protocol extension with @name func SetProtocol(name string, v func() protocol.Protocol) { protocols[name] = v } -// GetProtocol ... +// GetProtocol finds the protocol extension with @name func GetProtocol(name string) protocol.Protocol { if protocols[name] == nil { panic("protocol for " + name + " is not existing, make sure you have import the package.") diff --git a/common/extension/proxy_factory.go b/common/extension/proxy_factory.go index 19826bb0560ea0d3fa471c04873b20a6878f57d8..1e326d884b5dd37925c38ffdf0a87e69bf6a865c 100644 --- a/common/extension/proxy_factory.go +++ b/common/extension/proxy_factory.go @@ -25,12 +25,12 @@ var ( proxyFactories = make(map[string]func(...proxy.Option) proxy.ProxyFactory) ) -// SetProxyFactory ... +// SetProxyFactory sets the ProxyFactory extension with @name func SetProxyFactory(name string, f func(...proxy.Option) proxy.ProxyFactory) { proxyFactories[name] = f } -// GetProxyFactory ... +// GetProxyFactory finds the ProxyFactory extension with @name func GetProxyFactory(name string) proxy.ProxyFactory { if name == "" { name = "default" diff --git a/common/extension/registry.go b/common/extension/registry.go index 6ba746dc47382927d12ce39b7936212c5d75153d..291a7a7fc2cae07c9228043acae7cc0ed5459a1f 100644 --- a/common/extension/registry.go +++ b/common/extension/registry.go @@ -26,12 +26,12 @@ var ( registrys = make(map[string]func(config *common.URL) (registry.Registry, error)) ) -// SetRegistry ... +// SetRegistry sets the registry extension with @name func SetRegistry(name string, v func(config *common.URL) (registry.Registry, error)) { registrys[name] = v } -// GetRegistry ... +// GetRegistry finds the registry extension with @name func GetRegistry(name string, config *common.URL) (registry.Registry, error) { if registrys[name] == nil { panic("registry for " + name + " is not existing, make sure you have import the package.") diff --git a/common/extension/registry_directory.go b/common/extension/registry_directory.go index 6b92189c4e98b391a90e6e71a68d51a252eede2a..330fc46400daf81047e5c24c1634249e355d74b7 100644 --- a/common/extension/registry_directory.go +++ b/common/extension/registry_directory.go @@ -27,12 +27,12 @@ type registryDirectory func(url *common.URL, registry registry.Registry) (cluste var defaultRegistry registryDirectory -// SetDefaultRegistryDirectory ... +// SetDefaultRegistryDirectory sets the default registryDirectory func SetDefaultRegistryDirectory(v registryDirectory) { defaultRegistry = v } -// GetDefaultRegistryDirectory ... +// GetDefaultRegistryDirectory finds the registryDirectory with url and registry func GetDefaultRegistryDirectory(config *common.URL, registry registry.Registry) (cluster.Directory, error) { if defaultRegistry == nil { panic("registry directory is not existing, make sure you have import the package.") diff --git a/common/extension/rest_client.go b/common/extension/rest_client.go index 514d1fdfd2efb5c291fdb47df4dd69da26fa90b1..9caf8c67df76bb160d5e2c3100f83e2d198b6381 100644 --- a/common/extension/rest_client.go +++ b/common/extension/rest_client.go @@ -25,10 +25,12 @@ var ( restClients = make(map[string]func(restOptions *client.RestOptions) client.RestClient, 8) ) +// SetRestClient sets the RestClient with @name func SetRestClient(name string, fun func(restOptions *client.RestOptions) client.RestClient) { restClients[name] = fun } +// GetNewRestClient finds the RestClient with @name func GetNewRestClient(name string, restOptions *client.RestOptions) client.RestClient { if restClients[name] == nil { panic("restClient for " + name + " is not existing, make sure you have import the package.") diff --git a/common/extension/rest_server.go b/common/extension/rest_server.go index fa8d435a5c976a4c95b036810fa2916a327a73b9..37a231a57c861ae49aab244eb9fa8b611ae63f6d 100644 --- a/common/extension/rest_server.go +++ b/common/extension/rest_server.go @@ -25,10 +25,12 @@ var ( restServers = make(map[string]func() server.RestServer, 8) ) +// SetRestServer sets the RestServer with @name func SetRestServer(name string, fun func() server.RestServer) { restServers[name] = fun } +// GetNewRestServer finds the RestServer with @name func GetNewRestServer(name string) server.RestServer { if restServers[name] == nil { panic("restServer for " + name + " is not existing, make sure you have import the package.") diff --git a/common/extension/router_factory.go b/common/extension/router_factory.go index 1339228618def41ccebc8d54cdebb5a623e605fa..21a49d2681b500bf4e4942d1b92e5b23bc7cf6b7 100644 --- a/common/extension/router_factory.go +++ b/common/extension/router_factory.go @@ -31,12 +31,12 @@ var ( fileRouterFactories = make(map[string]router.FileRouterFactory) ) -// SetRouterFactory Set create router factory function by name +// SetRouterFactory sets create router factory function with @name func SetRouterFactory(name string, fun func() router.RouterFactory) { routers[name] = fun } -// GetRouterFactory Get create router factory function by name +// GetRouterFactory gets create router factory function by @name func GetRouterFactory(name string) router.RouterFactory { if routers[name] == nil { panic("router_factory for " + name + " is not existing, make sure you have import the package.") @@ -44,12 +44,12 @@ func GetRouterFactory(name string) router.RouterFactory { return routers[name]() } -// GetRouterFactories Get all create router factory function +// GetRouterFactories gets all create router factory function func GetRouterFactories() map[string]func() router.RouterFactory { return routers } -// GetFileRouterFactories Get all create file router factory instance +// GetFileRouterFactories gets all create file router factory instance func GetFileRouterFactories() map[string]router.FileRouterFactory { l := len(routers) if l == 0 { diff --git a/common/extension/service_discovery.go b/common/extension/service_discovery.go index f820721515d9091c454067cf059bc29664e04808..456b14c83dcab4189ea287f2e9f3329109e538c3 100644 --- a/common/extension/service_discovery.go +++ b/common/extension/service_discovery.go @@ -28,7 +28,7 @@ var ( discoveryCreatorMap = make(map[string]func(name string) (registry.ServiceDiscovery, error), 4) ) -// SetServiceDiscovery will store the creator and name +// SetServiceDiscovery will store the @creator and @name // protocol indicate the implementation, like nacos // the name like nacos-1... func SetServiceDiscovery(protocol string, creator func(name string) (registry.ServiceDiscovery, error)) { diff --git a/common/extension/tps_limit.go b/common/extension/tps_limit.go index c72c2b030fc0f391362189bfe18a65582543693a..d25821deee626cb75c94af2257f877c9983023de 100644 --- a/common/extension/tps_limit.go +++ b/common/extension/tps_limit.go @@ -26,12 +26,12 @@ var ( tpsLimiter = make(map[string]func() filter.TpsLimiter) ) -// SetTpsLimiter ... +// SetTpsLimiter sets the TpsLimiter with @name func SetTpsLimiter(name string, creator func() filter.TpsLimiter) { tpsLimiter[name] = creator } -// GetTpsLimiter ... +// GetTpsLimiter finds the TpsLimiter with @name func GetTpsLimiter(name string) filter.TpsLimiter { creator, ok := tpsLimiter[name] if !ok { @@ -41,12 +41,12 @@ func GetTpsLimiter(name string) filter.TpsLimiter { return creator() } -// SetTpsLimitStrategy ... +// SetTpsLimitStrategy sets the TpsLimitStrategyCreator with @name func SetTpsLimitStrategy(name string, creator filter.TpsLimitStrategyCreator) { tpsLimitStrategy[name] = creator } -// GetTpsLimitStrategyCreator ... +// GetTpsLimitStrategyCreator finds the TpsLimitStrategyCreator with @name func GetTpsLimitStrategyCreator(name string) filter.TpsLimitStrategyCreator { creator, ok := tpsLimitStrategy[name] if !ok { diff --git a/common/logger/logger.go b/common/logger/logger.go index 016afe69808f2007541c617f406db64beb511f1c..9bc6a461003d086e8951ebac3d6997774ac69b90 100644 --- a/common/logger/logger.go +++ b/common/logger/logger.go @@ -40,13 +40,13 @@ var ( logger Logger ) -// DubboLogger ... +// nolint type DubboLogger struct { Logger dynamicLevel zap.AtomicLevel } -// Logger ... +// Logger is the interface for Logger types type Logger interface { Info(args ...interface{}) Warn(args ...interface{}) @@ -67,7 +67,7 @@ func init() { } } -// InitLog ... +// InitLog use for init logger by call InitLogger func InitLog(logConfFile string) error { if logConfFile == "" { InitLogger(nil) @@ -96,7 +96,7 @@ func InitLog(logConfFile string) error { return nil } -// InitLogger ... +// InitLogger use for init logger by @conf func InitLogger(conf *zap.Config) { var zapLoggerConfig zap.Config if conf == nil { @@ -125,18 +125,18 @@ func InitLogger(conf *zap.Config) { getty.SetLogger(logger) } -// SetLogger ... +// SetLogger sets logger for dubbo and getty func SetLogger(log Logger) { logger = log getty.SetLogger(logger) } -// GetLogger ... +// GetLogger gets the logger func GetLogger() Logger { return logger } -// SetLoggerLevel ... +// SetLoggerLevel use for set logger level func SetLoggerLevel(level string) bool { if l, ok := logger.(OpsLogger); ok { l.SetLoggerLevel(level) @@ -145,13 +145,13 @@ func SetLoggerLevel(level string) bool { return false } -// OpsLogger ... +// OpsLogger use for the SetLoggerLevel type OpsLogger interface { Logger SetLoggerLevel(level string) } -// SetLoggerLevel ... +// SetLoggerLevel use for set logger level func (dl *DubboLogger) SetLoggerLevel(level string) { l := new(zapcore.Level) l.Set(level) diff --git a/common/logger/logging.go b/common/logger/logging.go index 36d48ee61e8a4a986abfbaa79f3d361cd81494f4..7a31ece203815287384ade282b2a4f12e11abc2a 100644 --- a/common/logger/logging.go +++ b/common/logger/logging.go @@ -17,42 +17,42 @@ package logger -// Info ... +// Info is info level func Info(args ...interface{}) { logger.Info(args...) } -// Warn ... +// Warn is warning level func Warn(args ...interface{}) { logger.Warn(args...) } -// Error ... +// Error is error level func Error(args ...interface{}) { logger.Error(args...) } -// Debug ... +// Debug is debug level func Debug(args ...interface{}) { logger.Debug(args...) } -// Infof ... +// Infof is format info level func Infof(fmt string, args ...interface{}) { logger.Infof(fmt, args...) } -// Warnf ... +// Warnf is format warning level func Warnf(fmt string, args ...interface{}) { logger.Warnf(fmt, args...) } -// Errorf ... +// Errorf is format error level func Errorf(fmt string, args ...interface{}) { logger.Errorf(fmt, args...) } -// Debugf ... +// Debugf is format debug level func Debugf(fmt string, args ...interface{}) { logger.Debugf(fmt, args...) } diff --git a/common/node.go b/common/node.go index 979eee31ef3a63eb21af6c9045aee7f6d784f2ba..4febd78536126c67bdc65fc09d4be47fb869ef5e 100644 --- a/common/node.go +++ b/common/node.go @@ -17,7 +17,7 @@ package common -// Node ... +// Node use for process dubbo node type Node interface { GetUrl() URL IsAvailable() bool diff --git a/common/proxy/proxy.go b/common/proxy/proxy.go index f98a44873aa33589997c8c14b78b403a668bffe9..abcf87cd9d297769bf8aff6fa07d6a4659091eb6 100644 --- a/common/proxy/proxy.go +++ b/common/proxy/proxy.go @@ -25,12 +25,13 @@ import ( 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/protocol" invocation_impl "github.com/apache/dubbo-go/protocol/invocation" ) -// Proxy struct +// nolint type Proxy struct { rpc common.RPCService invoke protocol.Invoker @@ -140,7 +141,7 @@ func (p *Proxy) Implement(v common.RPCService) { } // add user setAttachment - atm := invCtx.Value("attachment") + atm := invCtx.Value(constant.AttachmentKey) if m, ok := atm.(map[string]string); ok { for k, value := range m { inv.SetAttachments(k, value) @@ -148,6 +149,9 @@ func (p *Proxy) Implement(v common.RPCService) { } result := p.invoke.Invoke(invCtx, inv) + if len(result.Attachments()) > 0 { + invCtx = context.WithValue(invCtx, constant.AttachmentKey, result.Attachments()) + } err = result.Error() logger.Debugf("[makeDubboCallProxy] result: %v, err: %v", result.Result(), err) @@ -201,12 +205,12 @@ func (p *Proxy) Implement(v common.RPCService) { } -// Get get rpc service instance. +// Get gets rpc service instance. func (p *Proxy) Get() common.RPCService { return p.rpc } -// GetCallback get callback. +// GetCallback gets callback. func (p *Proxy) GetCallback() interface{} { return p.callBack } diff --git a/common/proxy/proxy_factory.go b/common/proxy/proxy_factory.go index 34fa3fd07eacae95351f302158d7da68165ea5cf..117428cb253e1ad4a4ceee59aa620d7097b41a75 100644 --- a/common/proxy/proxy_factory.go +++ b/common/proxy/proxy_factory.go @@ -29,5 +29,5 @@ type ProxyFactory interface { GetInvoker(url common.URL) protocol.Invoker } -// Option ... +// Option will define a function of handling ProxyFactory type Option func(ProxyFactory) diff --git a/common/proxy/proxy_factory/default.go b/common/proxy/proxy_factory/default.go index 114cfee2363022da5f7957a825a16fc42b8c928f..1bb1e29c5ced78ad9e2e2483b73379c66328050a 100644 --- a/common/proxy/proxy_factory/default.go +++ b/common/proxy/proxy_factory/default.go @@ -40,7 +40,7 @@ func init() { extension.SetProxyFactory("default", NewDefaultProxyFactory) } -// DefaultProxyFactory ... +// DefaultProxyFactory is the default proxy factory type DefaultProxyFactory struct { //delegate ProxyFactory } @@ -53,17 +53,17 @@ type DefaultProxyFactory struct { // } //} -// NewDefaultProxyFactory ... +// NewDefaultProxyFactory returns a proxy factory instance func NewDefaultProxyFactory(options ...proxy.Option) proxy.ProxyFactory { return &DefaultProxyFactory{} } -// GetProxy ... +// GetProxy gets a proxy func (factory *DefaultProxyFactory) GetProxy(invoker protocol.Invoker, url *common.URL) *proxy.Proxy { return factory.GetAsyncProxy(invoker, nil, url) } -// GetAsyncProxy ... +// GetAsyncProxy gets a async proxy func (factory *DefaultProxyFactory) GetAsyncProxy(invoker protocol.Invoker, callBack interface{}, url *common.URL) *proxy.Proxy { //create proxy attachments := map[string]string{} @@ -71,19 +71,19 @@ func (factory *DefaultProxyFactory) GetAsyncProxy(invoker protocol.Invoker, call return proxy.NewProxy(invoker, callBack, attachments) } -// GetInvoker ... +// GetInvoker gets a invoker func (factory *DefaultProxyFactory) GetInvoker(url common.URL) protocol.Invoker { return &ProxyInvoker{ BaseInvoker: *protocol.NewBaseInvoker(url), } } -// ProxyInvoker ... +// ProxyInvoker is a invoker struct type ProxyInvoker struct { protocol.BaseInvoker } -// Invoke ... +// Invoke is used to call service method by invocation func (pi *ProxyInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result { result := &protocol.RPCResult{} result.SetAttachments(invocation.Attachments()) @@ -113,6 +113,7 @@ func (pi *ProxyInvoker) Invoke(ctx context.Context, invocation protocol.Invocati in := []reflect.Value{svc.Rcvr()} if method.CtxType() != nil { + ctx = context.WithValue(ctx, constant.AttachmentKey, invocation.Attachments()) in = append(in, method.SuiteContext(ctx)) } diff --git a/common/rpc_service.go b/common/rpc_service.go index 90ebdaa6dc9acb8c06a0155e77d6b38c481c0a9e..2eeb52bdfbea21825f7702a750cabe73a3a09bf6 100644 --- a/common/rpc_service.go +++ b/common/rpc_service.go @@ -35,23 +35,23 @@ import ( ) // RPCService -//rpc service interface +// rpc service interface type RPCService interface { // Reference: // rpc service id or reference id Reference() string } -//AsyncCallbackService callback interface for async +// AsyncCallbackService callback interface for async type AsyncCallbackService interface { // Callback: callback CallBack(response CallbackResponse) } -//CallbackResponse for different protocol +// CallbackResponse for different protocol type CallbackResponse interface{} -//AsyncCallback async callback method +// AsyncCallback async callback method type AsyncCallback func(response CallbackResponse) // for lowercase func @@ -87,27 +87,27 @@ type MethodType struct { replyType reflect.Type // return value, otherwise it is nil } -// Method get @m.method. +// Method gets @m.method. func (m *MethodType) Method() reflect.Method { return m.method } -// CtxType get @m.ctxType. +// CtxType gets @m.ctxType. func (m *MethodType) CtxType() reflect.Type { return m.ctxType } -// ArgsType get @m.argsType. +// ArgsType gets @m.argsType. func (m *MethodType) ArgsType() []reflect.Type { return m.argsType } -// ReplyType get @m.replyType. +// ReplyType gets @m.replyType. func (m *MethodType) ReplyType() reflect.Type { return m.replyType } -// SuiteContext tranfer @ctx to reflect.Value type or get it from @m.ctxType. +// SuiteContext tranfers @ctx to reflect.Value type or get it from @m.ctxType. func (m *MethodType) SuiteContext(ctx context.Context) reflect.Value { if contextv := reflect.ValueOf(ctx); contextv.IsValid() { return contextv @@ -127,7 +127,7 @@ type Service struct { methods map[string]*MethodType } -// Method get @s.methods. +// Method gets @s.methods. func (s *Service) Method() map[string]*MethodType { return s.methods } @@ -137,12 +137,12 @@ func (s *Service) Name() string { return s.name } -// RcvrType get @s.rcvrType. +// RcvrType gets @s.rcvrType. func (s *Service) RcvrType() reflect.Type { return s.rcvrType } -// Rcvr get @s.rcvr. +// Rcvr gets @s.rcvr. func (s *Service) Rcvr() reflect.Value { return s.rcvr } @@ -157,7 +157,7 @@ type serviceMap struct { interfaceMap map[string][]*Service // interface -> service } -// GetService get a service defination by protocol and name +// GetService gets a service defination by protocol and name func (sm *serviceMap) GetService(protocol, name string) *Service { sm.mutex.RLock() defer sm.mutex.RUnlock() @@ -170,7 +170,7 @@ func (sm *serviceMap) GetService(protocol, name string) *Service { return nil } -// GetInterface get an interface defination by interface name +// GetInterface gets an interface defination by interface name func (sm *serviceMap) GetInterface(interfaceName string) []*Service { sm.mutex.RLock() defer sm.mutex.RUnlock() @@ -180,7 +180,7 @@ func (sm *serviceMap) GetInterface(interfaceName string) []*Service { return nil } -// Register register a service by @interfaceName and @protocol +// Register registers a service by @interfaceName and @protocol func (sm *serviceMap) Register(interfaceName, protocol string, rcvr RPCService) (string, error) { if sm.serviceMap[protocol] == nil { sm.serviceMap[protocol] = make(map[string]*Service) @@ -228,7 +228,7 @@ func (sm *serviceMap) Register(interfaceName, protocol string, rcvr RPCService) return strings.TrimSuffix(methods, ","), nil } -// UnRegister cancel a service by @interfaceName, @protocol and @serviceId +// UnRegister cancels a service by @interfaceName, @protocol and @serviceId func (sm *serviceMap) UnRegister(interfaceName, protocol, serviceId string) error { if protocol == "" || serviceId == "" { return perrors.New("protocol or serviceName is nil") diff --git a/common/url.go b/common/url.go index a70ac7dc9dd6f415aa458689864604a793c8e256..1cfa47ae28451a6ab6c00029247ba7179b43371a 100644 --- a/common/url.go +++ b/common/url.go @@ -18,7 +18,6 @@ package common import ( - "bytes" "encoding/base64" "fmt" "math" @@ -26,7 +25,6 @@ import ( "net/url" "strconv" "strings" - "sync" ) import ( @@ -40,136 +38,140 @@ import ( "github.com/apache/dubbo-go/common/constant" ) -///////////////////////////////// +// /////////////////////////////// // dubbo role type -///////////////////////////////// +// /////////////////////////////// // role constant const ( - // CONSUMER ... + // CONSUMER is consumer role CONSUMER = iota - // CONFIGURATOR ... + // CONFIGURATOR is configurator role CONFIGURATOR - // ROUTER ... + // ROUTER is router role ROUTER - // PROVIDER ... + // PROVIDER is provider role PROVIDER ) var ( - // DubboNodes ... + // DubboNodes Dubbo service node DubboNodes = [...]string{"consumers", "configurators", "routers", "providers"} // DubboRole Dubbo service role DubboRole = [...]string{"consumer", "", "routers", "provider"} ) -// RoleType ... +// nolint type RoleType int func (t RoleType) String() string { return DubboNodes[t] } -// Role ... +// Role returns role by @RoleType func (t RoleType) Role() string { return DubboRole[t] } type baseUrl struct { - Protocol string - Location string // ip+port - Ip string - Port string - //url.Values is not safe map, add to avoid concurrent map read and map write error - paramsLock sync.RWMutex + Protocol string + Location string // ip+port + Ip string + Port string params url.Values PrimitiveURL string } -// URL ... +// URL is not thread-safe. +// we fail to define this struct to be immutable object. +// but, those method which will update the URL, including SetParam, SetParams +// are only allowed to be invoked in creating URL instance +// Please keep in mind that this struct is immutable after it has been created and initialized. type URL struct { baseUrl Path string // like /com.ikurento.dubbo.UserProvider3 Username string Password string Methods []string - //special for registry + // special for registry SubURL *URL } +// Option accepts url +// Option will define a function of handling URL type option func(*URL) -// WithUsername ... +// WithUsername sets username for url func WithUsername(username string) option { return func(url *URL) { url.Username = username } } -// WithPassword ... +// WithPassword sets password for url func WithPassword(pwd string) option { return func(url *URL) { url.Password = pwd } } -// WithMethods ... +// WithMethods sets methods for url func WithMethods(methods []string) option { return func(url *URL) { url.Methods = methods } } -// WithParams ... +// WithParams sets params for url func WithParams(params url.Values) option { return func(url *URL) { url.params = params } } -// WithParamsValue ... +// WithParamsValue sets params field for url func WithParamsValue(key, val string) option { return func(url *URL) { url.SetParam(key, val) } } -// WithProtocol ... +// WithProtocol sets protocol for url func WithProtocol(proto string) option { return func(url *URL) { url.Protocol = proto } } -// WithIp ... +// WithIp sets ip for url func WithIp(ip string) option { return func(url *URL) { url.Ip = ip } } -// WithPort ... +// WithPort sets port for url func WithPort(port string) option { return func(url *URL) { url.Port = port } } -// WithPath ... +// WithPath sets path for url func WithPath(path string) option { return func(url *URL) { url.Path = "/" + strings.TrimPrefix(path, "/") } } -// WithLocation ... +// WithLocation sets location for url func WithLocation(location string) option { return func(url *URL) { url.Location = location } } -// WithToken ... +// WithToken sets token for url func WithToken(token string) option { return func(url *URL) { if len(token) > 0 { @@ -182,7 +184,7 @@ func WithToken(token string) option { } } -// NewURLWithOptions ... +// NewURLWithOptions will create a new url with options func NewURLWithOptions(opts ...option) *URL { url := &URL{} for _, opt := range opts { @@ -212,7 +214,7 @@ func NewURL(urlString string, opts ...option) (URL, error) { return s, perrors.Errorf("url.QueryUnescape(%s), error{%v}", urlString, err) } - //rawUrlString = "//" + rawUrlString + // rawUrlString = "//" + rawUrlString if strings.Index(rawUrlString, "//") < 0 { t := URL{baseUrl: baseUrl{}} for _, opt := range opts { @@ -275,7 +277,7 @@ func (c URL) URLEqual(url URL) bool { return false } - //TODO :may need add interface key any value condition + // TODO :may need add interface key any value condition return isMatchCategory(url.GetParam(constant.CATEGORY_KEY, constant.DEFAULT_CATEGORY), c.GetParam(constant.CATEGORY_KEY, constant.DEFAULT_CATEGORY)) } @@ -292,23 +294,21 @@ func isMatchCategory(category1 string, category2 string) bool { } func (c URL) String() string { - var buildString string + var buf strings.Builder if len(c.Username) == 0 && len(c.Password) == 0 { - buildString = fmt.Sprintf( + buf.WriteString(fmt.Sprintf( "%s://%s:%s%s?", - c.Protocol, c.Ip, c.Port, c.Path) + c.Protocol, c.Ip, c.Port, c.Path)) } else { - buildString = fmt.Sprintf( + buf.WriteString(fmt.Sprintf( "%s://%s:%s@%s:%s%s?", - c.Protocol, c.Username, c.Password, c.Ip, c.Port, c.Path) + c.Protocol, c.Username, c.Password, c.Ip, c.Port, c.Path)) } - c.paramsLock.RLock() - buildString += c.params.Encode() - c.paramsLock.RUnlock() - return buildString + buf.WriteString(c.params.Encode()) + return buf.String() } -// Key ... +// Key gets key func (c URL) Key() string { buildString := fmt.Sprintf( "%s://%s:%s@%s:%s/?interface=%s&group=%s&version=%s", @@ -316,13 +316,13 @@ func (c URL) Key() string { return buildString } -// ServiceKey get a unique key of a service. +// ServiceKey gets a unique key of a service. func (c URL) ServiceKey() string { intf := c.GetParam(constant.INTERFACE_KEY, strings.TrimPrefix(c.Path, "/")) if intf == "" { return "" } - buf := &bytes.Buffer{} + var buf strings.Builder group := c.GetParam(constant.GROUP_KEY, "") if group != "" { buf.WriteString(group) @@ -347,7 +347,7 @@ func (c *URL) ColonSeparatedKey() string { if intf == "" { return "" } - buf := &bytes.Buffer{} + var buf strings.Builder buf.WriteString(intf) buf.WriteString(":") version := c.GetParam(constant.VERSION_KEY, "") @@ -362,44 +362,44 @@ func (c *URL) ColonSeparatedKey() string { return buf.String() } -// EncodedServiceKey ... +// EncodedServiceKey encode the service key func (c *URL) EncodedServiceKey() string { serviceKey := c.ServiceKey() return strings.Replace(serviceKey, "/", "*", 1) } -// Service ... +// Service gets service func (c URL) Service() string { service := c.GetParam(constant.INTERFACE_KEY, strings.TrimPrefix(c.Path, "/")) if service != "" { return service } else if c.SubURL != nil { service = c.GetParam(constant.INTERFACE_KEY, strings.TrimPrefix(c.Path, "/")) - if service != "" { //if url.path is "" then return suburl's path, special for registry url + if service != "" { // if url.path is "" then return suburl's path, special for registry url return service } } return "" } -// AddParam ... +// AddParam will add the key-value pair +// Not thread-safe +// think twice before using it. func (c *URL) AddParam(key string, value string) { - c.paramsLock.Lock() c.params.Add(key, value) - c.paramsLock.Unlock() } -// SetParam ... +// SetParam will put the key-value pair into url +// it's not thread safe. +// think twice before you want to use this method +// usually it should only be invoked when you want to initialized an url func (c *URL) SetParam(key string, value string) { - c.paramsLock.Lock() c.params.Set(key, value) - c.paramsLock.Unlock() } -// RangeParams ... +// RangeParams will iterate the params +// it's not thread-safe 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 @@ -407,10 +407,8 @@ func (c *URL) RangeParams(f func(key, value string) bool) { } } -// GetParam ... +// GetParam gets value by key func (c URL) GetParam(s string, d string) string { - c.paramsLock.RLock() - defer c.paramsLock.RUnlock() r := c.params.Get(s) if len(r) == 0 { r = d @@ -418,21 +416,19 @@ func (c URL) GetParam(s string, d string) string { return r } -// GetParams ... +// GetParams gets values func (c URL) GetParams() url.Values { return c.params } -// GetParamAndDecoded ... +// GetParamAndDecoded gets values and decode 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 } -// GetRawParam ... +// GetRawParam gets raw param func (c URL) GetRawParam(key string) string { switch key { case "protocol": @@ -452,25 +448,25 @@ func (c URL) GetRawParam(key string) string { } } -// GetParamBool ... -func (c URL) GetParamBool(s string, d bool) bool { - r, err := strconv.ParseBool(c.GetParam(s, "")) +// GetParamBool judge whether @key exists or not +func (c URL) GetParamBool(key string, d bool) bool { + r, err := strconv.ParseBool(c.GetParam(key, "")) if err != nil { return d } return r } -// GetParamInt ... -func (c URL) GetParamInt(s string, d int64) int64 { - r, err := strconv.Atoi(c.GetParam(s, "")) +// GetParamInt gets int value by @key +func (c URL) GetParamInt(key string, d int64) int64 { + r, err := strconv.Atoi(c.GetParam(key, "")) if r == 0 || err != nil { return d } return int64(r) } -// GetMethodParamInt ... +// GetMethodParamInt gets int method param func (c URL) GetMethodParamInt(method string, key string, d int64) int64 { r, err := strconv.Atoi(c.GetParam("methods."+method+"."+key, "")) if r == 0 || err != nil { @@ -479,7 +475,7 @@ func (c URL) GetMethodParamInt(method string, key string, d int64) int64 { return int64(r) } -// GetMethodParamInt64 ... +// GetMethodParamInt64 gets int64 method param func (c URL) GetMethodParamInt64(method string, key string, d int64) int64 { r := c.GetMethodParamInt(method, key, math.MinInt64) if r == math.MinInt64 { @@ -488,7 +484,7 @@ func (c URL) GetMethodParamInt64(method string, key string, d int64) int64 { return r } -// GetMethodParam ... +// GetMethodParam gets method param func (c URL) GetMethodParam(method string, key string, d string) string { r := c.GetParam("methods."+method+"."+key, "") if r == "" { @@ -497,23 +493,16 @@ func (c URL) GetMethodParam(method string, key string, d string) string { return r } -// GetMethodParamBool ... +// GetMethodParamBool judge whether @method param exists or not func (c URL) GetMethodParamBool(method string, key string, d bool) bool { r := c.GetParamBool("methods."+method+"."+key, d) return r } -// RemoveParams ... -func (c *URL) RemoveParams(set *gxset.HashSet) { - c.paramsLock.Lock() - defer c.paramsLock.Unlock() - for k := range set.Items { - s := k.(string) - delete(c.params, s) - } -} - -// SetParams ... +// SetParams will put all key-value pair into url. +// 1. if there already has same key, the value will be override +// 2. it's not thread safe +// 3. think twice when you want to invoke this method func (c *URL) SetParams(m url.Values) { for k := range m { c.SetParam(k, m.Get(k)) @@ -562,29 +551,35 @@ 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. - -// MergeUrl ... +// TODO configuration merge, in the future , the configuration center's config should merge too. + +// MergeUrl will merge those two url +// the result is based on serviceUrl, and the key which si only contained in referenceUrl +// will be added into result. +// for example, if serviceUrl contains params (a1->v1, b1->v2) and referenceUrl contains params(a2->v3, b1 -> v4) +// the params of result will be (a1->v1, b1->v2, a2->v3). +// You should notice that the value of b1 is v2, not v4. +// due to URL is not thread-safe, so this method is not thread-safe func MergeUrl(serviceUrl *URL, referenceUrl *URL) *URL { mergedUrl := serviceUrl.Clone() - //iterator the referenceUrl if serviceUrl not have the key ,merge in + // 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 + // loadBalance,cluster,retries strategy config methodConfigMergeFcn := mergeNormalParam(mergedUrl, referenceUrl, []string{constant.LOADBALANCE_KEY, constant.CLUSTER_KEY, constant.RETRIES_KEY, constant.TIMEOUT_KEY}) - //remote timestamp + // remote timestamp 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 + // finally execute methodConfigMergeFcn for _, method := range referenceUrl.Methods { for _, fcn := range methodConfigMergeFcn { fcn("methods." + method) @@ -594,7 +589,7 @@ func MergeUrl(serviceUrl *URL, referenceUrl *URL) *URL { return mergedUrl } -// Clone ... +// Clone will copy the url func (c *URL) Clone() *URL { newUrl := &URL{} copier.Copy(newUrl, c) @@ -606,7 +601,20 @@ func (c *URL) Clone() *URL { return newUrl } -// Copy url based on the reserved parameters' keys. +func (c *URL) CloneExceptParams(excludeParams *gxset.HashSet) *URL { + newUrl := &URL{} + copier.Copy(newUrl, c) + newUrl.params = url.Values{} + c.RangeParams(func(key, value string) bool { + if !excludeParams.Contains(key) { + newUrl.SetParam(key, value) + } + return true + }) + return newUrl +} + +// Copy url based on the reserved parameter's keys. func (c *URL) CloneWithParams(reserveParams []string) *URL { params := url.Values{} for _, reserveParam := range reserveParams { diff --git a/common/yaml/yaml.go b/common/yaml/yaml.go index 93ebb166144510236aff27a67422a6377ccb5c9f..5edda1b3c7751e8171528d121148b6c3c60fe128 100644 --- a/common/yaml/yaml.go +++ b/common/yaml/yaml.go @@ -40,7 +40,7 @@ func LoadYMLConfig(confProFile string) ([]byte, error) { return ioutil.ReadFile(confProFile) } -// unmarshalYMLConfig Load yml config byte from file , then unmarshal to object +// unmarshalYMLConfig Load yml config byte from file, then unmarshal to object func UnmarshalYMLConfig(confProFile string, out interface{}) ([]byte, error) { confFileStream, err := LoadYMLConfig(confProFile) if err != nil { diff --git a/config/base_config_test.go b/config/base_config_test.go index 4a4b2b06b985971b7a397daa52107fa812fc88e9..f36d7190c379d7d190af3fd2b2314b3b4b10c3f0 100644 --- a/config/base_config_test.go +++ b/config/base_config_test.go @@ -21,9 +21,11 @@ import ( "reflect" "testing" ) + import ( "github.com/stretchr/testify/assert" ) + import ( "github.com/apache/dubbo-go/common/config" "github.com/apache/dubbo-go/common/extension" @@ -455,7 +457,6 @@ func Test_refreshProvider(t *testing.T) { } func Test_startConfigCenter(t *testing.T) { - extension.SetConfigCenterFactory("mock", func() config_center.DynamicConfigurationFactory { return &config_center.MockDynamicConfigurationFactory{} }) @@ -473,21 +474,21 @@ func Test_startConfigCenter(t *testing.T) { } func Test_initializeStruct(t *testing.T) { - consumerConfig := &ConsumerConfig{} + testConsumerConfig := &ConsumerConfig{} tp := reflect.TypeOf(ConsumerConfig{}) v := reflect.New(tp) initializeStruct(tp, v.Elem()) - fmt.Println(reflect.ValueOf(consumerConfig).Elem().Type().String()) + fmt.Println(reflect.ValueOf(testConsumerConfig).Elem().Type().String()) fmt.Println(v.Elem().Type().String()) - reflect.ValueOf(consumerConfig).Elem().Set(v.Elem()) + reflect.ValueOf(testConsumerConfig).Elem().Set(v.Elem()) assert.Condition(t, func() (success bool) { - return consumerConfig.Registry != nil + return testConsumerConfig.Registry != nil }) assert.Condition(t, func() (success bool) { - return consumerConfig.Registries != nil + return testConsumerConfig.Registries != nil }) assert.Condition(t, func() (success bool) { - return consumerConfig.References != nil + return testConsumerConfig.References != nil }) } diff --git a/config/config_loader.go b/config/config_loader.go index b79c2e824988e2353b032d3ac1992740d0eca2b9..a4dc62ffbd0decbf83bc8b9f5ff9f0b17718277d 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -276,16 +276,10 @@ func GetApplicationConfig() *ApplicationConfig { // GetProviderConfig find the provider config // if not found, create new one -// we use double-check to reduce race condition -// In general, it will be locked 0 or 1 time. -// So you don't need to worry about the race condition func GetProviderConfig() ProviderConfig { if providerConfig == nil { logger.Warnf("providerConfig is nil! we will try to create one") - configAccessMutex.Lock() - defer configAccessMutex.Unlock() if providerConfig == nil { - logger.Warnf("creating empty provider config. You should see this log only once.") return ProviderConfig{} } } @@ -299,11 +293,7 @@ func GetProviderConfig() ProviderConfig { // So you don't need to worry about the race condition func GetConsumerConfig() ConsumerConfig { if consumerConfig == nil { - logger.Warnf("consumerConfig is nil! we will try to create one") - configAccessMutex.Lock() - defer configAccessMutex.Unlock() if consumerConfig == nil { - logger.Warnf("creating empty consumer config. You should see this log only once.") return ConsumerConfig{} } } diff --git a/config/consumer_config.go b/config/consumer_config.go index 76476511fbf74a5e973d59e560f65cab978d4527..bee9b1e3fcf6e9d95a285c8613bb9c8f4c6c858b 100644 --- a/config/consumer_config.go +++ b/config/consumer_config.go @@ -126,7 +126,7 @@ func configCenterRefreshConsumer() error { var err error if consumerConfig.ConfigCenterConfig != nil { consumerConfig.SetFatherConfig(consumerConfig) - if err := consumerConfig.startConfigCenter(); err != nil { + if err = consumerConfig.startConfigCenter(); err != nil { return perrors.Errorf("start config center error , error message is {%v}", perrors.WithStack(err)) } consumerConfig.fresh() @@ -141,6 +141,5 @@ func configCenterRefreshConsumer() error { return perrors.WithMessagef(err, "time.ParseDuration(Connect_Timeout{%#v})", consumerConfig.Connect_Timeout) } } - return nil } diff --git a/config/metadata_report_config.go b/config/metadata_report_config.go index caf7c55c28a02cdfe1afcefa7861770b81944c92..66b88d5e9acb7c7f737104c53fe3a04982b92d9b 100644 --- a/config/metadata_report_config.go +++ b/config/metadata_report_config.go @@ -104,7 +104,7 @@ func startMetadataReport(metadataType string, metadataReportConfig *MetadataRepo if url, err := metadataReportConfig.ToUrl(); err == nil { instance.GetMetadataReportInstance(url) } else { - return perrors.New("MetadataConfig is invalid!") + return perrors.Wrap(err, "Start MetadataReport failed.") } return nil diff --git a/config/service_config.go b/config/service_config.go index d233e2b8a55facd2ca62f86a7af9f5d6e7e309d5..2b1e5a1a3f1e708831f8f969706088d2db0512a5 100644 --- a/config/service_config.go +++ b/config/service_config.go @@ -170,9 +170,9 @@ func (c *ServiceConfig) Export() error { // registry the service reflect methods, err := common.ServiceMap.Register(c.InterfaceName, proto.Name, c.rpcService) if err != nil { - err := perrors.Errorf("The service %v export the protocol %v error! Error message is %v .", c.InterfaceName, proto.Name, err.Error()) - logger.Errorf(err.Error()) - return err + formatErr := perrors.Errorf("The service %v export the protocol %v error! Error message is %v .", c.InterfaceName, proto.Name, err.Error()) + logger.Errorf(formatErr.Error()) + return formatErr } port := proto.Port diff --git a/config_center/apollo/listener.go b/config_center/apollo/listener.go index fb257a4828aed077f61568685ee7823e9c215cf9..1cf65ed22ba0a1f765af66191ed19a04f81b0fe6 100644 --- a/config_center/apollo/listener.go +++ b/config_center/apollo/listener.go @@ -29,7 +29,7 @@ type apolloListener struct { listeners map[config_center.ConfigurationListener]struct{} } -// NewApolloListener ... +// NewApolloListener creates a new apolloListener func NewApolloListener() *apolloListener { return &apolloListener{ listeners: make(map[config_center.ConfigurationListener]struct{}, 0), @@ -49,7 +49,7 @@ func (a *apolloListener) OnChange(changeEvent *agollo.ChangeEvent) { } } -// AddListener ... +// AddListener adds a listener for apollo func (a *apolloListener) AddListener(l config_center.ConfigurationListener) { if _, ok := a.listeners[l]; !ok { a.listeners[l] = struct{}{} @@ -57,7 +57,7 @@ func (a *apolloListener) AddListener(l config_center.ConfigurationListener) { } } -// RemoveListener ... +// RemoveListener removes listeners of apollo func (a *apolloListener) RemoveListener(l config_center.ConfigurationListener) { delete(a.listeners, l) } diff --git a/config_center/configuration_listener.go b/config_center/configuration_listener.go index e70e4f68075c51c33f1110ef44a7b703e36fb78d..541cc09286bb83fa5b66db3745e45ad0a9df5e2f 100644 --- a/config_center/configuration_listener.go +++ b/config_center/configuration_listener.go @@ -25,12 +25,12 @@ import ( "github.com/apache/dubbo-go/remoting" ) -// ConfigurationListener ... +// ConfigurationListener for changing listener's event type ConfigurationListener interface { Process(*ConfigChangeEvent) } -// ConfigChangeEvent ... +// ConfigChangeEvent for changing listener's event type ConfigChangeEvent struct { Key string Value interface{} diff --git a/config_center/configurator.go b/config_center/configurator.go index ffa9034e05c4c3d4cc254886e2ed19576f155dec..9db4804365689d8eb357965973a2916e86383cf8 100644 --- a/config_center/configurator.go +++ b/config_center/configurator.go @@ -21,7 +21,7 @@ import ( "github.com/apache/dubbo-go/common" ) -// Configurator ... +// Configurator supports GetUrl and constructor type Configurator interface { GetUrl() *common.URL Configure(url *common.URL) diff --git a/config_center/configurator/mock.go b/config_center/configurator/mock.go index d294b9195db9cfe60056bc29ec26816f740ea396..7ec7179634cfd967cd27e85ed248e2075c387cb5 100644 --- a/config_center/configurator/mock.go +++ b/config_center/configurator/mock.go @@ -23,7 +23,7 @@ import ( "github.com/apache/dubbo-go/config_center" ) -// NewMockConfigurator ... +// NewMockConfigurator creates a new mockConfigurator func NewMockConfigurator(url *common.URL) config_center.Configurator { return &mockConfigurator{configuratorUrl: url} } @@ -32,12 +32,12 @@ type mockConfigurator struct { configuratorUrl *common.URL } -// GetUrl ... +// GetUrl gets a configuratorUrl func (c *mockConfigurator) GetUrl() *common.URL { return c.configuratorUrl } -// Configure ... +// Configure sets up param CLUSTER_KEY and cluster for url 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 index 18415bee3a28b37ffc2f3f73cc7309b685de5408..ebd3dc601b2821f3f4e1e4405720e4ebc55b607e 100644 --- a/config_center/configurator/override.go +++ b/config_center/configurator/override.go @@ -50,12 +50,12 @@ func (c *overrideConfigurator) GetUrl() *common.URL { } func (c *overrideConfigurator) Configure(url *common.URL) { - //remove configuratorUrl some param that can not be configured + // 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 + // branch for version 2.7.x apiVersion := c.configuratorUrl.GetParam(constant.CONFIG_VERSION_KEY, "") if len(apiVersion) != 0 { currentSide := url.GetParam(constant.SIDE_KEY, "") @@ -67,12 +67,12 @@ func (c *overrideConfigurator) Configure(url *common.URL) { c.configureIfMatch(url.Ip, url) } } else { - //branch for version 2.6.x and less + // branch for version 2.6.x and less c.configureDeprecated(url) } } -//translate from java, compatible rules in java +// configureIfMatch 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, "") @@ -105,8 +105,7 @@ func (c *overrideConfigurator) configureIfMatch(host string, url *common.URL) { if returnUrl { return } - configUrl := c.configuratorUrl.Clone() - configUrl.RemoveParams(conditionKeys) + configUrl := c.configuratorUrl.CloneExceptParams(conditionKeys) url.SetParams(configUrl.GetParams()) } } diff --git a/config_center/dynamic_configuration.go b/config_center/dynamic_configuration.go index 9013d7140e757520f2e8f048ce53a5ac2a13f982..540febc9d38e164afcc62538478df140b7d671c7 100644 --- a/config_center/dynamic_configuration.go +++ b/config_center/dynamic_configuration.go @@ -40,7 +40,7 @@ const ( DEFAULT_CONFIG_TIMEOUT = "10s" ) -// DynamicConfiguration ... +// DynamicConfiguration for modify listener and get properties file type DynamicConfiguration interface { Parser() parser.ConfigurationParser SetParser(parser.ConfigurationParser) @@ -71,14 +71,14 @@ type Options struct { // Option ... type Option func(*Options) -// WithGroup ... +// WithGroup assigns group to opt.Group func WithGroup(group string) Option { return func(opt *Options) { opt.Group = group } } -// WithTimeout ... +// WithTimeout assigns time to opt.Timeout func WithTimeout(time time.Duration) Option { return func(opt *Options) { opt.Timeout = time diff --git a/config_center/dynamic_configuration_factory.go b/config_center/dynamic_configuration_factory.go index 9f9b13227f6623a02b0261c46d8d1e43624005f8..46faf864443b7f8780584213b758f26395224956 100644 --- a/config_center/dynamic_configuration_factory.go +++ b/config_center/dynamic_configuration_factory.go @@ -21,7 +21,7 @@ import ( "github.com/apache/dubbo-go/common" ) -// DynamicConfigurationFactory ... +// DynamicConfigurationFactory gets the DynamicConfiguration type DynamicConfigurationFactory interface { GetDynamicConfiguration(*common.URL) (DynamicConfiguration, error) } diff --git a/config_center/mock_dynamic_config.go b/config_center/mock_dynamic_config.go index 59c788b65bce2a4773975ea1a96a314649781832..9cfb9e6078be60fbe2072e8e293143e8b111df58 100644 --- a/config_center/mock_dynamic_config.go +++ b/config_center/mock_dynamic_config.go @@ -43,7 +43,7 @@ var ( dynamicConfiguration *MockDynamicConfiguration ) -// GetDynamicConfiguration ... +// GetDynamicConfiguration returns a DynamicConfiguration func (f *MockDynamicConfigurationFactory) GetDynamicConfiguration(_ *common.URL) (DynamicConfiguration, error) { var err error once.Do(func() { @@ -99,16 +99,16 @@ type MockDynamicConfiguration struct { listener map[string]ConfigurationListener } -// AddListener ... +// AddListener adds a listener for MockDynamicConfiguration func (c *MockDynamicConfiguration) AddListener(key string, listener ConfigurationListener, _ ...Option) { c.listener[key] = listener } -// RemoveListener ... +// RemoveListener removes the listener for MockDynamicConfiguration func (c *MockDynamicConfiguration) RemoveListener(_ string, _ ConfigurationListener, _ ...Option) { } -// GetConfig ... +// GetConfig returns content of MockDynamicConfiguration func (c *MockDynamicConfiguration) GetConfig(_ string, _ ...Option) (string, error) { return c.content, nil @@ -119,17 +119,17 @@ func (c *MockDynamicConfiguration) GetConfigs(key string, opts ...Option) (strin return c.GetConfig(key, opts...) } -// Parser ... +// Parser returns a parser of MockDynamicConfiguration func (c *MockDynamicConfiguration) Parser() parser.ConfigurationParser { return c.parser } -// SetParser ... +// SetParser sets parser of MockDynamicConfiguration func (c *MockDynamicConfiguration) SetParser(p parser.ConfigurationParser) { c.parser = p } -// GetProperties ... +// GetProperties gets content of MockDynamicConfiguration func (c *MockDynamicConfiguration) GetProperties(_ string, _ ...Option) (string, error) { return c.content, nil } @@ -139,7 +139,7 @@ func (c *MockDynamicConfiguration) GetInternalProperty(key string, opts ...Optio return c.GetProperties(key, opts...) } -// GetRule ... +// GetRule gets properties of MockDynamicConfiguration func (c *MockDynamicConfiguration) GetRule(key string, opts ...Option) (string, error) { return c.GetProperties(key, opts...) } diff --git a/config_center/parser/configuration_parser.go b/config_center/parser/configuration_parser.go index f33b4ba866da69e1d23b493f42152bbb0f437878..6fbdc27d4339150bfec624f7dc5ea0f6a608d7a7 100644 --- a/config_center/parser/configuration_parser.go +++ b/config_center/parser/configuration_parser.go @@ -47,7 +47,7 @@ type ConfigurationParser interface { ParseToUrls(content string) ([]*common.URL, error) } -// DefaultConfigurationParser for support properties file in config center +// DefaultConfigurationParser for supporting properties file in config center type DefaultConfigurationParser struct{} // ConfiguratorConfig ... @@ -71,7 +71,7 @@ type ConfigItem struct { Side string `yaml:"side"` } -// Parse ... +// Parse load content func (parser *DefaultConfigurationParser) Parse(content string) (map[string]string, error) { pps, err := properties.LoadString(content) if err != nil { diff --git a/config_center/zookeeper/listener.go b/config_center/zookeeper/listener.go index 122dfaf4f268a706151de6acdaa78bb46e59f8fb..747c4be352add3f549eaf02e83da6442a8a84c6a 100644 --- a/config_center/zookeeper/listener.go +++ b/config_center/zookeeper/listener.go @@ -33,12 +33,12 @@ type CacheListener struct { rootPath string } -// NewCacheListener ... +// NewCacheListener creates a new CacheListener func NewCacheListener(rootPath string) *CacheListener { return &CacheListener{rootPath: rootPath} } -// AddListener ... +// AddListener will add a listener if loaded 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 @@ -50,7 +50,7 @@ func (l *CacheListener) AddListener(key string, listener config_center.Configura } } -// RemoveListener ... +// RemoveListener will delete a listener if loaded func (l *CacheListener) RemoveListener(key string, listener config_center.ConfigurationListener) { listeners, loaded := l.keyListeners.Load(key) if loaded { @@ -58,7 +58,7 @@ func (l *CacheListener) RemoveListener(key string, listener config_center.Config } } -// DataChange ... +// DataChange changes all listeners' event func (l *CacheListener) DataChange(event remoting.Event) bool { if event.Content == "" { //meanings new node diff --git a/filter/filter_impl/hystrix_filter.go b/filter/filter_impl/hystrix_filter.go index 9fd97b57b677c9aa8ec492151df9aace6dc78b62..4c872bed3e7fef8eca47f51422525a4918d6c1d8 100644 --- a/filter/filter_impl/hystrix_filter.go +++ b/filter/filter_impl/hystrix_filter.go @@ -124,7 +124,7 @@ func (hf *HystrixFilter) Invoke(ctx context.Context, invoker protocol.Invoker, i _, _, 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) + logger.Errorf("[Hystrix Filter]Errors occurred getting circuit for %s , will invoke without hystrix, error is: %+v", cmdName, err) return invoker.Invoke(ctx, invocation) } logger.Infof("[Hystrix Filter]Using hystrix filter: %s", cmdName) diff --git a/filter/filter_impl/token_filter_test.go b/filter/filter_impl/token_filter_test.go index d7a7f20a5d7648f6ee18fd26f041acb313dd97fe..b8b297e67267640a1c294541afdd4e062bfebb25 100644 --- a/filter/filter_impl/token_filter_test.go +++ b/filter/filter_impl/token_filter_test.go @@ -53,10 +53,10 @@ func TestTokenFilter_Invoke(t *testing.T) { func TestTokenFilter_InvokeEmptyToken(t *testing.T) { filter := GetTokenFilter() - url := common.URL{} + testUrl := common.URL{} attch := make(map[string]string, 0) attch[constant.TOKEN_KEY] = "ori_key" - result := filter.Invoke(context.Background(), protocol.NewBaseInvoker(url), invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, attch)) + result := filter.Invoke(context.Background(), protocol.NewBaseInvoker(testUrl), invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, attch)) assert.Nil(t, result.Error()) assert.Nil(t, result.Result()) } @@ -64,23 +64,23 @@ func TestTokenFilter_InvokeEmptyToken(t *testing.T) { func TestTokenFilter_InvokeEmptyAttach(t *testing.T) { filter := GetTokenFilter() - url := common.NewURLWithOptions( + testUrl := common.NewURLWithOptions( common.WithParams(url.Values{}), common.WithParamsValue(constant.TOKEN_KEY, "ori_key")) attch := make(map[string]string, 0) - result := filter.Invoke(context.Background(), protocol.NewBaseInvoker(*url), invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, attch)) + result := filter.Invoke(context.Background(), protocol.NewBaseInvoker(*testUrl), invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, attch)) assert.NotNil(t, result.Error()) } func TestTokenFilter_InvokeNotEqual(t *testing.T) { filter := GetTokenFilter() - url := common.NewURLWithOptions( + testUrl := 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(context.Background(), - protocol.NewBaseInvoker(*url), invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, attch)) + protocol.NewBaseInvoker(*testUrl), invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, attch)) assert.NotNil(t, result.Error()) } diff --git a/go.mod b/go.mod index ba3cf3e2190de476592278c13ba09c9adaaf947d..0fc3599813b1cb96a5988119d27d4596f115e386 100644 --- a/go.mod +++ b/go.mod @@ -43,8 +43,7 @@ require ( github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect github.com/zouyx/agollo v0.0.0-20191114083447-dde9fc9f35b8 - go.etcd.io/bbolt v1.3.3 // indirect - go.etcd.io/etcd v3.3.13+incompatible + go.etcd.io/bbolt v1.3.4 // indirect go.uber.org/atomic v1.4.0 go.uber.org/zap v1.10.0 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect diff --git a/go.sum b/go.sum index eb84bde1fb26d84ff5a3a3e36ebe178a63cfb4c9..a26694e75f08e37ed963831edbd7700f1f773393 100644 --- a/go.sum +++ b/go.sum @@ -509,10 +509,8 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/zouyx/agollo v0.0.0-20191114083447-dde9fc9f35b8 h1:k8TV7Gz7cpWpOw/dz71fx8cCZdWoPuckHJ/wkJl+meg= github.com/zouyx/agollo v0.0.0-20191114083447-dde9fc9f35b8/go.mod h1:S1cAa98KMFv4Sa8SbJ6ZtvOmf0VlgH0QJ1gXI0lBfBY= -go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v3.3.13+incompatible h1:jCejD5EMnlGxFvcGRyEV4VGlENZc7oPQX6o0t7n3xbw= -go.etcd.io/etcd v3.3.13+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI= +go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg= +go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= @@ -563,6 +561,8 @@ golang.org/x/sys v0.0.0-20190508220229-2d0786266e9c/go.mod h1:h1NjWce9XRLGQEsW7w 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/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= diff --git a/integrate_test.sh b/integrate_test.sh new file mode 100644 index 0000000000000000000000000000000000000000..c9c2f23b5b07f0baf96260d8092e7464d4d15659 --- /dev/null +++ b/integrate_test.sh @@ -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. + +#!/bin/bash + +set -e +set -x + +echo 'start integrate-test' + +# set root workspace +ROOT_DIR=$(pwd) +echo "integrate-test root work-space -> ${ROOT_DIR}" + +# show all travis-env +echo "travis current commit id -> ${TRAVIS_COMMIT}" +echo "travis pull request -> ${TRAVIS_PULL_REQUEST}" +echo "travis pull request branch -> ${TRAVIS_PULL_REQUEST_BRANCH}" +echo "travis pull request slug -> ${TRAVIS_PULL_REQUEST_SLUG}" +echo "travis pull request sha -> ${TRAVIS_PULL_REQUEST_SHA}" +echo "travis pull request repo slug -> ${TRAVIS_REPO_SLUG}" + + +# #start etcd registry insecure listen in [:]:2379 +# docker run -d --network host k8s.gcr.io/etcd:3.3.10 etcd +# echo "etcdv3 listen in [:]2379" + +# #start consul registry insecure listen in [:]:8500 +# docker run -d --network host consul +# echo "consul listen in [:]8500" + +# #start nacos registry insecure listen in [:]:8848 +# docker run -d --network host nacos/nacos-server:latest +# echo "ncacos listen in [:]8848" + +# default use zk as registry +#start zookeeper registry insecure listen in [:]:2181 +docker run -d --network host zookeeper +echo "zookeeper listen in [:]2181" + +# build go-server image +cd ./test/integrate/dubbo/go-server +docker build . -t ci-provider --build-arg PR_ORIGIN_REPO=${TRAVIS_PULL_REQUEST_SLUG} --build-arg PR_ORIGIN_COMMITID=${TRAVIS_PULL_REQUEST_SHA} +cd ${ROOT_DIR} +docker run -d --network host ci-provider + +# build go-client image +cd ./test/integrate/dubbo/go-client +docker build . -t ci-consumer --build-arg PR_ORIGIN_REPO=${TRAVIS_PULL_REQUEST_SLUG} --build-arg PR_ORIGIN_COMMITID=${TRAVIS_PULL_REQUEST_SHA} +cd ${ROOT_DIR} +# run provider +# check consumer status +docker run -it --network host ci-consumer diff --git a/metadata/report/delegate/delegate_report.go b/metadata/report/delegate/delegate_report.go index 4bc781a7f54a19c789dd8a0f7bd2f13bf09fc353..1ab7e4e7c32c0e987a56069c5a5e25653423466a 100644 --- a/metadata/report/delegate/delegate_report.go +++ b/metadata/report/delegate/delegate_report.go @@ -130,7 +130,7 @@ func NewMetadataReport() (*MetadataReport, error) { scheduler := gocron.NewScheduler(time.UTC) _, err := scheduler.Every(1).Day().Do( func() { - logger.Info("start to publish all metadata in metadata report %s.", url.String()) + logger.Infof("start to publish all metadata in metadata report %s.", url.String()) bmr.allMetadataReportsLock.RLock() bmr.doHandlerMetadataCollection(bmr.allMetadataReports) bmr.allMetadataReportsLock.RUnlock() diff --git a/protocol/dubbo/listener.go b/protocol/dubbo/listener.go index 1f4cc0068efb5688b545fa35b784b4fb2e923dc7..f57d89d1a716d2a6056e0e4a581926dc237934e4 100644 --- a/protocol/dubbo/listener.go +++ b/protocol/dubbo/listener.go @@ -143,7 +143,7 @@ func (h *RpcClientHandler) OnMessage(session getty.Session, pkg interface{}) { // OnCron ... func (h *RpcClientHandler) OnCron(session getty.Session) { - rpcSession, err := h.conn.getClientRpcSession(session) + clientRpcSession, err := h.conn.getClientRpcSession(session) if err != nil { logger.Errorf("client.getClientSession(session{%s}) = error{%v}", session.Stat(), perrors.WithStack(err)) @@ -151,7 +151,7 @@ func (h *RpcClientHandler) OnCron(session getty.Session) { } if h.conn.pool.rpcClient.conf.sessionTimeout.Nanoseconds() < time.Since(session.GetActive()).Nanoseconds() { logger.Warnf("session{%s} timeout{%s}, reqNum{%d}", - session.Stat(), time.Since(session.GetActive()).String(), rpcSession.reqNum) + session.Stat(), time.Since(session.GetActive()).String(), clientRpcSession.reqNum) h.conn.removeSession(session) // -> h.conn.close() -> h.conn.pool.remove(h.conn) return } diff --git a/protocol/dubbo/pool.go b/protocol/dubbo/pool.go index 918514c2676cfc69336a9f53e6d16d7f23cf7dca..f0bd09ba7c3392dd1dbe10306c7c70cc0eab8ccb 100644 --- a/protocol/dubbo/pool.go +++ b/protocol/dubbo/pool.go @@ -219,25 +219,25 @@ func (c *gettyRPCClient) updateSession(session getty.Session) { func (c *gettyRPCClient) getClientRpcSession(session getty.Session) (rpcSession, error) { var ( - err error - rpcSession rpcSession + err error + rpcClientSession rpcSession ) c.lock.RLock() defer c.lock.RUnlock() if c.sessions == nil { - return rpcSession, errClientClosed + return rpcClientSession, errClientClosed } err = errSessionNotExist for _, s := range c.sessions { if s.session == session { - rpcSession = *s + rpcClientSession = *s err = nil break } } - return rpcSession, perrors.WithStack(err) + return rpcClientSession, perrors.WithStack(err) } func (c *gettyRPCClient) isAvailable() bool { @@ -319,7 +319,8 @@ func (p *gettyRPCClientPool) getGettyRpcClient(protocol, addr string) (*gettyRPC conn, err := p.get() if err == nil && conn == nil { // create new conn - rpcClientConn, err := newGettyRPCClientConn(p, protocol, addr) + var rpcClientConn *gettyRPCClient + rpcClientConn, err = newGettyRPCClientConn(p, protocol, addr) return rpcClientConn, perrors.WithStack(err) } return conn, perrors.WithStack(err) diff --git a/protocol/invocation.go b/protocol/invocation.go index f32f2c3449ac063ecb89952bd4653312a07a3df4..eedf5f0253c2b76a3e0e1b52a00124d648351cfc 100644 --- a/protocol/invocation.go +++ b/protocol/invocation.go @@ -30,5 +30,8 @@ type Invocation interface { Reply() interface{} Attachments() map[string]string AttachmentsByKey(string, string) string + // Refer to dubbo 2.7.6. It is different from attachment. It is used in internal process. + Attributes() map[string]interface{} + AttributeByKey(string, interface{}) interface{} Invoker() Invoker } diff --git a/protocol/invocation/rpcinvocation.go b/protocol/invocation/rpcinvocation.go index b207fd0b0cc4eb7de8409a8c46c6fc9ef0baa5c7..68fe7b92042e6b4cf4a253c9ce354184f79af558 100644 --- a/protocol/invocation/rpcinvocation.go +++ b/protocol/invocation/rpcinvocation.go @@ -40,8 +40,10 @@ type RPCInvocation struct { reply interface{} callBack interface{} attachments map[string]string - invoker protocol.Invoker - lock sync.RWMutex + // Refer to dubbo 2.7.6. It is different from attachment. It is used in internal process. + attributes map[string]interface{} + invoker protocol.Invoker + lock sync.RWMutex } // NewRPCInvocation ... @@ -50,6 +52,7 @@ func NewRPCInvocation(methodName string, arguments []interface{}, attachments ma methodName: methodName, arguments: arguments, attachments: attachments, + attributes: make(map[string]interface{}, 8), } } @@ -59,6 +62,9 @@ func NewRPCInvocationWithOptions(opts ...option) *RPCInvocation { for _, opt := range opts { opt(invo) } + if invo.attributes == nil { + invo.attributes = make(map[string]interface{}) + } return invo } @@ -111,6 +117,22 @@ func (r *RPCInvocation) AttachmentsByKey(key string, defaultValue string) string return defaultValue } +// get attributes +func (r *RPCInvocation) Attributes() map[string]interface{} { + return r.attributes +} + +// get attribute by key. If it is not exist, it will return default value +func (r *RPCInvocation) AttributeByKey(key string, defaultValue interface{}) interface{} { + r.lock.RLock() + defer r.lock.RUnlock() + value, ok := r.attributes[key] + if ok { + return value + } + return defaultValue +} + // SetAttachments ... func (r *RPCInvocation) SetAttachments(key string, value string) { r.lock.Lock() @@ -121,6 +143,13 @@ func (r *RPCInvocation) SetAttachments(key string, value string) { r.attachments[key] = value } +// SetAttribute. If Attributes is nil, it will be inited. +func (r *RPCInvocation) SetAttribute(key string, value interface{}) { + r.lock.Lock() + defer r.lock.Unlock() + r.attributes[key] = value +} + // Invoker ... func (r *RPCInvocation) Invoker() protocol.Invoker { return r.invoker diff --git a/protocol/jsonrpc/http.go b/protocol/jsonrpc/http.go index ba7197dbc857c2ed7acda1a9f246a5b826e86915..70b3abd24f9451b4fa81d02eb9390823e6714470 100644 --- a/protocol/jsonrpc/http.go +++ b/protocol/jsonrpc/http.go @@ -172,7 +172,7 @@ func (c *HTTPClient) Do(addr, path string, httpHeader http.Header, body []byte) httpReq.Close = true reqBuf := bytes.NewBuffer(make([]byte, 0)) - if err := httpReq.Write(reqBuf); err != nil { + if err = httpReq.Write(reqBuf); err != nil { return nil, perrors.WithStack(err) } @@ -191,7 +191,7 @@ func (c *HTTPClient) Do(addr, path string, httpHeader http.Header, body []byte) } setNetConnTimeout(tcpConn, c.options.HTTPTimeout) - if _, err := reqBuf.WriteTo(tcpConn); err != nil { + if _, err = reqBuf.WriteTo(tcpConn); err != nil { return nil, perrors.WithStack(err) } diff --git a/protocol/jsonrpc/json.go b/protocol/jsonrpc/json.go index d1c2a858b4e4223ac32fc1160b56f6ee1862c8ce..3176e193816bf95882539374672eeed7f9cddc44 100644 --- a/protocol/jsonrpc/json.go +++ b/protocol/jsonrpc/json.go @@ -67,8 +67,8 @@ type Error struct { func (e *Error) Error() string { buf, err := json.Marshal(e) if err != nil { - msg, err := json.Marshal(err.Error()) - if err != nil { + msg, retryErr := json.Marshal(err.Error()) + if retryErr != nil { msg = []byte("jsonrpc2.Error: json.Marshal failed") } return fmt.Sprintf(`{"code":%d,"message":%s}`, -32001, string(msg)) @@ -133,7 +133,7 @@ func (c *jsonClientCodec) Write(d *CodecData) ([]byte, error) { } case reflect.Array, reflect.Struct: case reflect.Ptr: - switch k := reflect.TypeOf(param).Elem().Kind(); k { + switch ptrK := reflect.TypeOf(param).Elem().Kind(); ptrK { case reflect.Map: if reflect.TypeOf(param).Elem().Key().Kind() == reflect.String { if reflect.ValueOf(param).Elem().IsNil() { @@ -146,7 +146,7 @@ func (c *jsonClientCodec) Write(d *CodecData) ([]byte, error) { } case reflect.Array, reflect.Struct: default: - return nil, perrors.New("unsupported param type: Ptr to " + k.String()) + return nil, perrors.New("unsupported param type: Ptr to " + ptrK.String()) } default: return nil, perrors.New("unsupported param type: " + k.String()) diff --git a/protocol/jsonrpc/jsonrpc_protocol.go b/protocol/jsonrpc/jsonrpc_protocol.go index bed7099ab60a6c05c3799f993c0bb348a4b00f02..64f708652d8cb4bf2a6d53488c9fe17e64f10ad0 100644 --- a/protocol/jsonrpc/jsonrpc_protocol.go +++ b/protocol/jsonrpc/jsonrpc_protocol.go @@ -109,8 +109,8 @@ func (jp *JsonrpcProtocol) Destroy() { func (jp *JsonrpcProtocol) openServer(url common.URL) { _, ok := jp.serverMap[url.Location] if !ok { - _, ok := jp.ExporterMap().Load(strings.TrimPrefix(url.Path, "/")) - if !ok { + _, loadOk := jp.ExporterMap().Load(strings.TrimPrefix(url.Path, "/")) + if !loadOk { panic("[JsonrpcProtocol]" + url.Key() + "is not existing") } diff --git a/protocol/jsonrpc/server.go b/protocol/jsonrpc/server.go index 8600f02dad3d32d797613823de0bbe40261d2e71..fcea66632e787083823c1d06ca6c1698c45d5b23 100644 --- a/protocol/jsonrpc/server.go +++ b/protocol/jsonrpc/server.go @@ -349,9 +349,9 @@ func serveRequest(ctx context.Context, constant.PATH_KEY: path, constant.VERSION_KEY: codec.req.Version})) if err := result.Error(); err != nil { - rspStream, err := codec.Write(err.Error(), invalidRequest) - if err != nil { - return perrors.WithStack(err) + rspStream, codecErr := codec.Write(err.Error(), invalidRequest) + if codecErr != nil { + return perrors.WithStack(codecErr) } if errRsp := sendErrorResp(header, rspStream); errRsp != nil { logger.Warnf("Exporter: sendErrorResp(header:%#v, error:%v) = error:%s", diff --git a/registry/consul/listener.go b/registry/consul/listener.go index b047a4c08c9f6c809ed3dca8bd0d06ceaa576cae..5fac9ec0f9b6c08620021de9d0b92e3b94773c12 100644 --- a/registry/consul/listener.go +++ b/registry/consul/listener.go @@ -142,7 +142,6 @@ func (l *consulListener) run() { func (l *consulListener) handler(idx uint64, raw interface{}) { var ( service *consul.ServiceEntry - event *registry.ServiceEvent url common.URL ok bool err error @@ -183,7 +182,7 @@ func (l *consulListener) handler(idx uint64, raw interface{}) { } l.urls = newUrls - for _, event = range events { + for _, event := range events { l.eventCh <- event } } diff --git a/registry/directory/directory.go b/registry/directory/directory.go index d689bc6237c77fef9eb43412817bf30f6ea863c2..253dc597f9981c61574b8af97119653652d51bbc 100644 --- a/registry/directory/directory.go +++ b/registry/directory/directory.go @@ -61,7 +61,7 @@ type RegistryDirectory struct { forbidden atomic.Bool } -// NewRegistryDirectory ... +// NewRegistryDirectory will create a new RegistryDirectory func NewRegistryDirectory(url *common.URL, registry registry.Registry) (cluster.Directory, error) { if url.SubURL == nil { return nil, perrors.Errorf("url is invalid, suburl can not be nil") @@ -86,6 +86,7 @@ func (dir *RegistryDirectory) subscribe(url *common.URL) { dir.registry.Subscribe(url, dir) } +// Notify monitor changes from registry,and update the cacheServices func (dir *RegistryDirectory) Notify(event *registry.ServiceEvent) { go dir.update(event) } @@ -152,9 +153,11 @@ func (dir *RegistryDirectory) refreshInvokers(res *registry.ServiceEvent) { } func (dir *RegistryDirectory) toGroupInvokers() []protocol.Invoker { - newInvokersList := []protocol.Invoker{} + var ( + err error + newInvokersList []protocol.Invoker + ) groupInvokersMap := make(map[string][]protocol.Invoker) - groupInvokersList := []protocol.Invoker{} dir.cacheInvokersMap.Range(func(key, value interface{}) bool { newInvokersList = append(newInvokersList, value.(protocol.Invoker)) @@ -170,6 +173,7 @@ func (dir *RegistryDirectory) toGroupInvokers() []protocol.Invoker { groupInvokersMap[group] = []protocol.Invoker{invoker} } } + groupInvokersList := make([]protocol.Invoker, 0, len(groupInvokersMap)) if len(groupInvokersMap) == 1 { // len is 1 it means no group setting ,so do not need cluster again for _, invokers := range groupInvokersMap { @@ -178,9 +182,13 @@ func (dir *RegistryDirectory) toGroupInvokers() []protocol.Invoker { } else { for _, invokers := range groupInvokersMap { staticDir := directory.NewStaticDirectory(invokers) - cluster := extension.GetCluster(dir.GetUrl().SubURL.GetParam(constant.CLUSTER_KEY, constant.DEFAULT_CLUSTER)) - staticDir.BuildRouterChain(invokers) - groupInvokersList = append(groupInvokersList, cluster.Join(staticDir)) + cst := extension.GetCluster(dir.GetUrl().SubURL.GetParam(constant.CLUSTER_KEY, constant.DEFAULT_CLUSTER)) + err = staticDir.BuildRouterChain(invokers) + if err != nil { + logger.Error(err) + continue + } + groupInvokersList = append(groupInvokersList, cst.Join(staticDir)) } } @@ -244,6 +252,7 @@ func (dir *RegistryDirectory) List(invocation protocol.Invocation) []protocol.In return routerChain.Route(invokers, dir.cacheOriginUrl, invocation) } +// IsAvailable whether the directory is available func (dir *RegistryDirectory) IsAvailable() bool { if !dir.BaseDirectory.IsAvailable() { return dir.BaseDirectory.IsAvailable() @@ -258,6 +267,7 @@ func (dir *RegistryDirectory) IsAvailable() bool { return false } +// Destroy method func (dir *RegistryDirectory) Destroy() { // TODO:unregister & unsubscribe dir.BaseDirectory.Destroy(func() { @@ -297,6 +307,7 @@ func newReferenceConfigurationListener(dir *RegistryDirectory, url *common.URL) return listener } +// Process handle events and update Invokers func (l *referenceConfigurationListener) Process(event *config_center.ConfigChangeEvent) { l.BaseConfigurationListener.Process(event) l.directory.refreshInvokers(nil) @@ -322,6 +333,7 @@ func (l *consumerConfigurationListener) addNotifyListener(listener registry.Noti l.listeners = append(l.listeners, listener) } +// Process handles events from Configuration Center and update Invokers 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 1e3d611bf7c213894edbcbcedde79a93900572b4..04fae049d49bc2970668dc0ae8360f48da9d49dc 100644 --- a/registry/directory/directory_test.go +++ b/registry/directory/directory_test.go @@ -25,6 +25,7 @@ import ( ) import ( + "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" ) @@ -37,6 +38,7 @@ import ( "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/mock" "github.com/apache/dubbo-go/protocol/protocolwrapper" "github.com/apache/dubbo-go/registry" "github.com/apache/dubbo-go/remoting" @@ -173,7 +175,21 @@ Loop1: break Loop1 } } +} +func Test_toGroupInvokers(t *testing.T) { + registryDirectory, _ := normalRegistryDir() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + invoker := mock.NewMockInvoker(ctrl) + newUrl, _ := common.NewURL("dubbo://192.168.1.1:20000/com.ikurento.user.UserProvider") + invoker.EXPECT().GetUrl().Return(newUrl).AnyTimes() + + registryDirectory.cacheInvokersMap.Store("group1", invoker) + registryDirectory.cacheInvokersMap.Store("group2", invoker) + registryDirectory.cacheInvokersMap.Store("group1", invoker) + groupInvokers := registryDirectory.toGroupInvokers() + assert.Len(t, groupInvokers, 2) } func normalRegistryDir(noMockEvent ...bool) (*RegistryDirectory, *registry.MockRegistry) { diff --git a/registry/etcdv3/listener_test.go b/registry/etcdv3/listener_test.go index e691ae3cf1204ee97f130764496a7fc5bf67ac42..f27e7ce8ba5ab3515f8290b208b4823872ba48a3 100644 --- a/registry/etcdv3/listener_test.go +++ b/registry/etcdv3/listener_test.go @@ -24,9 +24,9 @@ import ( ) import ( + "github.com/coreos/etcd/embed" "github.com/dubbogo/getty" "github.com/stretchr/testify/suite" - "go.etcd.io/etcd/embed" ) import ( diff --git a/registry/kubernetes/listener_test.go b/registry/kubernetes/listener_test.go index c50b5b670a5491b9813652f7aa46bec18a35a7d7..1c9d8bdd5e0b713d61764163eff3b9fd3d5f320a 100644 --- a/registry/kubernetes/listener_test.go +++ b/registry/kubernetes/listener_test.go @@ -191,7 +191,6 @@ type KubernetesRegistryTestSuite struct { } func (s *KubernetesRegistryTestSuite) initRegistry() *kubernetesRegistry { - t := s.T() regurl, err := common.NewURL("registry://127.0.0.1:443", common.WithParamsValue(constant.ROLE_KEY, strconv.Itoa(common.PROVIDER))) @@ -204,7 +203,7 @@ func (s *KubernetesRegistryTestSuite) initRegistry() *kubernetesRegistry { out := fake.NewSimpleClientset() // mock current pod - if _, err := out.CoreV1().Pods(s.currentPod.GetNamespace()).Create(&s.currentPod); err != nil { + if _, err = out.CoreV1().Pods(s.currentPod.GetNamespace()).Create(&s.currentPod); err != nil { t.Fatal(err) } return out, nil diff --git a/registry/kubernetes/registry_test.go b/registry/kubernetes/registry_test.go index ea6d7663a9ceeab241c7a94a91f94288ab2990fc..a650b189c39b94849dee4fbf7fc292e33e87b829 100644 --- a/registry/kubernetes/registry_test.go +++ b/registry/kubernetes/registry_test.go @@ -68,9 +68,9 @@ func (s *KubernetesRegistryTestSuite) TestSubscribe() { time.Sleep(1e9) go func() { - err := r.Register(url) - if err != nil { - t.Fatal(err) + registerErr := r.Register(url) + if registerErr != nil { + t.Fatal(registerErr) } }() diff --git a/registry/nacos/registry_test.go b/registry/nacos/registry_test.go index 7475b455c0dda09da65012465711ece264bb3dd5..d0311b200b27081c60bc97b2307a54774ca977bd 100644 --- a/registry/nacos/registry_test.go +++ b/registry/nacos/registry_test.go @@ -42,7 +42,7 @@ func TestNacosRegistry_Register(t *testing.T) { urlMap.Set(constant.INTERFACE_KEY, "com.ikurento.user.UserProvider") urlMap.Set(constant.VERSION_KEY, "1.0.0") urlMap.Set(constant.CLUSTER_KEY, "mock") - url, _ := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParams(urlMap), common.WithMethods([]string{"GetUser", "AddUser"})) + testUrl, _ := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParams(urlMap), common.WithMethods([]string{"GetUser", "AddUser"})) reg, err := newNacosRegistry(®url) assert.Nil(t, err) @@ -50,7 +50,7 @@ func TestNacosRegistry_Register(t *testing.T) { t.Errorf("new nacos registry error:%s \n", err.Error()) return } - err = reg.Register(url) + err = reg.Register(testUrl) assert.Nil(t, err) if err != nil { t.Errorf("register error:%s \n", err.Error()) @@ -72,10 +72,10 @@ func TestNacosRegistry_Subscribe(t *testing.T) { urlMap.Set(constant.VERSION_KEY, "1.0.0") urlMap.Set(constant.CLUSTER_KEY, "mock") urlMap.Set(constant.NACOS_PATH_KEY, "") - url, _ := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParams(urlMap), common.WithMethods([]string{"GetUser", "AddUser"})) + testUrl, _ := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider", common.WithParams(urlMap), common.WithMethods([]string{"GetUser", "AddUser"})) reg, _ := newNacosRegistry(®url) - err := reg.Register(url) + err := reg.Register(testUrl) assert.Nil(t, err) if err != nil { t.Errorf("new nacos registry error:%s \n", err.Error()) @@ -84,7 +84,7 @@ func TestNacosRegistry_Subscribe(t *testing.T) { regurl.SetParam(constant.ROLE_KEY, strconv.Itoa(common.CONSUMER)) reg2, _ := newNacosRegistry(®url) - listener, err := reg2.(*nacosRegistry).subscribe(&url) + listener, err := reg2.(*nacosRegistry).subscribe(&testUrl) 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 aa8fbcbe7d6eca682892d4627878fe6bfc3756fe..a936db80bf2c3b46ba389142cc40686ed3df17b1 100644 --- a/registry/protocol/protocol.go +++ b/registry/protocol/protocol.go @@ -56,8 +56,8 @@ type registryProtocol struct { invokers []protocol.Invoker // Registry Map<RegistryAddress, Registry> 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 + // 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 overrideListeners *sync.Map serviceConfigurationListeners *sync.Map @@ -70,10 +70,8 @@ func init() { } func getCacheKey(url *common.URL) string { - newUrl := url.Clone() delKeys := gxset.NewSet("dynamic", "enabled") - newUrl.RemoveParams(delKeys) - return newUrl.String() + return url.CloneExceptParams(delKeys).String() } func newRegistryProtocol() *registryProtocol { @@ -103,16 +101,14 @@ func getUrlToRegistry(providerUrl *common.URL, registryUrl *common.URL) *common. // filterHideKey filter the parameters that do not need to be output in url(Starting with .) func filterHideKey(url *common.URL) *common.URL { - //be careful params maps in url is map type - cloneURL := url.Clone() + // be careful params maps in url is map type removeSet := gxset.NewSet() - for k, _ := range cloneURL.GetParams() { + for k, _ := range url.GetParams() { if strings.HasPrefix(k, ".") { removeSet.Add(k) } } - cloneURL.RemoveParams(removeSet) - return cloneURL + return url.CloneExceptParams(removeSet) } func (proto *registryProtocol) initConfigurationListeners() { @@ -138,7 +134,7 @@ func (proto *registryProtocol) Refer(url common.URL) protocol.Invoker { reg = regI.(registry.Registry) } - //new registry directory for store service url from registry + // new registry directory for store service url from registry directory, err := extension.GetDefaultRegistryDirectory(®istryUrl, reg) if err != nil { logger.Errorf("consumer service %v create registry directory error, error message is %s, and will return nil invoker!", @@ -152,7 +148,7 @@ func (proto *registryProtocol) Refer(url common.URL) protocol.Invoker { serviceUrl.String(), registryUrl.String(), err.Error()) } - //new cluster invoker + // new cluster invoker cluster := extension.GetCluster(serviceUrl.GetParam(constant.CLUSTER_KEY, constant.DEFAULT_CLUSTER)) invoker := cluster.Join(directory) @@ -217,7 +213,7 @@ func (proto *registryProtocol) reExport(invoker protocol.Invoker, newUrl *common oldExporter.(protocol.Exporter).Unexport() proto.bounds.Delete(key) proto.Export(wrappedNewInvoker) - //TODO: unregister & unsubscribe + // TODO: unregister & unsubscribe } } @@ -300,7 +296,7 @@ func isMatched(providerUrl *common.URL, consumerUrl *common.URL) bool { 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) { + // 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 || @@ -353,9 +349,9 @@ func (proto *registryProtocol) Destroy() { } func getRegistryUrl(invoker protocol.Invoker) *common.URL { - //here add * for return a new url + // here add * for return a new url url := invoker.GetUrl() - //if the protocol == registry ,set protocol the registry value in url.params + // if the protocol == registry ,set protocol the registry value in url.params if url.Protocol == constant.REGISTRY_PROTOCOL { protocol := url.GetParam(constant.REGISTRY_KEY, "") url.Protocol = protocol @@ -365,7 +361,7 @@ func getRegistryUrl(invoker protocol.Invoker) *common.URL { func getProviderUrl(invoker protocol.Invoker) *common.URL { url := invoker.GetUrl() - //be careful params maps in url is map type + // be careful params maps in url is map type return url.SubURL.Clone() } diff --git a/registry/servicediscovery/service_discovery_registry.go b/registry/servicediscovery/service_discovery_registry.go index 33d22e7339cb98552ec11c08b34c32ed444263c7..949010431f7f08cb5827fd45b799292848f6d9c6 100644 --- a/registry/servicediscovery/service_discovery_registry.go +++ b/registry/servicediscovery/service_discovery_registry.go @@ -38,6 +38,7 @@ import ( "github.com/apache/dubbo-go/metadata/service" "github.com/apache/dubbo-go/metadata/service/remote" "github.com/apache/dubbo-go/registry" + registryCommon "github.com/apache/dubbo-go/registry/common" "github.com/apache/dubbo-go/registry/servicediscovery/proxy" "github.com/apache/dubbo-go/registry/servicediscovery/synthesizer" "github.com/apache/dubbo-go/remoting" @@ -113,7 +114,11 @@ func creatServiceDiscovery(url *common.URL) (registry.ServiceDiscovery, error) { if !ok { return nil, perrors.Errorf("The service discovery with name: %s is not found", sdcName) } - return extension.GetServiceDiscovery(sdc.Protocol, sdcName) + originServiceDiscovery, err := extension.GetServiceDiscovery(sdc.Protocol, sdcName) + if err != nil { + return nil, perrors.WithMessage(err, "Create service discovery fialed") + } + return registryCommon.NewEventPublishingServiceDiscovery(originServiceDiscovery), nil } func parseServices(literalServices string) *gxset.HashSet { @@ -155,6 +160,7 @@ func (s *serviceDiscoveryRegistry) Register(url common.URL) error { return nil } ok, err := s.metaDataService.ExportURL(url) + s.metaDataService.PublishServiceDefinition(url) if err != nil { logger.Errorf("The URL[%s] registry catch error:%s!", url.String(), err.Error()) return err @@ -506,13 +512,14 @@ func (s *serviceDiscoveryRegistry) cloneExportedURLs(url common.URL, serviceInsa templateExportURLs := s.getTemplateExportedURLs(url, serviceInstance) host := serviceInstance.GetHost() for _, u := range templateExportURLs { - u.RemoveParams(removeParamSet) port := strconv.Itoa(getProtocolPort(serviceInstance, u.Protocol)) if u.Location != host || u.Port != port { u.Port = port // reset port u.Location = host // reset host } - clonedExportedURLs = append(clonedExportedURLs, u) + + cloneUrl := u.CloneExceptParams(removeParamSet) + clonedExportedURLs = append(clonedExportedURLs, *cloneUrl) } } return clonedExportedURLs diff --git a/remoting/etcdv3/client_test.go b/remoting/etcdv3/client_test.go index 895cc2954adf93b5899d0ae5daedbd35834b7ef4..e37b6383df55f1c7e7b64be62fc2eb22d1034616 100644 --- a/remoting/etcdv3/client_test.go +++ b/remoting/etcdv3/client_test.go @@ -29,11 +29,11 @@ import ( ) import ( + "github.com/coreos/etcd/embed" "github.com/coreos/etcd/mvcc/mvccpb" perrors "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" - "go.etcd.io/etcd/embed" "google.golang.org/grpc/connectivity" ) diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index bd1da547766abb12dc742234787262212e3db314..92ea76046f002cbdf6dbe754453ef8ebb4a14de2 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -87,8 +87,6 @@ func StateToString(state zk.State) string { default: return state.String() } - - return "zookeeper unknown state" } // Options ... @@ -111,12 +109,10 @@ func WithZkName(name string) Option { // ValidateZookeeperClient ... func ValidateZookeeperClient(container zkClientFacade, opts ...Option) error { - var ( - err error - ) - opions := &Options{} + var err error + options := &Options{} for _, opt := range opts { - opt(opions) + opt(options) } connected := false err = nil @@ -129,17 +125,18 @@ func ValidateZookeeperClient(container zkClientFacade, opts ...Option) error { if container.ZkClient() == nil { //in dubbo ,every registry only connect one node ,so this is []string{r.Address} - timeout, err := time.ParseDuration(url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT)) + var timeout time.Duration + timeout, err = time.ParseDuration(url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT)) if err != nil { logger.Errorf("timeout config %v is invalid ,err is %v", url.GetParam(constant.REGISTRY_TIMEOUT_KEY, constant.DEFAULT_REG_TIMEOUT), err.Error()) return perrors.WithMessagef(err, "newZookeeperClient(address:%+v)", url.Location) } zkAddresses := strings.Split(url.Location, ",") - newClient, err := newZookeeperClient(opions.zkName, zkAddresses, timeout) + newClient, err := newZookeeperClient(options.zkName, zkAddresses, timeout) if err != nil { logger.Warnf("newZookeeperClient(name{%s}, zk address{%v}, timeout{%d}) = error{%v}", - opions.zkName, url.Location, timeout.String(), err) + options.zkName, url.Location, timeout.String(), err) return perrors.WithMessagef(err, "newZookeeperClient(address:%+v)", url.Location) } container.SetZkClient(newClient) @@ -157,7 +154,7 @@ func ValidateZookeeperClient(container zkClientFacade, opts ...Option) error { } if connected { - logger.Info("Connect to zookeeper successfully, name{%s}, zk address{%v}", opions.zkName, url.Location) + logger.Info("Connect to zookeeper successfully, name{%s}, zk address{%v}", options.zkName, url.Location) container.WaitGroup().Add(1) //zk client start successful, then registry wg +1 } diff --git a/remoting/zookeeper/listener.go b/remoting/zookeeper/listener.go index 097106acf6b44d03708362d587b5faa8281edeab..f9d57ba5c2276181bb551e8b8499d850b87d041a 100644 --- a/remoting/zookeeper/listener.go +++ b/remoting/zookeeper/listener.go @@ -18,7 +18,6 @@ package zookeeper import ( - "github.com/apache/dubbo-go/common" "path" "strings" "sync" @@ -32,6 +31,7 @@ import ( ) 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/remoting" @@ -96,8 +96,6 @@ func (l *ZkEventListener) ListenServiceNodeEvent(zkPath string, listener ...remo return false } } - - return false } func (l *ZkEventListener) handleZkNodeEvent(zkPath string, children []string, listener remoting.DataListener) { diff --git a/test/integrate/dubbo/go-client/Dockerfile b/test/integrate/dubbo/go-client/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..d48df36dc72d7e75f8c2c8c91d5acbb01e39757d --- /dev/null +++ b/test/integrate/dubbo/go-client/Dockerfile @@ -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. +# + +FROM golang + +WORKDIR /go/src/github.com/apache/dubbo-go/test/integrate/dubbo/go-client + +ENV CONF_CONSUMER_FILE_PATH "client.yml" +ENV APP_LOG_CONF_FILE "log.yml" + +ARG PR_ORIGIN_REPO +ARG PR_ORIGIN_COMMITID + +ADD . /go/src/github.com/apache/dubbo-go/test/integrate/dubbo/go-client + +# update dubbo-go to current commit id +RUN test ${PR_ORIGIN_REPO} && echo "github.com/apache/dubbo-go will be replace to github.com/${PR_ORIGIN_REPO}@${PR_ORIGIN_COMMITID}" || echo 'go get github.com/apache/dubbo-go@develop' +RUN test ${PR_ORIGIN_REPO} && go mod edit -replace=github.com/apache/dubbo-go=github.com/${PR_ORIGIN_REPO}@${PR_ORIGIN_COMMITID} || go get -u github.com/apache/dubbo-go@develop + +RUN go install github.com/apache/dubbo-go/test/integrate/dubbo/go-client + +CMD go-client \ No newline at end of file diff --git a/test/integrate/dubbo/go-client/client.go b/test/integrate/dubbo/go-client/client.go new file mode 100644 index 0000000000000000000000000000000000000000..4c62674d33dba7caca72ca7552e73c4c0fdf14c9 --- /dev/null +++ b/test/integrate/dubbo/go-client/client.go @@ -0,0 +1,70 @@ +/* + * 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 ( + hessian "github.com/apache/dubbo-go-hessian2" + _ "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/filter_impl" + + _ "github.com/apache/dubbo-go/cluster/cluster_impl" + _ "github.com/apache/dubbo-go/cluster/loadbalance" + _ "github.com/apache/dubbo-go/registry/zookeeper" +) + +var ( + survivalTimeout int = 10e9 +) + +func println(format string, args ...interface{}) { + fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...) +} + +// they are necessary: +// export CONF_CONSUMER_FILE_PATH="xxx" +// export APP_LOG_CONF_FILE="xxx" +func main() { + hessian.RegisterPOJO(&User{}) + config.Load() + time.Sleep(3e9) + + println("\n\n\nstart to test dubbo") + + go func() { + select { + case <-time.After(time.Minute): + panic("provider not start after client already running 1min") + } + }() + user := &User{} + err := userProvider.GetUser(context.TODO(), []interface{}{"A001"}, user) + if err != nil { + panic(err) + } + println("response result: %v\n", user) +} diff --git a/test/integrate/dubbo/go-client/client.yml b/test/integrate/dubbo/go-client/client.yml new file mode 100644 index 0000000000000000000000000000000000000000..df44a13da38a14fa4a81b6189aa05708cf6f5599 --- /dev/null +++ b/test/integrate/dubbo/go-client/client.yml @@ -0,0 +1,61 @@ +# dubbo client yaml configure file + + +check: true +# client +request_timeout : "3s" +# connect timeout +connect_timeout : "3s" + +# application config +application: + organization : "ikurento.com" + name : "BDTService" + module : "dubbogo user-info client" + version : "0.0.1" + owner : "ZX" + environment : "dev" + +registries : + "demoZk": + protocol: "zookeeper" + timeout : "3s" + address: "127.0.0.1:2181" + username: "" + password: "" + + +references: + "UserProvider": + # å¯ä»¥æŒ‡å®šå¤šä¸ªregistry,使用逗å·éš”å¼€;ä¸æŒ‡å®šé»˜è®¤å‘所有注册ä¸å¿ƒæ³¨å†Œ + registry: "demoZk" + 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: 1024000 + session_name: "client" diff --git a/test/integrate/dubbo/go-client/go.mod b/test/integrate/dubbo/go-client/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..4708eb1f0f48c10acc254880ecb6dad3a03529f2 --- /dev/null +++ b/test/integrate/dubbo/go-client/go.mod @@ -0,0 +1,3 @@ +module github.com/apache/dubbo-go/test/integrate/dubbo/go-client + +go 1.13 diff --git a/test/integrate/dubbo/go-client/go.sum b/test/integrate/dubbo/go-client/go.sum new file mode 100644 index 0000000000000000000000000000000000000000..687fd0f337095443e2627b70a48c524fe335aba1 --- /dev/null +++ b/test/integrate/dubbo/go-client/go.sum @@ -0,0 +1,389 @@ +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/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +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/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/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/Jeffail/gabs v1.1.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= +github.com/Microsoft/go-winio v0.4.3/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/NYTimes/gziphandler v1.0.1/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/SAP/go-hdb v0.12.0/go.mod h1:etBT+FAi1t5k3K3tf5vQTnosgYmhDkRi8jEnQqCnxF0= +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/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= +github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw= +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/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 v1.4.1/go.mod h1:hzP9PQkcYFcBUgedttDeimugDNqbmGzh18QQy/vBjnw= +github.com/apache/dubbo-go-hessian2 v1.4.0/go.mod h1:VwEnsOMidkM1usya2uPfGpSLO9XUF//WQcWn3y+jFz8= +github.com/apache/dubbo-go-hessian2 v1.5.0/go.mod h1:VwEnsOMidkM1usya2uPfGpSLO9XUF//WQcWn3y+jFz8= +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/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/asaskevich/govalidator v0.0.0-20180319081651-7d2e70ef918f/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +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/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +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/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +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/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/coredns/coredns v1.1.2/go.mod h1:zASH/MVDgR6XZTbxvOnsZfffS+31vg6Ackf/wo1+AM0= +github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/creasty/defaults v1.3.0/go.mod h1:CIEEvs7oIVZm30R8VxtFJs+4k201gReYyuYHJxZc68I= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc= +github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= +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/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= +github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dubbogo/getty v1.3.3/go.mod h1:U92BDyJ6sW9Jpohr2Vlz8w2uUbIbNZ3d+6rJvFTSPp0= +github.com/dubbogo/go-zookeeper v1.0.0/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c= +github.com/dubbogo/gost v1.5.1/go.mod h1:pPTjVyoJan3aPxBPNUX0ADkXjPibLo+/Ib0/fADXSG8= +github.com/dubbogo/gost v1.5.2/go.mod h1:pPTjVyoJan3aPxBPNUX0ADkXjPibLo+/Ib0/fADXSG8= +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/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful/v3 v3.0.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +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/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +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 v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +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/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/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-resty/resty/v2 v2.1.0/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= +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/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/gocql/gocql v0.0.0-20180617115710-e06f8c1bcd78/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0= +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/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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/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/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/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +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/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +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/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= +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/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +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/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= +github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= +github.com/hashicorp/consul v1.5.3/go.mod h1:61E2GJCPEP3oq8La7sfDdWGQ66+Zbxzw5ecOdFD7xIE= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +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/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-discover v0.0.0-20190403160810-22221edb15cd/go.mod h1:ueUgD9BeIocT7QNuvxSyJyPAM9dfifBcaWmeybb67OY= +github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +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/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-plugin v0.0.0-20180331002553-e8d22c780116/go.mod h1:JSqWYsict+jzcj0+xElxyrBQRPNoiWQuddnxArJ7XHQ= +github.com/hashicorp/go-raftchunking v0.6.1/go.mod h1:cGlg3JtDy7qy6c/3Bu660Mic1JF+7lWqIwCFSb08fX0= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +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/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +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/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +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/go.mod h1:KHvg/R2/dPtaePb16oW4qIyzkMxXOL38xjRN64adsts= +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/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69/go.mod h1:/z+jUGRBlwVpUZfjute9jWaF6/HuhjuFQuL1YXzVD1Q= +github.com/hashicorp/raft v1.1.1/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= +github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/vault v0.10.3/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bAbosPMpP0= +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/go.mod h1:bEpDU35nTu0ey1EXjwNwPjI9xErAsoOCmcMb9GKvyxo= +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/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4= +github.com/jefferai/jsonx v0.0.0-20160721235117-9cc31c3135ee/go.mod h1:N0t2vlmpe8nyZB5ouIbJQPDSR+mH6oe7xHB9VZHSUzM= +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/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/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62/go.mod h1:U+RSyWxWd04xTqnuOQxnai7XGS2PrPY2cfGoDKtMHjA= +github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +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/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/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/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/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570/go.mod h1:BLt8L9ld7wVsvEWQbuLrUZnCMnUmLZ+CGDzKtclrTlE= +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/go.mod h1:TPpsiPUEh0zFL1Snz4crhMlBe60PYxRHr5oFF3rRYg0= +github.com/lib/pq v0.0.0-20180523175426-90697d60dd84/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +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/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/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +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/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +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/go.mod h1:CEkSvEpoveoYjA81m4HNeYQ0sge0LFGKSEqO3JKHllo= +github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= +github.com/oklog/run v0.0.0-20180308005104-6934b124db28/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +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/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/ory/dockertest v3.3.4+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= +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/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v0.0.0-20180527043350-9f6ff22cfff8/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +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/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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/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/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/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/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +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/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shirou/gopsutil v0.0.0-20181107111621-48177ef5f880/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +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/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/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/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +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/go.mod h1:Cw4GTlQccdRGSEf6KiMju767x0NEHE0YIVPJSaXjlsw= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +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/tevid/gohamcrest v1.1.1/go.mod h1:3UvtWlqm8j5JbwYZh80D/PVBt0mJ1eJiYgZMibh0H/k= +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/go.mod h1:QDlpd3qS71vYtakd2hmdpqhJ9nwv6mD6A30bQ1BPBFE= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/vmware/govmomi v0.18.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/zouyx/agollo v0.0.0-20191114083447-dde9fc9f35b8/go.mod h1:S1cAa98KMFv4Sa8SbJ6ZtvOmf0VlgH0QJ1gXI0lBfBY= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v3.3.13+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +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/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +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-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +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-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/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/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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +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/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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/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-20181011042414-1f849cf54d09/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/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +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/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/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/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/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20160818020120-3f83fa500528/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +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/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/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +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/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/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/client-go v8.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= +sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/test/integrate/dubbo/go-client/log.yml b/test/integrate/dubbo/go-client/log.yml new file mode 100644 index 0000000000000000000000000000000000000000..59fa4279ad85272c4c49d532beaf23b74d00f58a --- /dev/null +++ b/test/integrate/dubbo/go-client/log.yml @@ -0,0 +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: diff --git a/test/integrate/dubbo/go-client/user.go b/test/integrate/dubbo/go-client/user.go new file mode 100644 index 0000000000000000000000000000000000000000..ff4486f07975ebbb0064a8c83b71c952e6311dbb --- /dev/null +++ b/test/integrate/dubbo/go-client/user.go @@ -0,0 +1,54 @@ +/* + * 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" + "time" +) + +import ( + hessian "github.com/apache/dubbo-go-hessian2" + "github.com/apache/dubbo-go/config" +) + +var userProvider = new(UserProvider) + +func init() { + config.SetConsumerService(userProvider) + hessian.RegisterPOJO(&User{}) +} + +type User struct { + Id string + Name string + Age int32 + Time time.Time +} + +type UserProvider struct { + GetUser func(ctx context.Context, req []interface{}, rsp *User) error +} + +func (u *UserProvider) Reference() string { + return "UserProvider" +} + +func (User) JavaClassName() string { + return "com.ikurento.user.User" +} diff --git a/test/integrate/dubbo/go-client/version.go b/test/integrate/dubbo/go-client/version.go new file mode 100644 index 0000000000000000000000000000000000000000..c6138584f1ddeab3a4927774f44f9e78a8f08da7 --- /dev/null +++ b/test/integrate/dubbo/go-client/version.go @@ -0,0 +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" +) diff --git a/test/integrate/dubbo/go-server/Dockerfile b/test/integrate/dubbo/go-server/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..c2f2d63462d94df7624ac100023e8b8c24e23e11 --- /dev/null +++ b/test/integrate/dubbo/go-server/Dockerfile @@ -0,0 +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. +# + +FROM golang + +WORKDIR /go/src/github.com/apache/dubbo-go/test/integrate/dubbo/go-server + +ENV CONF_PROVIDER_FILE_PATH "server.yml" +ENV APP_LOG_CONF_FILE "log.yml" + +ARG PR_ORIGIN_REPO +ARG PR_ORIGIN_COMMITID + +ADD . /go/src/github.com/apache/dubbo-go/test/integrate/dubbo/go-server +# update dubbo-go to current commit id +RUN test ${PR_ORIGIN_REPO} && echo "github.com/apache/dubbo-go will be replace to github.com/${PR_ORIGIN_REPO}@${PR_ORIGIN_COMMITID}" || echo 'go get github.com/apache/dubbo-go@develop' +RUN test ${PR_ORIGIN_REPO} && go mod edit -replace=github.com/apache/dubbo-go=github.com/${PR_ORIGIN_REPO}@${PR_ORIGIN_COMMITID} || go get -u github.com/apache/dubbo-go@develop + +RUN go install github.com/apache/dubbo-go/test/integrate/dubbo/go-server + +CMD go-server diff --git a/test/integrate/dubbo/go-server/go.mod b/test/integrate/dubbo/go-server/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..9e1162327de374fb131c2a0b89d1be3baa578a1b --- /dev/null +++ b/test/integrate/dubbo/go-server/go.mod @@ -0,0 +1,3 @@ +module github.com/apache/dubbo-go/test/integrate/dubbo/go-server + +go 1.13 diff --git a/test/integrate/dubbo/go-server/log.yml b/test/integrate/dubbo/go-server/log.yml new file mode 100644 index 0000000000000000000000000000000000000000..59fa4279ad85272c4c49d532beaf23b74d00f58a --- /dev/null +++ b/test/integrate/dubbo/go-server/log.yml @@ -0,0 +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: diff --git a/test/integrate/dubbo/go-server/server.go b/test/integrate/dubbo/go-server/server.go new file mode 100644 index 0000000000000000000000000000000000000000..115bf0a4d78f171eb7f786808def91879ed93947 --- /dev/null +++ b/test/integrate/dubbo/go-server/server.go @@ -0,0 +1,56 @@ +/* + * 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 ( + hessian "github.com/apache/dubbo-go-hessian2" + _ "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/filter_impl" + _ "github.com/apache/dubbo-go/protocol/dubbo" + _ "github.com/apache/dubbo-go/registry/protocol" + _ "github.com/apache/dubbo-go/registry/zookeeper" +) + +var ( + stopC = make(chan struct{}) +) + +// they are necessary: +// export CONF_PROVIDER_FILE_PATH="xxx" +// export APP_LOG_CONF_FILE="xxx" +func main() { + + hessian.RegisterPOJO(&User{}) + config.Load() + + select { + case <-stopC: + // wait getty send resp to consumer + time.Sleep(3*time.Second) + return + case <-time.After(time.Minute): + panic("provider already running 1 min, but can't be call by consumer") + } +} diff --git a/test/integrate/dubbo/go-server/server.yml b/test/integrate/dubbo/go-server/server.yml new file mode 100644 index 0000000000000000000000000000000000000000..8a17297b10119c217e68b39d58a10493f6dfc7a7 --- /dev/null +++ b/test/integrate/dubbo/go-server/server.yml @@ -0,0 +1,57 @@ +# dubbo server yaml configure file + + +# application config +application: + organization : "ikurento.com" + name : "BDTService" + module : "dubbogo user-info server" + version : "0.0.1" + owner : "ZX" + environment : "dev" + +registries : + "demoZk": + protocol: "zookeeper" + timeout : "3s" + address: "127.0.0.1:2181" + +services: + "UserProvider": + # å¯ä»¥æŒ‡å®šå¤šä¸ªregistry,使用逗å·éš”å¼€;ä¸æŒ‡å®šé»˜è®¤å‘所有注册ä¸å¿ƒæ³¨å†Œ + registry: "demoZk" + protocol : "dubbo" + # 相当于dubbo.xmlä¸çš„interface + interface : "com.ikurento.user.UserProvider" + loadbalance: "random" + warmup: "100" + cluster: "failover" + methods: + - name: "GetUser" + retries: 1 + loadbalance: "random" + +protocols: + "dubbo": + name: "dubbo" + 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: 1024000 + session_name: "server" diff --git a/test/integrate/dubbo/go-server/user.go b/test/integrate/dubbo/go-server/user.go new file mode 100644 index 0000000000000000000000000000000000000000..7bff41566152940f885dec2eb256b261d04ad59a --- /dev/null +++ b/test/integrate/dubbo/go-server/user.go @@ -0,0 +1,65 @@ +/* + * 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 ( + hessian "github.com/apache/dubbo-go-hessian2" + "github.com/apache/dubbo-go/config" +) + +func init() { + config.SetProviderService(new(UserProvider)) + // ------for hessian2------ + hessian.RegisterPOJO(&User{}) +} + +type User struct { + Id string + Name string + Age int32 + Time time.Time +} + +type UserProvider struct { +} + +func (u *UserProvider) GetUser(ctx context.Context, req []interface{}) (*User, error) { + println("req:%#v", req) + rsp := User{"A001", "Alex Stocks", 18, time.Now()} + println("rsp:%#v", rsp) + close(stopC) + return &rsp, nil +} + +func (u *UserProvider) Reference() string { + return "UserProvider" +} + +func (u User) JavaClassName() string { + return "com.ikurento.user.User" +} + +func println(format string, args ...interface{}) { + fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...) +} diff --git a/test/integrate/dubbo/go-server/version.go b/test/integrate/dubbo/go-server/version.go new file mode 100644 index 0000000000000000000000000000000000000000..c6138584f1ddeab3a4927774f44f9e78a8f08da7 --- /dev/null +++ b/test/integrate/dubbo/go-server/version.go @@ -0,0 +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" +)