未验证 提交 9e3aec54 编写于 作者: J Jason Song 提交者: GitHub

Merge pull request #1470 from nobodyiam/config-source

add getSourceType api
package com.ctrip.framework.apollo;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import com.google.common.base.Function;
import java.util.Date;
......@@ -203,4 +204,11 @@ public interface Config {
* @return the property value
*/
public <T> T getProperty(String key, Function<String, T> function, T defaultValue);
/**
* Return the config's source type, i.e. where is the config loaded from
*
* @return the config's source type
*/
public ConfigSourceType getSourceType();
}
package com.ctrip.framework.apollo;
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
/**
* @author Jason Song(song_s@ctrip.com)
......@@ -36,4 +37,19 @@ public interface ConfigFile {
* @param listener the config file change listener
*/
void addChangeListener(ConfigFileChangeListener listener);
/**
* Remove the change listener
*
* @param listener the specific config change listener to remove
* @return true if the specific config change listener is found and removed
*/
public boolean removeChangeListener(ConfigChangeListener listener);
/**
* Return the config's source type, i.e. where is the config loaded from
*
* @return the config's source type
*/
public ConfigSourceType getSourceType();
}
package com.ctrip.framework.apollo.enums;
/**
* To indicate the config's source type, i.e. where is the config loaded from
*/
public enum ConfigSourceType {
REMOTE("Loaded from remote config service"), LOCAL("Loaded from local cache"), NONE("Load failed");
private final String description;
ConfigSourceType(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
package com.ctrip.framework.apollo.internals;
import com.ctrip.framework.apollo.ConfigChangeListener;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
......@@ -25,10 +27,12 @@ import com.google.common.collect.Lists;
public abstract class AbstractConfigFile implements ConfigFile, RepositoryChangeListener {
private static final Logger logger = LoggerFactory.getLogger(AbstractConfigFile.class);
private static ExecutorService m_executorService;
protected ConfigRepository m_configRepository;
protected String m_namespace;
protected AtomicReference<Properties> m_configProperties;
private List<ConfigFileChangeListener> m_listeners = Lists.newCopyOnWriteArrayList();
protected final ConfigRepository m_configRepository;
protected final String m_namespace;
protected final AtomicReference<Properties> m_configProperties;
private final List<ConfigFileChangeListener> m_listeners = Lists.newCopyOnWriteArrayList();
private volatile ConfigSourceType m_sourceType = ConfigSourceType.NONE;
static {
m_executorService = Executors.newCachedThreadPool(ApolloThreadFactory
......@@ -45,6 +49,7 @@ public abstract class AbstractConfigFile implements ConfigFile, RepositoryChange
private void initialize() {
try {
m_configProperties.set(m_configRepository.getConfig());
m_sourceType = m_configRepository.getSourceType();
} catch (Throwable ex) {
Tracer.logError(ex);
logger.warn("Init Apollo Config File failed - namespace: {}, reason: {}.",
......@@ -74,6 +79,7 @@ public abstract class AbstractConfigFile implements ConfigFile, RepositoryChange
String oldValue = getContent();
update(newProperties);
m_sourceType = m_configRepository.getSourceType();
String newValue = getContent();
......@@ -97,6 +103,16 @@ public abstract class AbstractConfigFile implements ConfigFile, RepositoryChange
}
}
@Override
public boolean removeChangeListener(ConfigChangeListener listener) {
return m_listeners.remove(listener);
}
@Override
public ConfigSourceType getSourceType() {
return m_sourceType;
}
private void fireConfigChange(final ConfigFileChangeEvent changeEvent) {
for (final ConfigFileChangeListener listener : m_listeners) {
m_executorService.submit(new Runnable() {
......
package com.ctrip.framework.apollo.internals;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import java.util.Properties;
/**
......@@ -29,4 +30,11 @@ public interface ConfigRepository {
* @param listener the listener to remove
*/
public void removeChangeListener(RepositoryChangeListener listener);
/**
* Return the config's source type, i.e. where is the config loaded from
*
* @return the config's source type
*/
public ConfigSourceType getSourceType();
}
package com.ctrip.framework.apollo.internals;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
......@@ -30,10 +31,12 @@ import com.google.common.util.concurrent.RateLimiter;
public class DefaultConfig extends AbstractConfig implements RepositoryChangeListener {
private static final Logger logger = LoggerFactory.getLogger(DefaultConfig.class);
private final String m_namespace;
private Properties m_resourceProperties;
private AtomicReference<Properties> m_configProperties;
private ConfigRepository m_configRepository;
private RateLimiter m_warnLogRateLimiter;
private final Properties m_resourceProperties;
private final AtomicReference<Properties> m_configProperties;
private final ConfigRepository m_configRepository;
private final RateLimiter m_warnLogRateLimiter;
private volatile ConfigSourceType m_sourceType = ConfigSourceType.NONE;
/**
* Constructor.
......@@ -52,7 +55,7 @@ public class DefaultConfig extends AbstractConfig implements RepositoryChangeLis
private void initialize() {
try {
m_configProperties.set(m_configRepository.getConfig());
updateConfig(m_configRepository.getConfig(), m_configRepository.getSourceType());
} catch (Throwable ex) {
Tracer.logError(ex);
logger.warn("Init Apollo Local Config failed - namespace: {}, reason: {}.",
......@@ -105,6 +108,11 @@ public class DefaultConfig extends AbstractConfig implements RepositoryChangeLis
return stringPropertyNames(properties);
}
@Override
public ConfigSourceType getSourceType() {
return m_sourceType;
}
private Set<String> stringPropertyNames(Properties properties) {
//jdk9以下版本Properties#enumerateStringProperties方法存在性能问题,keys() + get(k) 重复迭代, jdk9之后改为entrySet遍历.
Map<String, String> h = new HashMap<>();
......@@ -123,10 +131,12 @@ public class DefaultConfig extends AbstractConfig implements RepositoryChangeLis
if (newProperties.equals(m_configProperties.get())) {
return;
}
ConfigSourceType sourceType = m_configRepository.getSourceType();
Properties newConfigProperties = new Properties();
newConfigProperties.putAll(newProperties);
Map<String, ConfigChange> actualChanges = updateAndCalcConfigChanges(newConfigProperties);
Map<String, ConfigChange> actualChanges = updateAndCalcConfigChanges(newConfigProperties, sourceType);
//check double checked result
if (actualChanges.isEmpty()) {
......@@ -138,7 +148,13 @@ public class DefaultConfig extends AbstractConfig implements RepositoryChangeLis
Tracer.logEvent("Apollo.Client.ConfigChanges", m_namespace);
}
private Map<String, ConfigChange> updateAndCalcConfigChanges(Properties newConfigProperties) {
private void updateConfig(Properties newConfigProperties, ConfigSourceType sourceType) {
m_configProperties.set(newConfigProperties);
m_sourceType = sourceType;
}
private Map<String, ConfigChange> updateAndCalcConfigChanges(Properties newConfigProperties,
ConfigSourceType sourceType) {
List<ConfigChange> configChanges =
calcPropertyChanges(m_namespace, m_configProperties.get(), newConfigProperties);
......@@ -153,7 +169,7 @@ public class DefaultConfig extends AbstractConfig implements RepositoryChangeLis
}
//2. update m_configProperties
m_configProperties.set(newConfigProperties);
updateConfig(newConfigProperties, sourceType);
clearConfigCache();
//3. use getProperty to update configChange's new value and calc the final changes
......
package com.ctrip.framework.apollo.internals;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
......@@ -38,6 +39,8 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
private volatile Properties m_fileProperties;
private volatile ConfigRepository m_upstream;
private volatile ConfigSourceType m_sourceType = ConfigSourceType.LOCAL;
/**
* Constructor.
*
......@@ -104,6 +107,11 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
upstreamConfigRepository.addChangeListener(this);
}
@Override
public ConfigSourceType getSourceType() {
return m_sourceType;
}
@Override
public void onRepositoryChange(String namespace, Properties newProperties) {
if (newProperties.equals(m_fileProperties)) {
......@@ -111,7 +119,7 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
}
Properties newFileProperties = new Properties();
newFileProperties.putAll(newProperties);
updateFileProperties(newFileProperties);
updateFileProperties(newFileProperties, m_upstream.getSourceType());
this.fireRepositoryChange(namespace, newProperties);
}
......@@ -129,6 +137,7 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
try {
transaction.addData("Basedir", m_baseDir.getAbsolutePath());
m_fileProperties = this.loadFromLocalCacheFile(m_baseDir, m_namespace);
m_sourceType = ConfigSourceType.LOCAL;
transaction.setStatus(Transaction.SUCCESS);
} catch (Throwable ex) {
Tracer.logEvent("ApolloConfigException", ExceptionUtil.getDetailMessage(ex));
......@@ -140,6 +149,7 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
}
if (m_fileProperties == null) {
m_sourceType = ConfigSourceType.NONE;
throw new ApolloConfigException(
"Load config from local config failed!", exception);
}
......@@ -150,8 +160,7 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
return false;
}
try {
Properties properties = m_upstream.getConfig();
updateFileProperties(properties);
updateFileProperties(m_upstream.getConfig(), m_upstream.getSourceType());
return true;
} catch (Throwable ex) {
Tracer.logError(ex);
......@@ -162,7 +171,8 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
return false;
}
private synchronized void updateFileProperties(Properties newProperties) {
private synchronized void updateFileProperties(Properties newProperties, ConfigSourceType sourceType) {
this.m_sourceType = sourceType;
if (newProperties.equals(m_fileProperties)) {
return;
}
......
package com.ctrip.framework.apollo.internals;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import java.util.Collections;
import java.util.List;
import java.util.Map;
......@@ -47,21 +48,22 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
private static final Logger logger = LoggerFactory.getLogger(RemoteConfigRepository.class);
private static final Joiner STRING_JOINER = Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR);
private static final Joiner.MapJoiner MAP_JOINER = Joiner.on("&").withKeyValueSeparator("=");
private ConfigServiceLocator m_serviceLocator;
private HttpUtil m_httpUtil;
private ConfigUtil m_configUtil;
private RemoteConfigLongPollService remoteConfigLongPollService;
private static final Escaper pathEscaper = UrlEscapers.urlPathSegmentEscaper();
private static final Escaper queryParamEscaper = UrlEscapers.urlFormParameterEscaper();
private final ConfigServiceLocator m_serviceLocator;
private final HttpUtil m_httpUtil;
private final ConfigUtil m_configUtil;
private final RemoteConfigLongPollService remoteConfigLongPollService;
private volatile AtomicReference<ApolloConfig> m_configCache;
private final String m_namespace;
private final static ScheduledExecutorService m_executorService;
private AtomicReference<ServiceDTO> m_longPollServiceDto;
private AtomicReference<ApolloNotificationMessages> m_remoteMessages;
private RateLimiter m_loadConfigRateLimiter;
private AtomicBoolean m_configNeedForceRefresh;
private SchedulePolicy m_loadConfigFailSchedulePolicy;
private Gson gson;
private static final Escaper pathEscaper = UrlEscapers.urlPathSegmentEscaper();
private static final Escaper queryParamEscaper = UrlEscapers.urlFormParameterEscaper();
private final AtomicReference<ServiceDTO> m_longPollServiceDto;
private final AtomicReference<ApolloNotificationMessages> m_remoteMessages;
private final RateLimiter m_loadConfigRateLimiter;
private final AtomicBoolean m_configNeedForceRefresh;
private final SchedulePolicy m_loadConfigFailSchedulePolicy;
private final Gson gson;
static {
m_executorService = Executors.newScheduledThreadPool(1,
......@@ -105,6 +107,11 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
//remote config doesn't need upstream
}
@Override
public ConfigSourceType getSourceType() {
return ConfigSourceType.REMOTE;
}
private void schedulePeriodicRefresh() {
logger.debug("Schedule periodic refresh with interval: {} {}",
m_configUtil.getRefreshInterval(), m_configUtil.getRefreshIntervalTimeUnit());
......
package com.ctrip.framework.apollo.internals;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import java.util.Collections;
import java.util.List;
import java.util.Map;
......@@ -24,6 +25,7 @@ public class SimpleConfig extends AbstractConfig implements RepositoryChangeList
private final String m_namespace;
private final ConfigRepository m_configRepository;
private volatile Properties m_configProperties;
private volatile ConfigSourceType m_sourceType = ConfigSourceType.NONE;
/**
* Constructor.
......@@ -39,7 +41,7 @@ public class SimpleConfig extends AbstractConfig implements RepositoryChangeList
private void initialize() {
try {
m_configProperties = m_configRepository.getConfig();
updateConfig(m_configRepository.getConfig(), m_configRepository.getSourceType());
} catch (Throwable ex) {
Tracer.logError(ex);
logger.warn("Init Apollo Simple Config failed - namespace: {}, reason: {}", m_namespace,
......@@ -69,6 +71,11 @@ public class SimpleConfig extends AbstractConfig implements RepositoryChangeList
return m_configProperties.stringPropertyNames();
}
@Override
public ConfigSourceType getSourceType() {
return m_sourceType;
}
@Override
public synchronized void onRepositoryChange(String namespace, Properties newProperties) {
if (newProperties.equals(m_configProperties)) {
......@@ -77,9 +84,7 @@ public class SimpleConfig extends AbstractConfig implements RepositoryChangeList
Properties newConfigProperties = new Properties();
newConfigProperties.putAll(newProperties);
List<ConfigChange>
changes =
calcPropertyChanges(namespace, m_configProperties, newConfigProperties);
List<ConfigChange> changes = calcPropertyChanges(namespace, m_configProperties, newConfigProperties);
Map<String, ConfigChange> changeMap = Maps.uniqueIndex(changes,
new Function<ConfigChange, String>() {
@Override
......@@ -88,11 +93,16 @@ public class SimpleConfig extends AbstractConfig implements RepositoryChangeList
}
});
m_configProperties = newConfigProperties;
updateConfig(newConfigProperties, m_configRepository.getSourceType());
clearConfigCache();
this.fireConfigChange(new ConfigChangeEvent(m_namespace, changeMap));
Tracer.logEvent("Apollo.Client.ConfigChanges", m_namespace);
}
private void updateConfig(Properties newConfigProperties, ConfigSourceType sourceType) {
m_configProperties = newConfigProperties;
m_sourceType = sourceType;
}
}
......@@ -2,6 +2,7 @@ package com.ctrip.framework.apollo;
import static org.junit.Assert.assertEquals;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import java.util.Set;
import org.junit.Before;
......@@ -101,6 +102,11 @@ public class ConfigServiceTest {
public Set<String> getPropertyNames() {
return null;
}
@Override
public ConfigSourceType getSourceType() {
return null;
}
}
private static class MockConfigFile implements ConfigFile {
......@@ -137,6 +143,16 @@ public class ConfigServiceTest {
public void addChangeListener(ConfigFileChangeListener listener) {
}
@Override
public boolean removeChangeListener(ConfigChangeListener listener) {
return false;
}
@Override
public ConfigSourceType getSourceType() {
return null;
}
}
public static class MockConfigFactory implements ConfigFactory {
......
......@@ -5,6 +5,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import java.util.Properties;
import java.util.Set;
......@@ -103,6 +104,11 @@ public class DefaultConfigManagerTest {
public Set<String> getPropertyNames() {
return null;
}
@Override
public ConfigSourceType getSourceType() {
return null;
}
};
}
......
......@@ -9,6 +9,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import java.io.File;
......@@ -50,6 +51,7 @@ public class DefaultConfigTest {
private String someNamespace;
private ConfigRepository configRepository;
private Properties someProperties;
private ConfigSourceType someSourceType;
@Before
public void setUp() throws Exception {
......@@ -99,6 +101,8 @@ public class DefaultConfigTest {
someProperties.setProperty(someKey, someLocalFileValue);
someProperties.setProperty(anotherKey, someLocalFileValue);
when(configRepository.getConfig()).thenReturn(someProperties);
someSourceType = ConfigSourceType.LOCAL;
when(configRepository.getSourceType()).thenReturn(someSourceType);
//set up resource file
File resourceFile = new File(someResourceDir, someNamespace + ".properties");
......@@ -122,6 +126,7 @@ public class DefaultConfigTest {
assertEquals(someLocalFileValue, anotherKeyValue);
assertEquals(someResourceValue, lastKeyValue);
assertEquals(someSourceType, defaultConfig.getSourceType());
}
@Test
......@@ -599,6 +604,8 @@ public class DefaultConfigTest {
.of(someKey, someLocalFileValue, anotherKey, someLocalFileValue, keyToBeDeleted,
keyToBeDeletedValue, yetAnotherKey, yetAnotherValue));
when(configRepository.getConfig()).thenReturn(someProperties);
someSourceType = ConfigSourceType.LOCAL;
when(configRepository.getSourceType()).thenReturn(someSourceType);
//set up resource file
File resourceFile = new File(someResourceDir, someNamespace + ".properties");
......@@ -607,6 +614,8 @@ public class DefaultConfigTest {
DefaultConfig defaultConfig =
new DefaultConfig(someNamespace, configRepository);
assertEquals(someSourceType, defaultConfig.getSourceType());
final SettableFuture<ConfigChangeEvent> configChangeFuture = SettableFuture.create();
ConfigChangeListener someListener = new ConfigChangeListener() {
@Override
......@@ -625,6 +634,9 @@ public class DefaultConfigTest {
newProperties.putAll(ImmutableMap
.of(someKey, someKeyNewValue, anotherKey, anotherKeyNewValue, newKey, newValue));
ConfigSourceType anotherSourceType = ConfigSourceType.REMOTE;
when(configRepository.getSourceType()).thenReturn(anotherSourceType);
defaultConfig.onRepositoryChange(someNamespace, newProperties);
ConfigChangeEvent changeEvent = configChangeFuture.get(500, TimeUnit.MILLISECONDS);
......@@ -654,6 +666,8 @@ public class DefaultConfigTest {
assertEquals(null, newKeyChange.getOldValue());
assertEquals(newValue, newKeyChange.getNewValue());
assertEquals(PropertyChangeType.ADDED, newKeyChange.getChangeType());
assertEquals(anotherSourceType, defaultConfig.getSourceType());
}
@Test
......@@ -825,6 +839,34 @@ public class DefaultConfigTest {
}, Lists.<String>newArrayList()), Lists.newArrayList());
}
@Test
public void testLoadFromRepositoryFailedAndThenRecovered() {
String someKey = "someKey";
String someValue = "someValue";
String someDefaultValue = "someDefaultValue";
ConfigSourceType someSourceType = ConfigSourceType.REMOTE;
when(configRepository.getConfig()).thenThrow(mock(RuntimeException.class));
DefaultConfig defaultConfig =
new DefaultConfig(someNamespace, configRepository);
verify(configRepository, times(1)).addChangeListener(defaultConfig);
assertEquals(ConfigSourceType.NONE, defaultConfig.getSourceType());
assertEquals(someDefaultValue, defaultConfig.getProperty(someKey, someDefaultValue));
someProperties = new Properties();
someProperties.setProperty(someKey, someValue);
when(configRepository.getSourceType()).thenReturn(someSourceType);
defaultConfig.onRepositoryChange(someNamespace, someProperties);
assertEquals(someSourceType, defaultConfig.getSourceType());
assertEquals(someValue, defaultConfig.getProperty(someKey, someDefaultValue));
}
private void checkDatePropertyWithFormat(Config config, Date expected, String propertyName, String format, Date
defaultValue) {
assertEquals(expected, config.getDateProperty(propertyName, format, defaultValue));
......
......@@ -6,6 +6,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import java.util.Properties;
import org.junit.Before;
......@@ -26,6 +27,8 @@ public class JsonConfigFileTest {
@Mock
private ConfigRepository configRepository;
private ConfigSourceType someSourceType;
@Before
public void setUp() throws Exception {
someNamespace = "someName";
......@@ -38,7 +41,10 @@ public class JsonConfigFileTest {
String someValue = "someValue";
someProperties.setProperty(key, someValue);
someSourceType = ConfigSourceType.LOCAL;
when(configRepository.getConfig()).thenReturn(someProperties);
when(configRepository.getSourceType()).thenReturn(someSourceType);
JsonConfigFile configFile = new JsonConfigFile(someNamespace, configRepository);
......@@ -46,6 +52,7 @@ public class JsonConfigFileTest {
assertEquals(someNamespace, configFile.getNamespace());
assertTrue(configFile.hasContent());
assertEquals(someValue, configFile.getContent());
assertEquals(someSourceType, configFile.getSourceType());
}
@Test
......@@ -66,6 +73,7 @@ public class JsonConfigFileTest {
assertFalse(configFile.hasContent());
assertNull(configFile.getContent());
assertEquals(ConfigSourceType.NONE, configFile.getSourceType());
}
@Test
......@@ -76,18 +84,26 @@ public class JsonConfigFileTest {
String anotherValue = "anotherValue";
someProperties.setProperty(key, someValue);
someSourceType = ConfigSourceType.LOCAL;
when(configRepository.getConfig()).thenReturn(someProperties);
when(configRepository.getSourceType()).thenReturn(someSourceType);
JsonConfigFile configFile = new JsonConfigFile(someNamespace, configRepository);
assertEquals(someValue, configFile.getContent());
assertEquals(someSourceType, configFile.getSourceType());
Properties anotherProperties = new Properties();
anotherProperties.setProperty(key, anotherValue);
ConfigSourceType anotherSourceType = ConfigSourceType.REMOTE;
when(configRepository.getSourceType()).thenReturn(anotherSourceType);
configFile.onRepositoryChange(someNamespace, anotherProperties);
assertEquals(anotherValue, configFile.getContent());
assertEquals(anotherSourceType, configFile.getSourceType());
}
@Test
......@@ -97,16 +113,21 @@ public class JsonConfigFileTest {
String someValue = "someValue";
someProperties.setProperty(key, someValue);
someSourceType = ConfigSourceType.LOCAL;
when(configRepository.getConfig()).thenThrow(new RuntimeException("someError"));
when(configRepository.getSourceType()).thenReturn(someSourceType);
JsonConfigFile configFile = new JsonConfigFile(someNamespace, configRepository);
assertFalse(configFile.hasContent());
assertNull(configFile.getContent());
assertEquals(ConfigSourceType.NONE, configFile.getSourceType());
configFile.onRepositoryChange(someNamespace, someProperties);
assertTrue(configFile.hasContent());
assertEquals(someValue, configFile.getContent());
assertEquals(someSourceType, configFile.getSourceType());
}
}
......@@ -9,6 +9,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
......@@ -38,6 +39,7 @@ public class LocalFileConfigRepositoryTest {
private static String someCluster = "someCluster";
private String defaultKey;
private String defaultValue;
private ConfigSourceType someSourceType;
@Before
public void setUp() throws Exception {
......@@ -49,8 +51,10 @@ public class LocalFileConfigRepositoryTest {
defaultKey = "defaultKey";
defaultValue = "defaultValue";
someProperties.setProperty(defaultKey, defaultValue);
someSourceType = ConfigSourceType.REMOTE;
upstreamRepo = mock(ConfigRepository.class);
when(upstreamRepo.getConfig()).thenReturn(someProperties);
when(upstreamRepo.getSourceType()).thenReturn(someSourceType);
MockInjector.reset();
MockInjector.setInstance(ConfigUtil.class, new MockConfigUtil());
......@@ -95,7 +99,7 @@ public class LocalFileConfigRepositoryTest {
Properties properties = localRepo.getConfig();
assertEquals(someValue, properties.getProperty(someKey));
assertEquals(ConfigSourceType.LOCAL, localRepo.getSourceType());
}
@Test
......@@ -112,12 +116,12 @@ public class LocalFileConfigRepositoryTest {
Properties properties = localRepo.getConfig();
assertEquals(defaultValue, properties.getProperty(defaultKey));
assertEquals(someSourceType, localRepo.getSourceType());
}
@Test
public void testLoadConfigWithNoLocalFile() throws Exception {
LocalFileConfigRepository
localFileConfigRepository =
LocalFileConfigRepository localFileConfigRepository =
new LocalFileConfigRepository(someNamespace, upstreamRepo);
localFileConfigRepository.setLocalCacheDir(someBaseDir, true);
......@@ -126,6 +130,7 @@ public class LocalFileConfigRepositoryTest {
assertThat(
"LocalFileConfigRepository's properties should be the same as fallback repo's when there is no local cache",
result.entrySet(), equalTo(someProperties.entrySet()));
assertEquals(someSourceType, localFileConfigRepository.getSourceType());
}
@Test
......@@ -146,7 +151,7 @@ public class LocalFileConfigRepositoryTest {
assertThat(
"LocalFileConfigRepository should persist local cache files and return that afterwards",
someProperties.entrySet(), equalTo(anotherProperties.entrySet()));
assertEquals(someSourceType, localRepo.getSourceType());
}
@Test
......@@ -155,6 +160,9 @@ public class LocalFileConfigRepositoryTest {
LocalFileConfigRepository localFileConfigRepository =
new LocalFileConfigRepository(someNamespace, upstreamRepo);
assertEquals(someSourceType, localFileConfigRepository.getSourceType());
localFileConfigRepository.setLocalCacheDir(someBaseDir, true);
localFileConfigRepository.addChangeListener(someListener);
......@@ -163,6 +171,9 @@ public class LocalFileConfigRepositoryTest {
Properties anotherProperties = new Properties();
anotherProperties.put("anotherKey", "anotherValue");
ConfigSourceType anotherSourceType = ConfigSourceType.NONE;
when(upstreamRepo.getSourceType()).thenReturn(anotherSourceType);
localFileConfigRepository.onRepositoryChange(someNamespace, anotherProperties);
final ArgumentCaptor<Properties> captor = ArgumentCaptor.forClass(Properties.class);
......@@ -170,7 +181,7 @@ public class LocalFileConfigRepositoryTest {
verify(someListener, times(1)).onRepositoryChange(eq(someNamespace), captor.capture());
assertEquals(anotherProperties, captor.getValue());
assertEquals(anotherSourceType, localFileConfigRepository.getSourceType());
}
public static class MockConfigUtil extends ConfigUtil {
......
......@@ -12,6 +12,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
......@@ -105,6 +106,7 @@ public class RemoteConfigRepositoryTest {
Properties config = remoteConfigRepository.getConfig();
assertEquals(configurations, config);
assertEquals(ConfigSourceType.REMOTE, remoteConfigRepository.getSourceType());
remoteConfigLongPollService.stopLongPollingRefresh();
}
......
package com.ctrip.framework.apollo.internals;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
......@@ -28,6 +30,7 @@ public class SimpleConfigTest {
private String someNamespace;
@Mock
private ConfigRepository configRepository;
private ConfigSourceType someSourceType;
@Before
public void setUp() throws Exception {
......@@ -41,22 +44,28 @@ public class SimpleConfigTest {
String someValue = "someValue";
someProperties.setProperty(someKey, someValue);
someSourceType = ConfigSourceType.LOCAL;
when(configRepository.getConfig()).thenReturn(someProperties);
when(configRepository.getSourceType()).thenReturn(someSourceType);
SimpleConfig config = new SimpleConfig(someNamespace, configRepository);
assertEquals(someValue, config.getProperty(someKey, null));
assertEquals(someSourceType, config.getSourceType());
}
@Test
public void testLoadConfigFromConfigRepositoryError() throws Exception {
when(configRepository.getConfig()).thenThrow(Throwable.class);
String someKey = "someKey";
String anyValue = "anyValue" + Math.random();
when(configRepository.getConfig()).thenThrow(mock(RuntimeException.class));
Config config = new SimpleConfig(someNamespace, configRepository);
String someKey = "someKey";
String anyValue = "anyValue" + Math.random();
assertEquals(anyValue, config.getProperty(someKey, anyValue));
assertEquals(ConfigSourceType.NONE, config.getSourceType());
}
@Test
......@@ -74,7 +83,10 @@ public class SimpleConfigTest {
String someValueNew = "someValueNew";
anotherProperties.putAll(ImmutableMap.of(someKey, someValueNew, newKey, newValue));
someSourceType = ConfigSourceType.LOCAL;
when(configRepository.getConfig()).thenReturn(someProperties);
when(configRepository.getSourceType()).thenReturn(someSourceType);
final SettableFuture<ConfigChangeEvent> configChangeFuture = SettableFuture.create();
ConfigChangeListener someListener = new ConfigChangeListener() {
......@@ -85,8 +97,14 @@ public class SimpleConfigTest {
};
SimpleConfig config = new SimpleConfig(someNamespace, configRepository);
assertEquals(someSourceType, config.getSourceType());
config.addChangeListener(someListener);
ConfigSourceType anotherSourceType = ConfigSourceType.REMOTE;
when(configRepository.getSourceType()).thenReturn(anotherSourceType);
config.onRepositoryChange(someNamespace, anotherProperties);
ConfigChangeEvent changeEvent = configChangeFuture.get(500, TimeUnit.MILLISECONDS);
......@@ -108,5 +126,7 @@ public class SimpleConfigTest {
assertEquals(null, newKeyChange.getOldValue());
assertEquals(newValue, newKeyChange.getNewValue());
assertEquals(PropertyChangeType.ADDED, newKeyChange.getChangeType());
assertEquals(anotherSourceType, config.getSourceType());
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册