提交 2837221d 编写于 作者: J Jason Song

support server config separated by cluster

上级 f1b91928
package com.ctrip.framework.apollo.biz.customize; 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 com.ctrip.framework.apollo.common.customize.LoggingCustomizer;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -15,7 +15,7 @@ public class BizLoggingCustomizer extends LoggingCustomizer{ ...@@ -15,7 +15,7 @@ public class BizLoggingCustomizer extends LoggingCustomizer{
private static final String CLOGGING_SERVER_PORT_KEY = "clogging.server.port"; private static final String CLOGGING_SERVER_PORT_KEY = "clogging.server.port";
@Autowired @Autowired
private ServerConfigRepository serverConfigRepository; private ServerConfigService serverConfigService;
private String cloggingUrl; private String cloggingUrl;
private String cloggingPort; private String cloggingPort;
...@@ -23,7 +23,7 @@ public class BizLoggingCustomizer extends LoggingCustomizer{ ...@@ -23,7 +23,7 @@ public class BizLoggingCustomizer extends LoggingCustomizer{
@Override @Override
protected String cloggingUrl() { protected String cloggingUrl() {
if (cloggingUrl == null){ if (cloggingUrl == null){
cloggingUrl = serverConfigRepository.findByKey(CLOGGING_SERVER_URL_KEY).getValue(); cloggingUrl = serverConfigService.getValue(CLOGGING_SERVER_URL_KEY);
} }
return cloggingUrl; return cloggingUrl;
} }
...@@ -31,7 +31,7 @@ public class BizLoggingCustomizer extends LoggingCustomizer{ ...@@ -31,7 +31,7 @@ public class BizLoggingCustomizer extends LoggingCustomizer{
@Override @Override
protected String cloggingPort() { protected String cloggingPort() {
if (cloggingPort == null){ if (cloggingPort == null){
cloggingPort = serverConfigRepository.findByKey(CLOGGING_SERVER_PORT_KEY).getValue(); cloggingPort = serverConfigService.getValue(CLOGGING_SERVER_PORT_KEY);
} }
return cloggingPort; return cloggingPort;
} }
......
...@@ -20,6 +20,9 @@ public class ServerConfig extends BaseEntity { ...@@ -20,6 +20,9 @@ public class ServerConfig extends BaseEntity {
@Column(name = "Key", nullable = false) @Column(name = "Key", nullable = false)
private String key; private String key;
@Column(name = "Cluster", nullable = false)
private String cluster;
@Column(name = "Value", nullable = false) @Column(name = "Value", nullable = false)
private String value; private String value;
...@@ -50,6 +53,14 @@ public class ServerConfig extends BaseEntity { ...@@ -50,6 +53,14 @@ public class ServerConfig extends BaseEntity {
this.comment = comment; this.comment = comment;
} }
public String getCluster() {
return cluster;
}
public void setCluster(String cluster) {
this.cluster = cluster;
}
public String toString() { public String toString() {
return toStringHelper().add("key", key).add("value", value).add("comment", comment).toString(); return toStringHelper().add("key", key).add("value", value).add("comment", comment).toString();
} }
......
...@@ -3,8 +3,7 @@ package com.ctrip.framework.apollo.biz.eureka; ...@@ -3,8 +3,7 @@ package com.ctrip.framework.apollo.biz.eureka;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.ctrip.framework.apollo.biz.entity.ServerConfig; import com.ctrip.framework.apollo.biz.service.ServerConfigService;
import com.ctrip.framework.apollo.biz.repository.ServerConfigRepository;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean; import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
...@@ -13,7 +12,6 @@ import org.springframework.core.env.Environment; ...@@ -13,7 +12,6 @@ import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.List; import java.util.List;
import java.util.Objects;
@Component @Component
@Primary @Primary
...@@ -22,7 +20,7 @@ public class ApolloEurekaClientConfig extends EurekaClientConfigBean { ...@@ -22,7 +20,7 @@ public class ApolloEurekaClientConfig extends EurekaClientConfigBean {
private static final Splitter URL_SPLITTER = Splitter.on(",").omitEmptyStrings(); private static final Splitter URL_SPLITTER = Splitter.on(",").omitEmptyStrings();
@Autowired @Autowired
private ServerConfigRepository serverConfigRepository; private ServerConfigService serverConfigService;
@Autowired @Autowired
private Environment environment; private Environment environment;
...@@ -37,10 +35,10 @@ public class ApolloEurekaClientConfig extends EurekaClientConfigBean { ...@@ -37,10 +35,10 @@ public class ApolloEurekaClientConfig extends EurekaClientConfigBean {
} }
//Second check if it is configured in database //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())) { if (!Strings.isNullOrEmpty(eurekaUrl)) {
return URL_SPLITTER.splitToList(eurekaUrl.getValue()); return URL_SPLITTER.splitToList(eurekaUrl);
} }
......
...@@ -8,5 +8,5 @@ import org.springframework.data.repository.PagingAndSortingRepository; ...@@ -8,5 +8,5 @@ import org.springframework.data.repository.PagingAndSortingRepository;
* @author Jason Song(song_s@ctrip.com) * @author Jason Song(song_s@ctrip.com)
*/ */
public interface ServerConfigRepository extends PagingAndSortingRepository<ServerConfig, Long> { public interface ServerConfigRepository extends PagingAndSortingRepository<ServerConfig, Long> {
ServerConfig findByKey(String key); ServerConfig findTopByKeyAndCluster(String key, String cluster);
} }
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();
}
}
package com.ctrip.framework.apollo.biz; 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.DatabaseMessageSenderTest;
import com.ctrip.framework.apollo.biz.message.ReleaseMessageScannerTest;
import com.ctrip.framework.apollo.biz.repository.AppNamespaceRepositoryTest; import com.ctrip.framework.apollo.biz.repository.AppNamespaceRepositoryTest;
import com.ctrip.framework.apollo.biz.repository.AppRepositoryTest; import com.ctrip.framework.apollo.biz.repository.AppRepositoryTest;
import com.ctrip.framework.apollo.biz.service.AdminServiceTest; import com.ctrip.framework.apollo.biz.service.AdminServiceTest;
import com.ctrip.framework.apollo.biz.service.AdminServiceTransactionTest; 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.ConfigServiceTest;
import com.ctrip.framework.apollo.biz.service.PrivilegeServiceTest; 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.runner.RunWith;
import org.junit.runners.Suite; import org.junit.runners.Suite;
...@@ -20,7 +25,13 @@ import org.junit.runners.Suite.SuiteClasses; ...@@ -20,7 +25,13 @@ import org.junit.runners.Suite.SuiteClasses;
ConfigServiceTest.class, ConfigServiceTest.class,
PrivilegeServiceTest.class, PrivilegeServiceTest.class,
AdminServiceTransactionTest.class, AdminServiceTransactionTest.class,
DatabaseMessageSenderTest.class}) DatabaseMessageSenderTest.class,
ServerConfigServiceTest.class,
ApolloEurekaClientConfigTest.class,
ReleaseMessageScannerTest.class,
ClusterServiceTest.class,
ReleaseKeyGeneratorTest.class
})
public class AllTests { public class AllTests {
} }
package com.ctrip.framework.apollo.biz.eureka; package com.ctrip.framework.apollo.biz.eureka;
import com.ctrip.framework.apollo.biz.entity.ServerConfig; import com.ctrip.framework.apollo.biz.service.ServerConfigService;
import com.ctrip.framework.apollo.biz.repository.ServerConfigRepository;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
...@@ -13,7 +12,8 @@ import org.springframework.test.util.ReflectionTestUtils; ...@@ -13,7 +12,8 @@ import org.springframework.test.util.ReflectionTestUtils;
import java.util.List; 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; import static org.mockito.Mockito.when;
/** /**
...@@ -23,14 +23,14 @@ import static org.mockito.Mockito.when; ...@@ -23,14 +23,14 @@ import static org.mockito.Mockito.when;
public class ApolloEurekaClientConfigTest { public class ApolloEurekaClientConfigTest {
private ApolloEurekaClientConfig eurekaClientConfig; private ApolloEurekaClientConfig eurekaClientConfig;
@Mock @Mock
private ServerConfigRepository serverConfigRepository; private ServerConfigService serverConfigService;
@Mock @Mock
private Environment environment; private Environment environment;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
eurekaClientConfig = new ApolloEurekaClientConfig(); eurekaClientConfig = new ApolloEurekaClientConfig();
ReflectionTestUtils.setField(eurekaClientConfig, "serverConfigRepository", serverConfigRepository); ReflectionTestUtils.setField(eurekaClientConfig, "serverConfigService", serverConfigService);
ReflectionTestUtils.setField(eurekaClientConfig, "environment", environment); ReflectionTestUtils.setField(eurekaClientConfig, "environment", environment);
} }
...@@ -39,8 +39,8 @@ public class ApolloEurekaClientConfigTest { ...@@ -39,8 +39,8 @@ public class ApolloEurekaClientConfigTest {
String someEurekaUrl = "http://xxx,http://yyy"; String someEurekaUrl = "http://xxx,http://yyy";
String myZone = "xx"; String myZone = "xx";
when(serverConfigRepository.findByKey(ApolloEurekaClientConfig.EUREKA_URL_CONFIG)) when(serverConfigService.getValue(ApolloEurekaClientConfig.EUREKA_URL_CONFIG))
.thenReturn(assembleServerConfig(ApolloEurekaClientConfig.EUREKA_URL_CONFIG, someEurekaUrl)); .thenReturn(someEurekaUrl);
List<String> eurekaUrls = eurekaClientConfig.getEurekaServerServiceUrls(myZone); List<String> eurekaUrls = eurekaClientConfig.getEurekaServerServiceUrls(myZone);
String[] expected = someEurekaUrl.split(","); String[] expected = someEurekaUrl.split(",");
...@@ -59,8 +59,8 @@ public class ApolloEurekaClientConfigTest { ...@@ -59,8 +59,8 @@ public class ApolloEurekaClientConfigTest {
when(environment.getProperty(ApolloEurekaClientConfig.EUREKA_URL_CONFIG)) when(environment.getProperty(ApolloEurekaClientConfig.EUREKA_URL_CONFIG))
.thenReturn(someEurekaUrlFromSystemProperty); .thenReturn(someEurekaUrlFromSystemProperty);
when(serverConfigRepository.findByKey(ApolloEurekaClientConfig.EUREKA_URL_CONFIG)) when(serverConfigService.getValue(ApolloEurekaClientConfig.EUREKA_URL_CONFIG))
.thenReturn(assembleServerConfig(ApolloEurekaClientConfig.EUREKA_URL_CONFIG, someEurekaUrl)); .thenReturn(someEurekaUrl);
List<String> eurekaUrls = eurekaClientConfig.getEurekaServerServiceUrls(myZone); List<String> eurekaUrls = eurekaClientConfig.getEurekaServerServiceUrls(myZone);
...@@ -70,11 +70,4 @@ public class ApolloEurekaClientConfigTest { ...@@ -70,11 +70,4 @@ public class ApolloEurekaClientConfigTest {
assertTrue(eurekaUrls.contains(url)); assertTrue(eurekaUrls.contains(url));
} }
} }
private ServerConfig assembleServerConfig(String key, String value) {
ServerConfig config = new ServerConfig();
config.setKey(key);
config.setValue(value);
return config;
}
} }
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;
}
}
...@@ -58,7 +58,7 @@ public class ConfigUtil { ...@@ -58,7 +58,7 @@ public class ConfigUtil {
private void initCluster() { private void initCluster() {
//Load data center from system property //Load data center from system property
cluster = System.getProperty("apollo.cluster"); cluster = System.getProperty(ConfigConsts.APOLLO_CLUSTER_KEY);
//Use data center as cluster //Use data center as cluster
if (Strings.isNullOrEmpty(cluster)) { if (Strings.isNullOrEmpty(cluster)) {
......
...@@ -4,4 +4,5 @@ public interface ConfigConsts { ...@@ -4,4 +4,5 @@ public interface ConfigConsts {
String NAMESPACE_APPLICATION = "application"; String NAMESPACE_APPLICATION = "application";
String CLUSTER_NAME_DEFAULT = "default"; String CLUSTER_NAME_DEFAULT = "default";
String CLUSTER_NAMESPACE_SEPARATOR = "+"; String CLUSTER_NAMESPACE_SEPARATOR = "+";
String APOLLO_CLUSTER_KEY = "apollo.cluster";
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册