From e26908a99c3c52cad9fd721bff785ea43281d810 Mon Sep 17 00:00:00 2001 From: Joe Zou <yixian.zou@gmail.com> Date: Mon, 4 Nov 2019 19:04:44 +0800 Subject: [PATCH] update apollo --- config/base_config.go | 2 +- config/base_config_test.go | 7 +- config/config_center_config.go | 10 +++ config_center/apollo/impl.go | 46 +++++------- config_center/apollo/impl_test.go | 113 ++++++++++++++++++++++++++++++ go.mod | 4 +- go.sum | 3 +- 7 files changed, 148 insertions(+), 37 deletions(-) create mode 100644 config_center/apollo/impl_test.go diff --git a/config/base_config.go b/config/base_config.go index 264eeda3c..d06a0efbd 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -47,7 +47,7 @@ type BaseConfig struct { } func (c *BaseConfig) startConfigCenter(ctx context.Context) error { - url, err := common.NewURL(ctx, c.ConfigCenterConfig.Address, common.WithProtocol(c.ConfigCenterConfig.Protocol)) + url, err := common.NewURL(ctx, c.ConfigCenterConfig.Address, common.WithProtocol(c.ConfigCenterConfig.Protocol),common.WithParams(c.ConfigCenterConfig.GetUrlMap())) if err != nil { return err } diff --git a/config/base_config_test.go b/config/base_config_test.go index 9452c9e61..08829275d 100644 --- a/config/base_config_test.go +++ b/config/base_config_test.go @@ -495,12 +495,13 @@ func Test_startApolloConfigCenter(t *testing.T) { c := &BaseConfig{ConfigCenterConfig: &ConfigCenterConfig{ Protocol: "apollo", Address: "106.12.25.204:8080", - Group: "mockDubbo", - ConfigFile: "mockDubbo.properties", + Group: "testApplication_yang", + Cluster: "dev", + ConfigFile: "mockDubbog.properties", }} err := c.startConfigCenter(context.Background()) assert.NoError(t, err) - b, v := config.GetEnvInstance().Configuration().Back().Value.(*config.InmemoryConfiguration).GetProperty("dubbo.application.organization") + b, v := config.GetEnvInstance().Configuration().Back().Value.(*config.InmemoryConfiguration).GetProperty("application.organization") assert.True(t, b) assert.Equal(t, "ikurento.com", v) } diff --git a/config/config_center_config.go b/config/config_center_config.go index ed4355895..ae9c6523a 100644 --- a/config/config_center_config.go +++ b/config/config_center_config.go @@ -19,6 +19,8 @@ package config import ( "context" + "github.com/apache/dubbo-go/common/constant" + "net/url" "time" ) @@ -50,3 +52,11 @@ func (c *ConfigCenterConfig) UnmarshalYAML(unmarshal func(interface{}) error) er } return nil } + +func (c *ConfigCenterConfig) GetUrlMap() url.Values { + urlMap := url.Values{} + urlMap.Set(constant.CONFIG_NAMESPACE_KEY, c.ConfigFile) + urlMap.Set(constant.CONFIG_GROUP_KEY, c.Group) + urlMap.Set(constant.CONFIG_CLUSTER_KEY, c.Cluster) + return urlMap +} diff --git a/config_center/apollo/impl.go b/config_center/apollo/impl.go index 57ada6f08..2a6cefc96 100644 --- a/config_center/apollo/impl.go +++ b/config_center/apollo/impl.go @@ -20,7 +20,6 @@ package apollo import ( "fmt" "github.com/go-errors/errors" - "os" "strconv" "strings" "sync" @@ -35,9 +34,6 @@ import ( ) const ( - apolloEnvKey = "env" - apolloAddrKey = "apollo.meta" - apolloClusterKey = "apollo.cluster" apolloProtocolPrefix = "http://" apolloConfigFormat = "%s.%s" ) @@ -54,24 +50,15 @@ func newApolloDynamicConfiguration(url *common.URL) (*apolloDynamicConfiguration c := &apolloDynamicConfiguration{ url: url, } - configEnv := url.GetParam(apolloEnvKey, "") configAddr := c.getAddressWithProtocolPrefix(url) - configCluster := url.GetParam(constant.CONFIG_GROUP_KEY, "") - if len(configEnv) != 0 { - os.Setenv(apolloEnvKey, configEnv) - } - - key := os.Getenv(apolloEnvKey) - if len(key) != 0 || constant.ANYHOST_VALUE == configAddr { - configAddr = key - } + configCluster := url.GetParam(constant.CONFIG_CLUSTER_KEY, "") - appId := os.Getenv("app.id") - namespace := url.GetParam(constant.CONFIG_NAMESPACE_KEY, config_center.DEFAULT_GROUP) + appId := url.GetParam(constant.CONFIG_GROUP_KEY, config_center.DEFAULT_GROUP) + namespaces := url.GetParam(constant.CONFIG_NAMESPACE_KEY, getProperties(config_center.DEFAULT_GROUP)) readyConfig := &agollo.AppConfig{ AppId: appId, Cluster: configCluster, - NamespaceName: getNamespaceName(namespace,agollo.YML), + NamespaceName: namespaces, Ip: configAddr, } @@ -127,7 +114,7 @@ func (c *apolloDynamicConfiguration) AddListener(key string, listener config_cen key = k.Group + key l, _ := c.listeners.LoadOrStore(key, NewApolloListener()) - l.(apolloListener).AddListener(listener) + l.(*apolloListener).AddListener(listener) } func (c *apolloDynamicConfiguration) RemoveListener(key string, listener config_center.ConfigurationListener, opts ...config_center.Option) { @@ -139,10 +126,14 @@ func (c *apolloDynamicConfiguration) RemoveListener(key string, listener config_ key = k.Group + key l, ok := c.listeners.Load(key) if ok { - l.(apolloListener).RemoveListener(listener) + l.(*apolloListener).RemoveListener(listener) } } +func getProperties(namespace string) string{ + return getNamespaceName(namespace,agollo.Properties) +} + func getNamespaceName(namespace string,configFileFormat agollo.ConfigFileFormat ) string{ return fmt.Sprintf(apolloConfigFormat, namespace, configFileFormat) } @@ -152,21 +143,16 @@ func (c *apolloDynamicConfiguration) GetConfig(key string, opts ...config_center for _, opt := range opts { opt(k) } - group := k.Group - if len(group) != 0 && c.url.GetParam(constant.CONFIG_GROUP_KEY, config_center.DEFAULT_GROUP) != group { - namespace := c.url.GetParam(constant.CONFIG_GROUP_KEY, config_center.DEFAULT_GROUP) - fileNamespace := getNamespaceName(namespace, agollo.Properties) - config := agollo.GetConfig(fileNamespace) - if config==nil{ - return "",errors.New(fmt.Sprintf("nothiing in namespace:%s ",fileNamespace)) - } - return config.GetContent(),nil + namespace := c.url.GetParam(constant.CONFIG_NAMESPACE_KEY, getProperties(config_center.DEFAULT_GROUP)) + config := agollo.GetConfig(namespace) + if config==nil{ + return "",errors.New(fmt.Sprintf("nothiing in namespace:%s ",namespace)) } - return agollo.GetStringValue(key, ""), nil + return config.GetContent(agollo.Properties),nil } func (c *apolloDynamicConfiguration) getAddressWithProtocolPrefix(url *common.URL) string { - address := "" + address := url.Location converted := address if len(address) != 0 { parts := strings.Split(address, ",") diff --git a/config_center/apollo/impl_test.go b/config_center/apollo/impl_test.go new file mode 100644 index 000000000..9c1c52b49 --- /dev/null +++ b/config_center/apollo/impl_test.go @@ -0,0 +1,113 @@ +/* + * 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 apollo + +import ( + "context" + "fmt" + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/config" + "github.com/apache/dubbo-go/config_center" + "github.com/apache/dubbo-go/config_center/parser" + "github.com/stretchr/testify/assert" + "net/http" + "net/http/httptest" + "strings" + "testing" +) + +const ( + mockAppId="testApplication_yang" + mockCluster="dev" + mockNamespace="mockDubbog.properties" + mockConfigRes=`{"appId":"testApplication_yang","cluster":"default","namespaceName":"mockDubbog.properties","configurations":{"registries.hangzhouzk.username":"","application.owner":"ZX","registries.shanghaizk.username":"","protocols.dubbo.ip":"127.0.0.1","protocol_conf.dubbo.getty_session_param.tcp_write_timeout":"5s","services.UserProvider.cluster":"failover","application.module":"dubbogo user-info server","services.UserProvider.interface":"com.ikurento.user.UserProvider","protocol_conf.dubbo.getty_session_param.compress_encoding":"false","registries.shanghaizk.address":"127.0.0.1:2182","protocol_conf.dubbo.session_timeout":"20s","registries.shanghaizk.timeout":"3s","protocol_conf.dubbo.getty_session_param.keep_alive_period":"120s","services.UserProvider.warmup":"100","application.version":"0.0.1","registries.hangzhouzk.protocol":"zookeeper","registries.hangzhouzk.password":"","protocols.dubbo.name":"dubbo","protocol_conf.dubbo.getty_session_param.wait_timeout":"1s","protocols.dubbo.port":"20000","application_config.owner":"demo","application_config.name":"demo","application_config.version":"0.0.1","application_config.environment":"dev","protocol_conf.dubbo.getty_session_param.session_name":"server","application.name":"BDTService","registries.hangzhouzk.timeout":"3s","protocol_conf.dubbo.getty_session_param.tcp_read_timeout":"1s","services.UserProvider.loadbalance":"random","protocol_conf.dubbo.session_number":"700","protocol_conf.dubbo.getty_session_param.max_msg_len":"1024","services.UserProvider.registry":"hangzhouzk","application_config.module":"demo","services.UserProvider.methods[0].name":"GetUser","protocol_conf.dubbo.getty_session_param.tcp_no_delay":"true","services.UserProvider.methods[0].retries":"1","protocol_conf.dubbo.getty_session_param.tcp_w_buf_size":"65536","protocol_conf.dubbo.getty_session_param.tcp_r_buf_size":"262144","registries.shanghaizk.password":"","application_config.organization":"demo","registries.shanghaizk.protocol":"zookeeper","protocol_conf.dubbo.getty_session_param.tcp_keep_alive":"true","registries.hangzhouzk.address":"127.0.0.1:2181","application.environment":"dev","services.UserProvider.protocol":"dubbo","application.organization":"ikurento.com","protocol_conf.dubbo.getty_session_param.pkg_wq_size":"512","services.UserProvider.methods[0].loadbalance":"random"},"releaseKey":"20191104105242-0f13805d89f834a4"}` + mockNotifyRes=`[{"namespaceName":"mockDubbog","notificationId":53050,"messages":{"details":{"testApplication_yang+default+mockDubbog":53050}}}]` + mockServiceConfigRes=`[{"appName":"APOLLO-CONFIGSERVICE","instanceId":"instance-300408ep:apollo-configservice:8080","homepageUrl":"http://localhost:8080"}]` + + apolloUrl ="apollo://%s" +) + +func initApollo() *httptest.Server { + handlerMap := make(map[string]func(http.ResponseWriter, *http.Request), 1) + handlerMap[mockNamespace]=configResponse + + return runMockConfigServer(handlerMap,notifyResponse) +} + +func configResponse(rw http.ResponseWriter, req *http.Request) { + result := fmt.Sprintf(mockConfigRes) + fmt.Fprintf(rw, "%s", result) +} + +func notifyResponse(rw http.ResponseWriter, req *http.Request) { + result := fmt.Sprintf(mockNotifyRes ) + fmt.Fprintf(rw, "%s", result) +} + +func serviceConfigResponse(rw http.ResponseWriter, req *http.Request) { + result := fmt.Sprintf(mockServiceConfigRes ) + fmt.Fprintf(rw, "%s", result) +} + + +//run mock config server +func runMockConfigServer(handlerMap map[string]func(http.ResponseWriter, *http.Request), + notifyHandler func(http.ResponseWriter, *http.Request)) *httptest.Server{ + uriHandlerMap := make(map[string]func(http.ResponseWriter, *http.Request), 0) + for namespace, handler := range handlerMap { + uri := fmt.Sprintf("/configs/%s/%s/%s", mockAppId, mockCluster, namespace) + uriHandlerMap[uri]=handler + } + uriHandlerMap["/notifications/v2"]=notifyHandler + uriHandlerMap["/services/config"]=serviceConfigResponse + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + uri := r.RequestURI + for path, handler := range uriHandlerMap { + if strings.HasPrefix(uri,path){ + handler(w,r) + break + } + } + })) + + return ts +} + + + +func Test_GetConfig(t *testing.T) { + c := &config.BaseConfig{ConfigCenterConfig: &config.ConfigCenterConfig{ + Protocol: "apollo", + Address: "106.12.25.204:8080", + Group: "testApplication_yang", + Cluster: "dev", + ConfigFile: "mockDubbog.properties", + }} + apollo := initApollo() + apolloUrl := strings.ReplaceAll(apollo.URL, "http", "apollo") + url, err:= common.NewURL(context.TODO(), apolloUrl,common.WithParams(c.ConfigCenterConfig.GetUrlMap())) + assert.NoError(t, err) + configuration, err := newApolloDynamicConfiguration(&url) + assert.NoError(t, err) + configs, err := configuration.GetConfig(mockNamespace, config_center.WithGroup("dubbo")) + assert.NoError(t, err) + configuration.SetParser(&parser.DefaultConfigurationParser{}) + mapContent, err := configuration.Parser().Parse(configs) + assert.NoError(t, err) + assert.Equal(t, "ikurento.com", mapContent["application.organization"]) +} diff --git a/go.mod b/go.mod index a7b0685d9..200ecfeb8 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/dubbogo/getty v1.3.1 github.com/dubbogo/gost v1.3.0 github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect - github.com/go-errors/errors v1.0.1 // indirect + github.com/go-errors/errors v1.0.1 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect github.com/golang/mock v1.3.1 github.com/google/btree v1.0.0 // indirect @@ -44,7 +44,7 @@ require ( github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 // indirect github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect - github.com/zouyx/agollo v0.0.0-20191028150957-a5bd2d53f93d + github.com/zouyx/agollo v0.0.0-20191104091136-2d89707d77fe go.etcd.io/bbolt v1.3.3 // indirect go.etcd.io/etcd v3.3.13+incompatible go.uber.org/atomic v1.4.0 diff --git a/go.sum b/go.sum index dd616f464..423381fa9 100644 --- a/go.sum +++ b/go.sum @@ -472,7 +472,8 @@ github.com/vmware/govmomi v0.18.0 h1:f7QxSmP7meCtoAmiKZogvVbLInT+CZx6Px6K5rYsJZo github.com/vmware/govmomi v0.18.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/zouyx/agollo v0.0.0-20191028150957-a5bd2d53f93d/go.mod h1:S1cAa98KMFv4Sa8SbJ6ZtvOmf0VlgH0QJ1gXI0lBfBY= +github.com/zouyx/agollo v0.0.0-20191104091136-2d89707d77fe h1:5CWYPmBOnGiSEYuyUKDGmSB1/Kjq28suo35ged1tIQI= +github.com/zouyx/agollo v0.0.0-20191104091136-2d89707d77fe/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= -- GitLab