From 2837221da86c0aa666b40e9e3aa1183b62e06c81 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Mon, 13 Jun 2016 14:55:58 +0800 Subject: [PATCH] support server config separated by cluster --- .../biz/customize/BizLoggingCustomizer.java | 8 +- .../apollo/biz/entity/ServerConfig.java | 11 ++ .../biz/eureka/ApolloEurekaClientConfig.java | 12 +- .../repository/ServerConfigRepository.java | 2 +- .../biz/service/ServerConfigService.java | 48 ++++++++ .../ctrip/framework/apollo/biz/AllTests.java | 13 +- .../eureka/ApolloEurekaClientConfigTest.java | 25 ++-- .../biz/service/ServerConfigServiceTest.java | 111 ++++++++++++++++++ .../framework/apollo/util/ConfigUtil.java | 2 +- .../framework/apollo/core/ConfigConsts.java | 1 + 10 files changed, 203 insertions(+), 30 deletions(-) create mode 100644 apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ServerConfigService.java create mode 100644 apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/service/ServerConfigServiceTest.java diff --git a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/customize/BizLoggingCustomizer.java b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/customize/BizLoggingCustomizer.java index 2143a936b..5aa1a8a6a 100644 --- a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/customize/BizLoggingCustomizer.java +++ b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/customize/BizLoggingCustomizer.java @@ -1,6 +1,6 @@ package com.ctrip.framework.apollo.biz.customize; -import com.ctrip.framework.apollo.biz.repository.ServerConfigRepository; +import com.ctrip.framework.apollo.biz.service.ServerConfigService; import com.ctrip.framework.apollo.common.customize.LoggingCustomizer; import org.springframework.beans.factory.annotation.Autowired; @@ -15,7 +15,7 @@ public class BizLoggingCustomizer extends LoggingCustomizer{ private static final String CLOGGING_SERVER_PORT_KEY = "clogging.server.port"; @Autowired - private ServerConfigRepository serverConfigRepository; + private ServerConfigService serverConfigService; private String cloggingUrl; private String cloggingPort; @@ -23,7 +23,7 @@ public class BizLoggingCustomizer extends LoggingCustomizer{ @Override protected String cloggingUrl() { if (cloggingUrl == null){ - cloggingUrl = serverConfigRepository.findByKey(CLOGGING_SERVER_URL_KEY).getValue(); + cloggingUrl = serverConfigService.getValue(CLOGGING_SERVER_URL_KEY); } return cloggingUrl; } @@ -31,7 +31,7 @@ public class BizLoggingCustomizer extends LoggingCustomizer{ @Override protected String cloggingPort() { if (cloggingPort == null){ - cloggingPort = serverConfigRepository.findByKey(CLOGGING_SERVER_PORT_KEY).getValue(); + cloggingPort = serverConfigService.getValue(CLOGGING_SERVER_PORT_KEY); } return cloggingPort; } diff --git a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/entity/ServerConfig.java b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/entity/ServerConfig.java index 1bff5bb7f..50338a5e5 100644 --- a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/entity/ServerConfig.java +++ b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/entity/ServerConfig.java @@ -20,6 +20,9 @@ public class ServerConfig extends BaseEntity { @Column(name = "Key", nullable = false) private String key; + @Column(name = "Cluster", nullable = false) + private String cluster; + @Column(name = "Value", nullable = false) private String value; @@ -50,6 +53,14 @@ public class ServerConfig extends BaseEntity { this.comment = comment; } + public String getCluster() { + return cluster; + } + + public void setCluster(String cluster) { + this.cluster = cluster; + } + public String toString() { return toStringHelper().add("key", key).add("value", value).add("comment", comment).toString(); } diff --git a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/eureka/ApolloEurekaClientConfig.java b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/eureka/ApolloEurekaClientConfig.java index 426292e80..006a48fa2 100644 --- a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/eureka/ApolloEurekaClientConfig.java +++ b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/eureka/ApolloEurekaClientConfig.java @@ -3,8 +3,7 @@ package com.ctrip.framework.apollo.biz.eureka; import com.google.common.base.Splitter; import com.google.common.base.Strings; -import com.ctrip.framework.apollo.biz.entity.ServerConfig; -import com.ctrip.framework.apollo.biz.repository.ServerConfigRepository; +import com.ctrip.framework.apollo.biz.service.ServerConfigService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean; @@ -13,7 +12,6 @@ import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; import java.util.List; -import java.util.Objects; @Component @Primary @@ -22,7 +20,7 @@ public class ApolloEurekaClientConfig extends EurekaClientConfigBean { private static final Splitter URL_SPLITTER = Splitter.on(",").omitEmptyStrings(); @Autowired - private ServerConfigRepository serverConfigRepository; + private ServerConfigService serverConfigService; @Autowired private Environment environment; @@ -37,10 +35,10 @@ public class ApolloEurekaClientConfig extends EurekaClientConfigBean { } //Second check if it is configured in database - ServerConfig eurekaUrl = serverConfigRepository.findByKey(EUREKA_URL_CONFIG); + String eurekaUrl = serverConfigService.getValue(EUREKA_URL_CONFIG); - if (!Objects.isNull(eurekaUrl) && !Strings.isNullOrEmpty(eurekaUrl.getValue())) { - return URL_SPLITTER.splitToList(eurekaUrl.getValue()); + if (!Strings.isNullOrEmpty(eurekaUrl)) { + return URL_SPLITTER.splitToList(eurekaUrl); } diff --git a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/ServerConfigRepository.java b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/ServerConfigRepository.java index c42815ed2..ceef2cc31 100644 --- a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/ServerConfigRepository.java +++ b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/repository/ServerConfigRepository.java @@ -8,5 +8,5 @@ import org.springframework.data.repository.PagingAndSortingRepository; * @author Jason Song(song_s@ctrip.com) */ public interface ServerConfigRepository extends PagingAndSortingRepository { - ServerConfig findByKey(String key); + ServerConfig findTopByKeyAndCluster(String key, String cluster); } diff --git a/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ServerConfigService.java b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ServerConfigService.java new file mode 100644 index 000000000..e4c2592b9 --- /dev/null +++ b/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/ServerConfigService.java @@ -0,0 +1,48 @@ +package com.ctrip.framework.apollo.biz.service; + +import com.google.common.base.Strings; + +import com.ctrip.framework.apollo.biz.entity.ServerConfig; +import com.ctrip.framework.apollo.biz.repository.ServerConfigRepository; +import com.ctrip.framework.apollo.core.ConfigConsts; +import com.ctrip.framework.foundation.Foundation; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @author Jason Song(song_s@ctrip.com) + */ +@Service +public class ServerConfigService { + @Autowired + private ServerConfigRepository serverConfigRepository; + + public String getValue(String key) { + ServerConfig serverConfig = null; + + //1. Load from cluster config + if (!Strings.isNullOrEmpty(System.getProperty(ConfigConsts.APOLLO_CLUSTER_KEY))) { + serverConfig = + serverConfigRepository.findTopByKeyAndCluster(key, System.getProperty(ConfigConsts.APOLLO_CLUSTER_KEY)); + } + + //2. Fall back to data center config + if (serverConfig == null && !Strings.isNullOrEmpty(getDataCenter())) { + serverConfig = serverConfigRepository.findTopByKeyAndCluster(key, getDataCenter()); + } + + //3. Fall back to default cluster config + if (serverConfig == null) { + serverConfig = + serverConfigRepository.findTopByKeyAndCluster(key, ConfigConsts.CLUSTER_NAME_DEFAULT); + } + + return serverConfig == null ? null : serverConfig.getValue(); + } + + String getDataCenter() { + return Foundation.server().getDataCenter(); + } + +} diff --git a/apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/AllTests.java b/apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/AllTests.java index e72d5c48c..ca91415b8 100644 --- a/apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/AllTests.java +++ b/apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/AllTests.java @@ -1,12 +1,17 @@ package com.ctrip.framework.apollo.biz; +import com.ctrip.framework.apollo.biz.eureka.ApolloEurekaClientConfigTest; import com.ctrip.framework.apollo.biz.message.DatabaseMessageSenderTest; +import com.ctrip.framework.apollo.biz.message.ReleaseMessageScannerTest; import com.ctrip.framework.apollo.biz.repository.AppNamespaceRepositoryTest; import com.ctrip.framework.apollo.biz.repository.AppRepositoryTest; import com.ctrip.framework.apollo.biz.service.AdminServiceTest; import com.ctrip.framework.apollo.biz.service.AdminServiceTransactionTest; +import com.ctrip.framework.apollo.biz.service.ClusterServiceTest; import com.ctrip.framework.apollo.biz.service.ConfigServiceTest; import com.ctrip.framework.apollo.biz.service.PrivilegeServiceTest; +import com.ctrip.framework.apollo.biz.service.ServerConfigServiceTest; +import com.ctrip.framework.apollo.biz.utils.ReleaseKeyGeneratorTest; import org.junit.runner.RunWith; import org.junit.runners.Suite; @@ -20,7 +25,13 @@ import org.junit.runners.Suite.SuiteClasses; ConfigServiceTest.class, PrivilegeServiceTest.class, AdminServiceTransactionTest.class, - DatabaseMessageSenderTest.class}) + DatabaseMessageSenderTest.class, + ServerConfigServiceTest.class, + ApolloEurekaClientConfigTest.class, + ReleaseMessageScannerTest.class, + ClusterServiceTest.class, + ReleaseKeyGeneratorTest.class +}) public class AllTests { } diff --git a/apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/eureka/ApolloEurekaClientConfigTest.java b/apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/eureka/ApolloEurekaClientConfigTest.java index 625d9d824..ba730cb37 100644 --- a/apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/eureka/ApolloEurekaClientConfigTest.java +++ b/apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/eureka/ApolloEurekaClientConfigTest.java @@ -1,7 +1,6 @@ package com.ctrip.framework.apollo.biz.eureka; -import com.ctrip.framework.apollo.biz.entity.ServerConfig; -import com.ctrip.framework.apollo.biz.repository.ServerConfigRepository; +import com.ctrip.framework.apollo.biz.service.ServerConfigService; import org.junit.Before; import org.junit.Test; @@ -13,7 +12,8 @@ import org.springframework.test.util.ReflectionTestUtils; import java.util.List; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; /** @@ -23,14 +23,14 @@ import static org.mockito.Mockito.when; public class ApolloEurekaClientConfigTest { private ApolloEurekaClientConfig eurekaClientConfig; @Mock - private ServerConfigRepository serverConfigRepository; + private ServerConfigService serverConfigService; @Mock private Environment environment; @Before public void setUp() throws Exception { eurekaClientConfig = new ApolloEurekaClientConfig(); - ReflectionTestUtils.setField(eurekaClientConfig, "serverConfigRepository", serverConfigRepository); + ReflectionTestUtils.setField(eurekaClientConfig, "serverConfigService", serverConfigService); ReflectionTestUtils.setField(eurekaClientConfig, "environment", environment); } @@ -39,8 +39,8 @@ public class ApolloEurekaClientConfigTest { String someEurekaUrl = "http://xxx,http://yyy"; String myZone = "xx"; - when(serverConfigRepository.findByKey(ApolloEurekaClientConfig.EUREKA_URL_CONFIG)) - .thenReturn(assembleServerConfig(ApolloEurekaClientConfig.EUREKA_URL_CONFIG, someEurekaUrl)); + when(serverConfigService.getValue(ApolloEurekaClientConfig.EUREKA_URL_CONFIG)) + .thenReturn(someEurekaUrl); List eurekaUrls = eurekaClientConfig.getEurekaServerServiceUrls(myZone); String[] expected = someEurekaUrl.split(","); @@ -59,8 +59,8 @@ public class ApolloEurekaClientConfigTest { when(environment.getProperty(ApolloEurekaClientConfig.EUREKA_URL_CONFIG)) .thenReturn(someEurekaUrlFromSystemProperty); - when(serverConfigRepository.findByKey(ApolloEurekaClientConfig.EUREKA_URL_CONFIG)) - .thenReturn(assembleServerConfig(ApolloEurekaClientConfig.EUREKA_URL_CONFIG, someEurekaUrl)); + when(serverConfigService.getValue(ApolloEurekaClientConfig.EUREKA_URL_CONFIG)) + .thenReturn(someEurekaUrl); List eurekaUrls = eurekaClientConfig.getEurekaServerServiceUrls(myZone); @@ -70,11 +70,4 @@ public class ApolloEurekaClientConfigTest { assertTrue(eurekaUrls.contains(url)); } } - - private ServerConfig assembleServerConfig(String key, String value) { - ServerConfig config = new ServerConfig(); - config.setKey(key); - config.setValue(value); - return config; - } } diff --git a/apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/service/ServerConfigServiceTest.java b/apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/service/ServerConfigServiceTest.java new file mode 100644 index 000000000..7a5b83628 --- /dev/null +++ b/apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/service/ServerConfigServiceTest.java @@ -0,0 +1,111 @@ +package com.ctrip.framework.apollo.biz.service; + +import com.ctrip.framework.apollo.biz.entity.ServerConfig; +import com.ctrip.framework.apollo.biz.repository.ServerConfigRepository; +import com.ctrip.framework.apollo.core.ConfigConsts; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +/** + * @author Jason Song(song_s@ctrip.com) + */ +@RunWith(MockitoJUnitRunner.class) +public class ServerConfigServiceTest { + private ServerConfigService serverConfigService; + @Mock + private ServerConfigRepository serverConfigRepository; + private String someCluster; + private String someDC; + private String someKey; + private String someClusterValue; + private String someDCValue; + private String defaultClusterValue; + + @Before + public void setUp() throws Exception { + serverConfigService = spy(new ServerConfigService()); + ReflectionTestUtils.setField(serverConfigService, "serverConfigRepository", serverConfigRepository); + + someCluster = "someCluster"; + someDC = "someDC"; + someKey = "someKey"; + someClusterValue = "someClusterValue"; + someDCValue = "someDCValue"; + defaultClusterValue = "defaultClusterValue"; + + when(serverConfigRepository.findTopByKeyAndCluster(someKey, someCluster)) + .thenReturn(assembleServerConfig(someKey, someClusterValue)); + when(serverConfigRepository.findTopByKeyAndCluster(someKey, someDC)) + .thenReturn(assembleServerConfig(someKey, someDCValue)); + when(serverConfigRepository.findTopByKeyAndCluster(someKey, ConfigConsts.CLUSTER_NAME_DEFAULT)) + .thenReturn(assembleServerConfig(someKey, defaultClusterValue)); + } + + @After + public void tearDown() throws Exception { + System.clearProperty(ConfigConsts.APOLLO_CLUSTER_KEY); + } + + @Test + public void testGetValueWithNoCluster() throws Exception { + when(serverConfigService.getDataCenter()).thenReturn(null); + + assertEquals(defaultClusterValue, serverConfigService.getValue(someKey)); + } + + @Test + public void testGetValueWithCluster() throws Exception { + System.setProperty(ConfigConsts.APOLLO_CLUSTER_KEY, someCluster); + + assertEquals(someClusterValue, serverConfigService.getValue(someKey)); + } + + @Test + public void testGetValueWithDataCenter() throws Exception { + when(serverConfigService.getDataCenter()).thenReturn(someDC); + + assertEquals(someDCValue, serverConfigService.getValue(someKey)); + } + + @Test + public void testGetValueWithKeyNotExists() throws Exception { + String someKeyNotExists = "someKeyNotExists"; + System.setProperty(ConfigConsts.APOLLO_CLUSTER_KEY, someCluster); + when(serverConfigService.getDataCenter()).thenReturn(someDC); + + assertNull(serverConfigService.getValue(someKeyNotExists)); + } + + @Test + public void testGetValueWithClusterNotExists() throws Exception { + String someClusterNotExists = "someClusterNotExists"; + System.setProperty(ConfigConsts.APOLLO_CLUSTER_KEY, someClusterNotExists); + + assertEquals(defaultClusterValue, serverConfigService.getValue(someKey)); + } + + @Test + public void testGetValueWithDCNotExists() throws Exception { + String someDCNotExists = "someDCNotExists"; + when(serverConfigService.getDataCenter()).thenReturn(someDCNotExists); + + assertEquals(defaultClusterValue, serverConfigService.getValue(someKey)); + } + + private ServerConfig assembleServerConfig(String key, String value) { + ServerConfig serverConfig = new ServerConfig(); + serverConfig.setKey(key); + serverConfig.setValue(value); + return serverConfig; + } +} diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/util/ConfigUtil.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/util/ConfigUtil.java index 3e6f4121f..cfef4f4e6 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/util/ConfigUtil.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/util/ConfigUtil.java @@ -58,7 +58,7 @@ public class ConfigUtil { private void initCluster() { //Load data center from system property - cluster = System.getProperty("apollo.cluster"); + cluster = System.getProperty(ConfigConsts.APOLLO_CLUSTER_KEY); //Use data center as cluster if (Strings.isNullOrEmpty(cluster)) { diff --git a/apollo-core/src/main/java/com/ctrip/framework/apollo/core/ConfigConsts.java b/apollo-core/src/main/java/com/ctrip/framework/apollo/core/ConfigConsts.java index 13cb07dd6..e0c4a8cd5 100644 --- a/apollo-core/src/main/java/com/ctrip/framework/apollo/core/ConfigConsts.java +++ b/apollo-core/src/main/java/com/ctrip/framework/apollo/core/ConfigConsts.java @@ -4,4 +4,5 @@ public interface ConfigConsts { String NAMESPACE_APPLICATION = "application"; String CLUSTER_NAME_DEFAULT = "default"; String CLUSTER_NAMESPACE_SEPARATOR = "+"; + String APOLLO_CLUSTER_KEY = "apollo.cluster"; } -- GitLab