diff --git a/component/remote/async.go b/component/remote/async.go index fc11720..db198ba 100644 --- a/component/remote/async.go +++ b/component/remote/async.go @@ -20,6 +20,10 @@ package remote import ( "encoding/json" "fmt" + "net/url" + "path" + "time" + "github.com/zouyx/agollo/v4/component/log" "github.com/zouyx/agollo/v4/constant" "github.com/zouyx/agollo/v4/env" @@ -27,9 +31,6 @@ import ( "github.com/zouyx/agollo/v4/extension" "github.com/zouyx/agollo/v4/protocol/http" "github.com/zouyx/agollo/v4/utils" - "net/url" - "path" - "time" ) const ( @@ -78,16 +79,14 @@ func (a *asyncApolloConfig) Sync(appConfigFunc func() config.AppConfig) []*confi if len(remoteConfigs) == 0 || len(apolloConfigs) > 0 { return apolloConfigs } - - appConfig.GetNotificationsMap().UpdateAllNotifications(remoteConfigs) - - notifications := appConfig.GetNotificationsMap().GetNotifications() - n := ¬ifications - n.Range(func(key, value interface{}) bool { - apolloConfig := a.SyncWithNamespace(key.(string), appConfigFunc) - apolloConfigs = append(apolloConfigs, apolloConfig) - return true - }) + //只是拉去有变化的配置, 并更新拉取成功的namespace的notify ID + for _, notifyConfig := range remoteConfigs { + apolloConfig := a.SyncWithNamespace(notifyConfig.NamespaceName, appConfigFunc) + if apolloConfig != nil { + appConfig.GetNotificationsMap().UpdateNotify(notifyConfig.NamespaceName, notifyConfig.NotificationID) + apolloConfigs = append(apolloConfigs, apolloConfig) + } + } return apolloConfigs } diff --git a/component/remote/async_test.go b/component/remote/async_test.go index f5afe82..f5c75e4 100644 --- a/component/remote/async_test.go +++ b/component/remote/async_test.go @@ -19,6 +19,12 @@ package remote import ( "fmt" + "net/http" + "net/http/httptest" + "strings" + "testing" + "time" + . "github.com/tevid/gohamcrest" "github.com/zouyx/agollo/v4/cluster/roundrobin" "github.com/zouyx/agollo/v4/env" @@ -27,11 +33,6 @@ import ( "github.com/zouyx/agollo/v4/env/server" "github.com/zouyx/agollo/v4/extension" http2 "github.com/zouyx/agollo/v4/protocol/http" - "net/http" - "net/http/httptest" - "strings" - "testing" - "time" ) var asyncApollo *asyncApolloConfig @@ -72,6 +73,7 @@ const configAbc1ResponseStr = `{ }` const responseStr = `[{"namespaceName":"application","notificationId":%d}]` +const tworesponseStr = `[{"namespaceName":"application","notificationId":%d},{"namespaceName":"abc1","notificationId":%d}]` func onlyNormalConfigResponse(rw http.ResponseWriter, req *http.Request) { rw.WriteHeader(http.StatusOK) @@ -83,17 +85,42 @@ func onlyNormalTwoConfigResponse(rw http.ResponseWriter, req *http.Request) { fmt.Fprintf(rw, configAbc1ResponseStr) } -func onlyNormalResponse(rw http.ResponseWriter, req *http.Request) { +func serverErrorTwoConfigResponse(rw http.ResponseWriter, req *http.Request) { + rw.WriteHeader(http.StatusInternalServerError) +} + +func onlynormalresponse(rw http.ResponseWriter, req *http.Request) { result := fmt.Sprintf(responseStr, 3) fmt.Fprintf(rw, "%s", result) } +func onlynormaltworesponse(rw http.ResponseWriter, req *http.Request) { + result := fmt.Sprintf(tworesponseStr, 3, 3) + fmt.Fprintf(rw, "%s", result) +} + func initMockNotifyAndConfigServer() *httptest.Server { //clear handlerMap := make(map[string]func(http.ResponseWriter, *http.Request), 1) handlerMap["application"] = onlyNormalConfigResponse handlerMap["abc1"] = onlyNormalTwoConfigResponse - return runMockConfigServer(handlerMap, onlyNormalResponse) + return runMockConfigServer(handlerMap, onlynormalresponse) +} + +func initMockNotifyAndConfigServerWithTwo() *httptest.Server { + //clear + handlerMap := make(map[string]func(http.ResponseWriter, *http.Request), 1) + handlerMap["application"] = onlyNormalConfigResponse + handlerMap["abc1"] = onlyNormalTwoConfigResponse + return runMockConfigServer(handlerMap, onlynormaltworesponse) +} + +func initMockNotifyAndConfigServerWithTwoErrResponse() *httptest.Server { + //clear + handlerMap := make(map[string]func(http.ResponseWriter, *http.Request), 1) + handlerMap["application"] = onlyNormalConfigResponse + handlerMap["abc1"] = serverErrorTwoConfigResponse + return runMockConfigServer(handlerMap, onlynormaltworesponse) } //run mock config server @@ -146,7 +173,37 @@ func TestApolloConfig_Sync(t *testing.T) { }) //err keep nil Assert(t, apolloConfigs, NotNilVal()) + Assert(t, len(apolloConfigs), Equal(1)) + Assert(t, appConfig.GetNotificationsMap().GetNotify("application"), Equal(int64(3))) + Assert(t, appConfig.GetNotificationsMap().GetNotify("abc1"), Equal(int64(-1))) +} + +func TestApolloConfig_SyncTwoOk(t *testing.T) { + server := initMockNotifyAndConfigServerWithTwo() + appConfig := initNotifications() + appConfig.IP = server.URL + apolloConfigs := asyncApollo.Sync(func() config.AppConfig { + return *appConfig + }) + //err keep nil + Assert(t, apolloConfigs, NotNilVal()) Assert(t, len(apolloConfigs), Equal(2)) + Assert(t, appConfig.GetNotificationsMap().GetNotify("application"), Equal(int64(3))) + Assert(t, appConfig.GetNotificationsMap().GetNotify("abc1"), Equal(int64(3))) +} + +func TestApolloConfig_SyncABC1Error(t *testing.T) { + server := initMockNotifyAndConfigServerWithTwoErrResponse() + appConfig := initNotifications() + appConfig.IP = server.URL + apolloConfigs := asyncApollo.Sync(func() config.AppConfig { + return *appConfig + }) + //err keep nil + Assert(t, apolloConfigs, NotNilVal()) + Assert(t, len(apolloConfigs), Equal(1)) + Assert(t, appConfig.GetNotificationsMap().GetNotify("application"), Equal(int64(3))) + Assert(t, appConfig.GetNotificationsMap().GetNotify("abc1"), Equal(int64(-1))) } func TestToApolloConfigError(t *testing.T) { diff --git a/env/config/config.go b/env/config/config.go index 30dc1d6..cf67af6 100644 --- a/env/config/config.go +++ b/env/config/config.go @@ -157,6 +157,13 @@ func (n *notificationsMap) UpdateAllNotifications(remoteConfigs []*Notification) } } +// UpdateNotify update namespace's notification ID +func (n *notificationsMap) UpdateNotify(namespaceName string, notificationID int64) { + if namespaceName != "" { + n.setNotify(namespaceName, notificationID) + } +} + func (n *notificationsMap) setNotify(namespaceName string, notificationID int64) { n.notifications.Store(namespaceName, notificationID) } diff --git a/env/config/config_test.go b/env/config/config_test.go index 583d2f3..6db6f79 100644 --- a/env/config/config_test.go +++ b/env/config/config_test.go @@ -99,3 +99,22 @@ func TestSplitNamespaces(t *testing.T) { Assert(t, l, Equal(3)) w.Wait() } + +func TestNotificationsMap(t *testing.T) { + appConfig.Init() + ID := appConfig.GetNotificationsMap().GetNotify("application") + Assert(t, ID, Equal(int64(-1))) + + appConfig.GetNotificationsMap().UpdateNotify("application", 3) + newID := appConfig.GetNotificationsMap().GetNotify("application") + Assert(t, newID, Equal(int64(3))) + + appConfig.GetNotificationsMap().UpdateNotify("", 100) + noID := appConfig.GetNotificationsMap().GetNotify("") + Assert(t, noID, Equal(int64(0))) + + appConfig.GetNotificationsMap().UpdateNotify("noExistNS", 3) + noExistID := appConfig.GetNotificationsMap().GetNotify("noExistNs") + Assert(t, noExistID, Equal(int64(0))) + +}