Commit 6860f0a2 authored by Jason Song's avatar Jason Song Committed by GitHub

Merge pull request #1275 from nobodyiam/configurable-apollo-meta-config-service

support passing apollo.meta and apollo.configService via system property, etc
parents 612f1967 87b8de4b
package com.ctrip.framework.apollo.internals;
import com.ctrip.framework.apollo.core.ServiceNameConsts;
import com.ctrip.framework.foundation.Foundation;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
......@@ -51,10 +53,57 @@ public class ConfigServiceLocator {
m_configUtil = ApolloInjector.getInstance(ConfigUtil.class);
this.m_executorService = Executors.newScheduledThreadPool(1,
ApolloThreadFactory.create("ConfigServiceLocator", true));
initConfigServices();
}
private void initConfigServices() {
// get from run time configurations
List<ServiceDTO> customizedConfigServices = getCustomizedConfigService();
if (customizedConfigServices != null) {
setConfigServices(customizedConfigServices);
return;
}
// update from meta service
this.tryUpdateConfigServices();
this.schedulePeriodicRefresh();
}
private List<ServiceDTO> getCustomizedConfigService() {
// 1. Get from System Property
String configServices = System.getProperty("apollo.configService");
if (Strings.isNullOrEmpty(configServices)) {
// 2. Get from OS environment variable
configServices = System.getenv("APOLLO.CONFIGSERVICE");
}
if (Strings.isNullOrEmpty(configServices)) {
// 3. Get from server.properties
configServices = Foundation.server().getProperty("apollo.configService", null);
}
if (Strings.isNullOrEmpty(configServices)) {
return null;
}
logger.warn("Located config services from apollo.configService configuration: {}, will not refresh config services from remote meta service!", configServices);
// mock service dto list
String[] configServiceUrls = configServices.split(",");
List<ServiceDTO> serviceDTOS = Lists.newArrayList();
for (String configServiceUrl : configServiceUrls) {
configServiceUrl = configServiceUrl.trim();
ServiceDTO serviceDTO = new ServiceDTO();
serviceDTO.setHomepageUrl(configServiceUrl);
serviceDTO.setAppName(ServiceNameConsts.APOLLO_CONFIGSERVICE);
serviceDTO.setInstanceId(configServiceUrl);
serviceDTOS.add(serviceDTO);
}
return serviceDTOS;
}
/**
* Get the config service info from remote meta server.
*
......@@ -109,8 +158,7 @@ public class ConfigServiceLocator {
logConfigService("Empty response!");
continue;
}
m_configServices.set(services);
logConfigServices(services);
setConfigServices(services);
return;
} catch (Throwable ex) {
Tracer.logEvent("ApolloConfigException", ExceptionUtil.getDetailMessage(ex));
......@@ -131,6 +179,11 @@ public class ConfigServiceLocator {
String.format("Get config services failed from %s", url), exception);
}
private void setConfigServices(List<ServiceDTO> services) {
m_configServices.set(services);
logConfigServices(services);
}
private String assembleMetaServiceUrl() {
String domainName = m_configUtil.getMetaServerDomainName();
String appId = m_configUtil.getAppId();
......
......@@ -221,7 +221,11 @@ public class ConfigUtil {
// 1. Get from System Property
String cacheRoot = System.getProperty("apollo.cacheDir");
if (Strings.isNullOrEmpty(cacheRoot)) {
// 2. Get from server.properties
// 2. Get from OS environment variable
cacheRoot = System.getenv("APOLLO.CACHEDIR");
}
if (Strings.isNullOrEmpty(cacheRoot)) {
// 3. Get from server.properties
cacheRoot = Foundation.server().getProperty("apollo.cacheDir", null);
}
......
package com.ctrip.framework.apollo.internals;
import static org.junit.Assert.assertEquals;
import com.ctrip.framework.apollo.core.dto.ServiceDTO;
import java.util.List;
import org.junit.After;
import org.junit.Test;
public class ConfigServiceLocatorTest {
@After
public void tearDown() throws Exception {
System.clearProperty("apollo.configService");
}
@Test
public void testGetConfigServicesWithSystemProperty() throws Exception {
String someConfigServiceUrl = " someConfigServiceUrl ";
String anotherConfigServiceUrl = " anotherConfigServiceUrl ";
System.setProperty("apollo.configService", someConfigServiceUrl + "," + anotherConfigServiceUrl);
ConfigServiceLocator configServiceLocator = new ConfigServiceLocator();
List<ServiceDTO> result = configServiceLocator.getConfigServices();
assertEquals(2, result.size());
assertEquals(someConfigServiceUrl.trim(), result.get(0).getHomepageUrl());
assertEquals(anotherConfigServiceUrl.trim(), result.get(1).getHomepageUrl());
}
}
......@@ -6,6 +6,8 @@ import com.ctrip.framework.apollo.core.utils.NetUtil;
import com.ctrip.framework.apollo.core.utils.ResourceUtils;
import com.ctrip.framework.apollo.tracer.Tracer;
import com.ctrip.framework.apollo.tracer.spi.Transaction;
import com.ctrip.framework.foundation.Foundation;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.Collections;
......@@ -33,9 +35,10 @@ public class MetaDomainConsts {
private static final long REFRESH_INTERVAL_IN_SECOND = 60;//1 min
private static final Logger logger = LoggerFactory.getLogger(MetaDomainConsts.class);
private static Map<Env, String> domains = new HashMap<>();
private static Map<String, String> metaServerAddressCache = Maps.newConcurrentMap();
private static AtomicBoolean periodicRefreshStarted = new AtomicBoolean(false);
private static final Map<Env, String> domains = new HashMap<>();
private static final Map<String, String> metaServerAddressCache = Maps.newConcurrentMap();
private static final AtomicBoolean periodicRefreshStarted = new AtomicBoolean(false);
private static final AtomicBoolean customizedMetaServiceLogged = new AtomicBoolean(false);
static {
initialize();
......@@ -60,11 +63,38 @@ public class MetaDomainConsts {
}
public static String getDomain(Env env) {
String metaAddress = domains.get(env);
//if there is more than one address, need to select one
// 1. Get meta server address from run time configurations
String metaAddress = getCustomizedMetaServerAddress();
if (Strings.isNullOrEmpty(metaAddress)) {
// 2. Get meta server address from environment
metaAddress = domains.get(env);
}
// 3. if there is more than one address, need to select one
if (metaAddress != null && metaAddress.contains(",")) {
return selectMetaServerAddress(metaAddress);
}
// 4. trim if necessary
if (metaAddress != null) {
metaAddress = metaAddress.trim();
}
return metaAddress;
}
private static String getCustomizedMetaServerAddress() {
// 1. Get from System Property
String metaAddress = System.getProperty("apollo.meta");
if (Strings.isNullOrEmpty(metaAddress)) {
// 2. Get from OS environment variable
metaAddress = System.getenv("APOLLO.META");
}
if (Strings.isNullOrEmpty(metaAddress)) {
metaAddress = Foundation.server().getProperty("apollo.meta", null);
}
if (!Strings.isNullOrEmpty(metaAddress) && customizedMetaServiceLogged.compareAndSet(false, true)) {
logger.warn("Located meta services from apollo.meta configuration: {}, will not use meta services defined in apollo-env.properties!", metaAddress);
}
return metaAddress;
}
......@@ -105,6 +135,7 @@ public class MetaDomainConsts {
boolean serverAvailable = false;
for (String address : metaServers) {
address = address.trim();
if (NetUtil.pingUrl(address)) {
//select the first available meta server
metaServerAddressCache.put(metaServerAddresses, address);
......@@ -116,7 +147,7 @@ public class MetaDomainConsts {
//we need to make sure the map is not empty, e.g. the first update might be failed
if (!metaServerAddressCache.containsKey(metaServerAddresses)) {
metaServerAddressCache.put(metaServerAddresses, metaServers.get(0));
metaServerAddressCache.put(metaServerAddresses, metaServers.get(0).trim());
}
if (!serverAvailable) {
......
......@@ -18,6 +18,7 @@ public class MetaDomainTest extends BaseIntegrationTest {
System.clearProperty("fat_meta");
System.clearProperty("uat_meta");
System.clearProperty("lpt_meta");
System.clearProperty("apollo.meta");
}
@Test
......@@ -27,12 +28,22 @@ public class MetaDomainTest extends BaseIntegrationTest {
assertEquals(MetaDomainConsts.DEFAULT_META_URL, MetaDomainConsts.getDomain(Env.PRO));
}
@Test
public void testGetMetaDomainWithSystemProperty() throws Exception {
String someMeta = "some-meta";
Env someEnv = Env.DEV;
System.setProperty("apollo.meta", someMeta);
assertEquals(someMeta, MetaDomainConsts.getDomain(someEnv));
}
@Test
public void testGetValidAddress() throws Exception {
String someResponse = "some response";
startServerWithHandlers(mockServerHandler(HttpServletResponse.SC_OK, someResponse));
String validServer = "http://localhost:" + PORT;
String validServer = " http://localhost:" + PORT + " ";
String invalidServer = "http://localhost:" + findFreePort();
System.setProperty("fat_meta", validServer + "," + invalidServer);
......@@ -40,14 +51,14 @@ public class MetaDomainTest extends BaseIntegrationTest {
MetaDomainConsts.initialize();
assertEquals(validServer, MetaDomainConsts.getDomain(Env.FAT));
assertEquals(validServer, MetaDomainConsts.getDomain(Env.UAT));
assertEquals(validServer.trim(), MetaDomainConsts.getDomain(Env.FAT));
assertEquals(validServer.trim(), MetaDomainConsts.getDomain(Env.UAT));
}
@Test
public void testInvalidAddress() throws Exception {
String invalidServer = "http://localhost:" + findFreePort();
String anotherInvalidServer = "http://localhost:" + findFreePort();
String invalidServer = "http://localhost:" + findFreePort() + " ";
String anotherInvalidServer = "http://localhost:" + findFreePort() + " ";
System.setProperty("lpt_meta", invalidServer + "," + anotherInvalidServer);
......@@ -55,6 +66,6 @@ public class MetaDomainTest extends BaseIntegrationTest {
String metaServer = MetaDomainConsts.getDomain(Env.LPT);
assertTrue(metaServer.equals(invalidServer) || metaServer.equals(anotherInvalidServer));
assertTrue(metaServer.equals(invalidServer.trim()) || metaServer.equals(anotherInvalidServer.trim()));
}
}
package com.ctrip.framework.apollo.foundation;
package com.ctrip.framework.foundation;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
import com.ctrip.framework.foundation.Foundation;
import com.ctrip.framework.foundation.internals.provider.DefaultApplicationProvider;
import com.ctrip.framework.foundation.internals.provider.DefaultServerProvider;
import org.junit.Assert;
import org.junit.Test;
public class FoundationTest {
private static final String someEnv = "pro";
@BeforeClass
public static void before() {
System.setProperty("env", someEnv);
}
@AfterClass
public static void afterClass() {
System.clearProperty("env");
}
@Test
public void testApp() {
// 获取AppId
String appId = Foundation.app().getAppId();
Assert.assertEquals("110402", appId);
assertTrue(Foundation.app() instanceof DefaultApplicationProvider);
}
@Test
public void testServer() {
// 获取当前环境
String envType = Foundation.server().getEnvType();
Assert.assertEquals(someEnv, envType);
assertTrue(Foundation.server() instanceof DefaultServerProvider);
}
@Test
......
package com.ctrip.framework.apollo.foundation.internals;
package com.ctrip.framework.foundation.internals;
import com.ctrip.framework.foundation.internals.ServiceBootstrap;
import org.junit.Test;
......
package com.ctrip.framework.apollo.foundation.internals.provider;
package com.ctrip.framework.foundation.internals.provider;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
......
package com.ctrip.framework.apollo.foundation.internals.provider;
package com.ctrip.framework.foundation.internals.provider;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
......
com.ctrip.framework.apollo.foundation.internals.ServiceBootstrapTest$Interface1Impl
\ No newline at end of file
com.ctrip.framework.apollo.foundation.internals.ServiceBootstrapTest$Interface1Impl
\ No newline at end of file
com.ctrip.framework.apollo.foundation.internals.ServiceBootstrapTest$SomeImplNotExists
\ No newline at end of file
......@@ -27,9 +27,6 @@ public class SimpleApolloConfigDemo {
ConfigChangeListener changeListener = new ConfigChangeListener() {
@Override
public void onChange(ConfigChangeEvent changeEvent) {
if (!changeEvent.isChanged("someKey")) {
return;
}
logger.info("Changes for namespace {}", changeEvent.getNamespace());
for (String key : changeEvent.changedKeys()) {
ConfigChange change = changeEvent.getChange(key);
......
......@@ -29,7 +29,6 @@ public class SpringBootApolloRefreshConfig {
public void onChange(ConfigChangeEvent changeEvent) {
boolean redisCacheKeysChanged = false;
for (String changedKey : changeEvent.changedKeys()) {
if (changeEvent.isChanged("someKey"))
if (changedKey.startsWith("redis.cache")) {
redisCacheKeysChanged = true;
break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment