From 38469c42f92c260e89bc5c7fe78700d8cc90e366 Mon Sep 17 00:00:00 2001 From: TerryLam2010 <36256759+TerryLam2010@users.noreply.github.com> Date: Thu, 5 Sep 2024 17:56:32 +0800 Subject: [PATCH] merge branch --- CHANGES.md | 11 +- .../data/internals/PureApolloConfig.java | 12 ++ .../internals/PureApolloConfigFactory.java | 4 +- .../ctrip/framework/apollo/ConfigFile.java | 10 + .../ctrip/framework/apollo/ConfigService.java | 22 +++ .../apollo/internals/AbstractConfig.java | 12 +- .../apollo/internals/AbstractConfigFile.java | 16 +- .../internals/AbstractConfigRepository.java | 4 +- .../apollo/internals/ConfigManager.java | 17 ++ .../apollo/internals/DefaultConfig.java | 42 +++- .../internals/DefaultConfigManager.java | 51 +++-- .../InterestedConfigChangeEvent.java | 4 +- .../apollo/internals/JsonConfigFile.java | 4 +- .../internals/LocalFileConfigRepository.java | 33 ++-- .../apollo/internals/PlainTextConfigFile.java | 4 +- ...pertiesCompatibleFileConfigRepository.java | 2 +- .../internals/PropertiesConfigFile.java | 4 +- .../RemoteConfigLongPollService.java | 83 ++++---- .../internals/RemoteConfigRepository.java | 13 +- .../internals/RepositoryChangeListener.java | 8 + .../apollo/internals/SimpleConfig.java | 29 ++- .../apollo/internals/TxtConfigFile.java | 4 +- .../apollo/internals/XmlConfigFile.java | 4 +- .../apollo/internals/YamlConfigFile.java | 4 +- .../apollo/internals/YmlConfigFile.java | 4 +- .../framework/apollo/model/ConfigChange.java | 10 +- .../apollo/model/ConfigChangeEvent.java | 12 +- .../apollo/model/ConfigFileChangeEvent.java | 13 +- .../framework/apollo/spi/ConfigFactory.java | 17 ++ .../apollo/spi/ConfigFactoryManager.java | 8 + .../framework/apollo/spi/ConfigRegistry.java | 18 ++ .../apollo/spi/DefaultConfigFactory.java | 63 +++--- .../spi/DefaultConfigFactoryManager.java | 19 +- .../apollo/spi/DefaultConfigRegistry.java | 36 +++- .../annotation/ApolloAnnotationProcessor.java | 4 +- .../spring/annotation/ApolloConfig.java | 7 + .../spring/annotation/EnableApolloConfig.java | 7 + .../spring/annotation/MultipleConfig.java | 51 +++++ .../config/PropertySourcesProcessor.java | 32 ++- .../DefaultApolloConfigRegistrarHelper.java | 42 +++- .../framework/apollo/util/ConfigUtil.java | 15 ++ .../framework/apollo/BaseIntegrationTest.java | 7 + .../framework/apollo/ConfigServiceTest.java | 50 ++++- .../framework/apollo/build/MockInjector.java | 6 +- .../integration/ConfigIntegrationTest.java | 2 +- .../apollo/internals/AbstractConfigTest.java | 16 +- .../internals/DefaultConfigManagerTest.java | 25 ++- .../apollo/internals/DefaultConfigTest.java | 62 +++--- .../InterestedConfigChangeEventTest.java | 8 +- .../apollo/internals/JsonConfigFileTest.java | 16 +- .../LocalFileConfigRepositoryTest.java | 16 +- ...iesCompatibleFileConfigRepositoryTest.java | 5 +- .../internals/PropertiesConfigFileTest.java | 16 +- .../RemoteConfigLongPollServiceTest.java | 43 ++-- .../internals/RemoteConfigRepositoryTest.java | 37 ++-- .../apollo/internals/SimpleConfigTest.java | 11 +- .../apollo/internals/TxtConfigFileTest.java | 5 +- .../apollo/internals/XmlConfigFileTest.java | 20 +- .../apollo/internals/YamlConfigFileTest.java | 20 +- ...ultConfigFactoryFileCachePropertyTest.java | 18 +- .../spi/DefaultConfigFactoryManagerTest.java | 43 ++++ .../apollo/spi/DefaultConfigFactoryTest.java | 50 ++--- .../apollo/spi/DefaultConfigRegistryTest.java | 10 + .../spring/AbstractSpringIntegrationTest.java | 63 ++++-- .../apollo/spring/BootstrapConfigTest.java | 33 ++-- .../spring/JavaConfigAnnotationTest.java | 187 +++++++++++++----- .../JavaConfigPlaceholderAutoUpdateTest.java | 87 ++++---- .../spring/JavaConfigPlaceholderTest.java | 53 ++--- .../spring/XMLConfigAnnotationTest.java | 20 +- .../XmlConfigPlaceholderAutoUpdateTest.java | 56 +++--- .../spring/XmlConfigPlaceholderTest.java | 15 +- .../CachedCompositePropertySourceTest.java | 2 +- .../config/PropertySourcesProcessorTest.java | 21 +- .../framework/apollo/util/ConfigUtilTest.java | 6 +- .../apollo/core/utils/StringUtils.java | 4 + .../provider/DefaultApplicationProvider.java | 9 + .../internals/provider/NullProvider.java | 5 + .../spi/provider/ApplicationProvider.java | 9 + .../mockserver/ApolloTestingServer.java | 3 +- ...ckServerApiWhileCacheDirSpecifiedTest.java | 2 +- changes/changes-2.3.0.md | 16 ++ pom.xml | 2 +- 82 files changed, 1299 insertions(+), 535 deletions(-) create mode 100644 apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/MultipleConfig.java create mode 100644 changes/changes-2.3.0.md diff --git a/CHANGES.md b/CHANGES.md index ac8b61a9..be8acbe5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,15 +2,10 @@ Changes by Version ================== Release Notes. -Apollo Java 2.3.0 +Apollo Java 2.4.0 ------------------ -* [add an initialize method to avoid DefaultProviderManager's logic being triggered when using custom ProviderManager.](https://github.com/apolloconfig/apollo-java/pull/50) -* [Implement parsing time based on pattern for @ApolloJsonValue](https://github.com/apolloconfig/apollo-java/pull/53) -* [Enhance to load mocked properties from apollo.cache-dir](https://github.com/apolloconfig/apollo-java/pull/58) -* [perf: speed up the first loading of namespace when startup meet 404](https://github.com/apolloconfig/apollo-java/pull/61) -* [perf: speed up when startup meets timeout](https://github.com/apolloconfig/apollo-java/pull/64) -* [upgrade spring boot to 2.7.18](https://github.com/apolloconfig/apollo-java/pull/68) +* ------------------ -All issues and pull requests are [here](https://github.com/apolloconfig/apollo-java/milestone/3?closed=1) \ No newline at end of file +All issues and pull requests are [here](https://github.com/apolloconfig/apollo-java/milestone/4?closed=1) \ No newline at end of file diff --git a/apollo-client-config-data/src/main/java/com/ctrip/framework/apollo/config/data/internals/PureApolloConfig.java b/apollo-client-config-data/src/main/java/com/ctrip/framework/apollo/config/data/internals/PureApolloConfig.java index c3bece95..222a12c0 100644 --- a/apollo-client-config-data/src/main/java/com/ctrip/framework/apollo/config/data/internals/PureApolloConfig.java +++ b/apollo-client-config-data/src/main/java/com/ctrip/framework/apollo/config/data/internals/PureApolloConfig.java @@ -39,6 +39,18 @@ public PureApolloConfig(String namespace, super(namespace, configRepository); } + /** + * Constructor. + * + * @param appId the appId of this config instance + * @param namespace the namespace of this config instance + * @param configRepository the config repository for this config instance + */ + public PureApolloConfig(String appId, String namespace, + ConfigRepository configRepository) { + super(appId, namespace, configRepository); + } + @Override public String getProperty(String key, String defaultValue) { // step 1: check local cached properties file diff --git a/apollo-client-config-data/src/main/java/com/ctrip/framework/apollo/config/data/internals/PureApolloConfigFactory.java b/apollo-client-config-data/src/main/java/com/ctrip/framework/apollo/config/data/internals/PureApolloConfigFactory.java index c731c7f7..f71436e1 100644 --- a/apollo-client-config-data/src/main/java/com/ctrip/framework/apollo/config/data/internals/PureApolloConfigFactory.java +++ b/apollo-client-config-data/src/main/java/com/ctrip/framework/apollo/config/data/internals/PureApolloConfigFactory.java @@ -27,7 +27,7 @@ public class PureApolloConfigFactory extends DefaultConfigFactory implements ConfigFactory { @Override - protected Config createRepositoryConfig(String namespace, ConfigRepository configRepository) { - return new PureApolloConfig(namespace, configRepository); + protected Config createRepositoryConfig(String appId, String namespace, ConfigRepository configRepository) { + return new PureApolloConfig(appId, namespace, configRepository); } } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/ConfigFile.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/ConfigFile.java index 50b84a38..06b72d3e 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/ConfigFile.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/ConfigFile.java @@ -35,6 +35,16 @@ public interface ConfigFile { */ boolean hasContent(); + /** + * Get the appId of this config file instance + * @return the appId + * + * @since 2.4.0 + */ + default String getAppId(){ + return null; + } + /** * Get the namespace of this config file instance * @return the namespace diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/ConfigService.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/ConfigService.java index 184c5ee3..55e142c2 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/ConfigService.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/ConfigService.java @@ -19,9 +19,11 @@ import com.ctrip.framework.apollo.build.ApolloInjector; import com.ctrip.framework.apollo.core.ConfigConsts; import com.ctrip.framework.apollo.core.enums.ConfigFileFormat; +import com.ctrip.framework.apollo.core.utils.StringUtils; import com.ctrip.framework.apollo.internals.ConfigManager; import com.ctrip.framework.apollo.spi.ConfigFactory; import com.ctrip.framework.apollo.spi.ConfigRegistry; +import com.ctrip.framework.apollo.util.ConfigUtil; /** * Entry point for client config use @@ -77,6 +79,10 @@ public static Config getConfig(String namespace) { return s_instance.getManager().getConfig(namespace); } + public static Config getConfig(String appId, String namespace) { + return s_instance.getManager().getConfig(appId, namespace); + } + public static ConfigFile getConfigFile(String namespace, ConfigFileFormat configFileFormat) { return s_instance.getManager().getConfigFile(namespace, configFileFormat); } @@ -93,16 +99,32 @@ static void setConfig(Config config) { */ static void setConfig(String namespace, final Config config) { s_instance.getRegistry().register(namespace, new ConfigFactory() { + + private final ConfigUtil m_configUtil = ApolloInjector.getInstance(ConfigUtil.class); + @Override public Config create(String namespace) { return config; } + @Override + public Config create(String appId, String namespace) { + if(!StringUtils.equals(appId, m_configUtil.getAppId())){ + throw new IllegalArgumentException("appId not match"); + } + return config; + } + @Override public ConfigFile createConfigFile(String namespace, ConfigFileFormat configFileFormat) { return null; } + @Override + public ConfigFile createConfigFile(String appId, String namespace, ConfigFileFormat configFileFormat) { + return null; + } + }); } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfig.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfig.java index 7ce41dca..ee50908f 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfig.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfig.java @@ -454,7 +454,7 @@ protected void clearConfigCache() { /** * @param changes map's key is config property's key */ - protected void fireConfigChange(String namespace, Map changes) { + protected void fireConfigChange(String appId, String namespace, Map changes) { final Set changedKeys = changes.keySet(); final List listeners = this.findMatchedConfigChangeListeners(changedKeys); @@ -462,7 +462,7 @@ protected void fireConfigChange(String namespace, Map chan for (ConfigChangeListener listener : listeners) { Set interestedChangedKeys = resolveInterestedChangedKeys(listener, changedKeys); InterestedConfigChangeEvent interestedConfigChangeEvent = new InterestedConfigChangeEvent( - namespace, changes, interestedChangedKeys); + appId, namespace, changes, interestedChangedKeys); this.notifyAsync(listener, interestedConfigChangeEvent); } } @@ -567,7 +567,7 @@ private Set resolveInterestedChangedKeys(ConfigChangeListener configChan return Collections.unmodifiableSet(interestedChangedKeys); } - List calcPropertyChanges(String namespace, Properties previous, + List calcPropertyChanges(String appId, String namespace, Properties previous, Properties current) { if (previous == null) { previous = propertiesFactory.getPropertiesInstance(); @@ -587,12 +587,12 @@ List calcPropertyChanges(String namespace, Properties previous, List changes = Lists.newArrayList(); for (String newKey : newKeys) { - changes.add(new ConfigChange(namespace, newKey, null, current.getProperty(newKey), + changes.add(new ConfigChange(appId, namespace, newKey, null, current.getProperty(newKey), PropertyChangeType.ADDED)); } for (String removedKey : removedKeys) { - changes.add(new ConfigChange(namespace, removedKey, previous.getProperty(removedKey), null, + changes.add(new ConfigChange(appId, namespace, removedKey, previous.getProperty(removedKey), null, PropertyChangeType.DELETED)); } @@ -602,7 +602,7 @@ List calcPropertyChanges(String namespace, Properties previous, if (Objects.equal(previousValue, currentValue)) { continue; } - changes.add(new ConfigChange(namespace, commonKey, previousValue, currentValue, + changes.add(new ConfigChange(appId, namespace, commonKey, previousValue, currentValue, PropertyChangeType.MODIFIED)); } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfigFile.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfigFile.java index 3a1c0df0..5f2bc09f 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfigFile.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfigFile.java @@ -45,6 +45,7 @@ public abstract class AbstractConfigFile implements ConfigFile, RepositoryChange private static final Logger logger = DeferredLoggerFactory.getLogger(AbstractConfigFile.class); private static ExecutorService m_executorService; protected final ConfigRepository m_configRepository; + protected final String m_appId; protected final String m_namespace; protected final AtomicReference m_configProperties; private final List m_listeners = Lists.newCopyOnWriteArrayList(); @@ -57,8 +58,9 @@ public abstract class AbstractConfigFile implements ConfigFile, RepositoryChange .create("ConfigFile", true)); } - public AbstractConfigFile(String namespace, ConfigRepository configRepository) { + public AbstractConfigFile(String appId, String namespace, ConfigRepository configRepository) { m_configRepository = configRepository; + m_appId = appId; m_namespace = namespace; m_configProperties = new AtomicReference<>(); propertiesFactory = ApolloInjector.getInstance(PropertiesFactory.class); @@ -80,6 +82,11 @@ private void initialize() { } } + @Override + public String getAppId() { + return m_appId; + } + @Override public String getNamespace() { return m_namespace; @@ -89,6 +96,11 @@ public String getNamespace() { @Override public synchronized void onRepositoryChange(String namespace, Properties newProperties) { + this.onRepositoryChange(m_appId, m_namespace, newProperties); + } + + @Override + public synchronized void onRepositoryChange(String appId, String namespace, Properties newProperties) { if (newProperties.equals(m_configProperties.get())) { return; } @@ -110,7 +122,7 @@ public synchronized void onRepositoryChange(String namespace, Properties newProp changeType = PropertyChangeType.DELETED; } - this.fireConfigChange(new ConfigFileChangeEvent(m_namespace, oldValue, newValue, changeType)); + this.fireConfigChange(new ConfigFileChangeEvent(m_appId, m_namespace, oldValue, newValue, changeType)); Tracer.logEvent("Apollo.Client.ConfigChanges", m_namespace); } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfigRepository.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfigRepository.java index b4505297..9b0a790c 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfigRepository.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfigRepository.java @@ -63,10 +63,10 @@ public void removeChangeListener(RepositoryChangeListener listener) { m_listeners.remove(listener); } - protected void fireRepositoryChange(String namespace, Properties newProperties) { + protected void fireRepositoryChange(String appId, String namespace, Properties newProperties) { for (RepositoryChangeListener listener : m_listeners) { try { - listener.onRepositoryChange(namespace, newProperties); + listener.onRepositoryChange(appId, namespace, newProperties); } catch (Throwable ex) { Tracer.logError(ex); logger.error("Failed to invoke repository change listener {}", listener.getClass(), ex); diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/ConfigManager.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/ConfigManager.java index 0fedcbea..d275eed0 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/ConfigManager.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/ConfigManager.java @@ -31,6 +31,14 @@ public interface ConfigManager { */ Config getConfig(String namespace); + /** + * Get the config instance for the namespace and appId specified. + * @param appId the appId + * @param namespace the namespace + * @return the config instance for the appId and namespace + */ + Config getConfig(String appId,String namespace); + /** * Get the config file instance for the namespace specified. * @param namespace the namespace @@ -38,4 +46,13 @@ public interface ConfigManager { * @return the config file instance for the namespace */ ConfigFile getConfigFile(String namespace, ConfigFileFormat configFileFormat); + + /** + * Get the config file instance for the namespace specified. + * @param appId the appId + * @param namespace the namespace + * @param configFileFormat the config file format + * @return the config file instance for the appId and namespace + */ + ConfigFile getConfigFile(String appId, String namespace, ConfigFileFormat configFileFormat); } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultConfig.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultConfig.java index 750abd0e..f9c8fb59 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultConfig.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultConfig.java @@ -16,8 +16,11 @@ */ package com.ctrip.framework.apollo.internals; +import com.ctrip.framework.apollo.build.ApolloInjector; import com.ctrip.framework.apollo.core.utils.DeferredLoggerFactory; +import com.ctrip.framework.apollo.core.utils.StringUtils; import com.ctrip.framework.apollo.enums.ConfigSourceType; +import com.ctrip.framework.apollo.util.ConfigUtil; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import java.io.IOException; @@ -46,6 +49,7 @@ public class DefaultConfig extends AbstractConfig implements RepositoryChangeListener { private static final Logger logger = DeferredLoggerFactory.getLogger(DefaultConfig.class); + private final String m_appId; private final String m_namespace; private final Properties m_resourceProperties; private final AtomicReference m_configProperties; @@ -61,8 +65,23 @@ public class DefaultConfig extends AbstractConfig implements RepositoryChangeLis * @param configRepository the config repository for this config instance */ public DefaultConfig(String namespace, ConfigRepository configRepository) { + this(null, namespace , configRepository); + } + + /** + * Constructor. + * + * @param appId the appId of this config instance + * @param namespace the namespace of this config instance + * @param configRepository the config repository for this config instance + */ + public DefaultConfig(String appId, String namespace, ConfigRepository configRepository) { + if (appId == null) { + appId = ApolloInjector.getInstance(ConfigUtil.class).getAppId(); + } + m_appId = appId; m_namespace = namespace; - m_resourceProperties = loadFromResource(m_namespace); + m_resourceProperties = loadFromResource(m_appId, m_namespace); m_configRepository = configRepository; m_configProperties = new AtomicReference<>(); m_warnLogRateLimiter = RateLimiter.create(0.017); // 1 warning log output per minute @@ -218,6 +237,11 @@ private Set stringPropertyNames(Properties properties) { @Override public synchronized void onRepositoryChange(String namespace, Properties newProperties) { + this.onRepositoryChange(m_appId, m_namespace, newProperties); + } + + @Override + public synchronized void onRepositoryChange(String appId, String namespace, Properties newProperties) { if (newProperties.equals(m_configProperties.get())) { return; } @@ -234,7 +258,7 @@ public synchronized void onRepositoryChange(String namespace, Properties newProp return; } - this.fireConfigChange(m_namespace, actualChanges); + this.fireConfigChange(m_appId, m_namespace, actualChanges); Tracer.logEvent("Apollo.Client.ConfigChanges", m_namespace); } @@ -247,7 +271,7 @@ private void updateConfig(Properties newConfigProperties, ConfigSourceType sourc private Map updateAndCalcConfigChanges(Properties newConfigProperties, ConfigSourceType sourceType) { List configChanges = - calcPropertyChanges(m_namespace, m_configProperties.get(), newConfigProperties); + calcPropertyChanges(m_appId, m_namespace, m_configProperties.get(), newConfigProperties); ImmutableMap.Builder actualChanges = new ImmutableMap.Builder<>(); @@ -298,11 +322,17 @@ private Map updateAndCalcConfigChanges(Properties newConfi return actualChanges.build(); } - private Properties loadFromResource(String namespace) { - String name = String.format("META-INF/config/%s.properties", namespace); + private Properties loadFromResource(String appId, String namespace) { + String name = String.format("META-INF/config/%s+%s.properties", appId, namespace); InputStream in = ClassLoaderUtil.getLoader().getResourceAsStream(name); Properties properties = null; + if (StringUtils.equals(ApolloInjector.getInstance(ConfigUtil.class).getAppId(), appId) + && in == null) { + name = String.format("META-INF/config/%s.properties", namespace); + in = ClassLoaderUtil.getLoader().getResourceAsStream(name); + } + if (in != null) { properties = propertiesFactory.getPropertiesInstance(); @@ -310,7 +340,7 @@ private Properties loadFromResource(String namespace) { properties.load(in); } catch (IOException ex) { Tracer.logError(ex); - logger.error("Load resource config for namespace {} failed", namespace, ex); + logger.error("Load resource config for appId {} namespace {} failed", appId, namespace, ex); } finally { try { in.close(); diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultConfigManager.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultConfigManager.java index e897b6f7..e35a6d5d 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultConfigManager.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultConfigManager.java @@ -24,7 +24,11 @@ import com.ctrip.framework.apollo.core.enums.ConfigFileFormat; import com.ctrip.framework.apollo.spi.ConfigFactory; import com.ctrip.framework.apollo.spi.ConfigFactoryManager; +import com.ctrip.framework.apollo.util.ConfigUtil; +import com.google.common.collect.HashBasedTable; import com.google.common.collect.Maps; +import com.google.common.collect.Table; +import com.google.common.collect.Tables; /** * @author Jason Song(song_s@ctrip.com) @@ -32,51 +36,68 @@ public class DefaultConfigManager implements ConfigManager { private ConfigFactoryManager m_factoryManager; - private Map m_configs = Maps.newConcurrentMap(); + private ConfigUtil m_configUtil; + + private Table m_configs = Tables.synchronizedTable(HashBasedTable.create()); + private Map m_configLocks = Maps.newConcurrentMap(); - private Map m_configFiles = Maps.newConcurrentMap(); + + private Table m_configFiles = HashBasedTable.create(); + private Map m_configFileLocks = Maps.newConcurrentMap(); + public DefaultConfigManager() { m_factoryManager = ApolloInjector.getInstance(ConfigFactoryManager.class); + m_configUtil = ApolloInjector.getInstance(ConfigUtil.class); } @Override public Config getConfig(String namespace) { - Config config = m_configs.get(namespace); + return getConfig(m_configUtil.getAppId(), namespace); + } + + @Override + public Config getConfig(String appId, String namespace) { + Config config = m_configs.get(appId, namespace); if (config == null) { - Object lock = m_configLocks.computeIfAbsent(namespace, key -> new Object()); + Object lock = m_configLocks.computeIfAbsent(String.format("%s.%s", appId, namespace), key -> new Object()); synchronized (lock) { - config = m_configs.get(namespace); + config = m_configs.get(appId, namespace); if (config == null) { - ConfigFactory factory = m_factoryManager.getFactory(namespace); + ConfigFactory factory = m_factoryManager.getFactory(appId, namespace); - config = factory.create(namespace); - m_configs.put(namespace, config); + config = factory.create(appId, namespace); + m_configs.put(appId, namespace, config); } } } - return config; } @Override public ConfigFile getConfigFile(String namespace, ConfigFileFormat configFileFormat) { + return getConfigFile(m_configUtil.getAppId(), namespace, configFileFormat); + } + + @Override + public ConfigFile getConfigFile(String appId, String namespace, ConfigFileFormat configFileFormat) { String namespaceFileName = String.format("%s.%s", namespace, configFileFormat.getValue()); - ConfigFile configFile = m_configFiles.get(namespaceFileName); + String lockNamespaceFileName = String.format("%s+%s.%s", appId, namespace, configFileFormat.getValue()); + ConfigFile configFile = m_configFiles.get(appId, namespaceFileName); if (configFile == null) { - Object lock = m_configFileLocks.computeIfAbsent(namespaceFileName, key -> new Object()); + Object lock = m_configFileLocks.computeIfAbsent(lockNamespaceFileName, key -> new Object()); synchronized (lock) { - configFile = m_configFiles.get(namespaceFileName); + configFile = m_configFiles.get(appId, namespaceFileName); if (configFile == null) { - ConfigFactory factory = m_factoryManager.getFactory(namespaceFileName); + ConfigFactory factory = m_factoryManager.getFactory(appId, namespaceFileName); - configFile = factory.createConfigFile(namespaceFileName, configFileFormat); - m_configFiles.put(namespaceFileName, configFile); + configFile = factory.createConfigFile(appId, namespaceFileName, configFileFormat); + m_configFiles.put(appId, namespaceFileName, configFile); } } } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/InterestedConfigChangeEvent.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/InterestedConfigChangeEvent.java index 2d336507..e72ed13a 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/InterestedConfigChangeEvent.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/InterestedConfigChangeEvent.java @@ -41,9 +41,9 @@ class InterestedConfigChangeEvent extends ConfigChangeEvent { */ private final Set m_interestedChangedKeys; - public InterestedConfigChangeEvent(String namespace, + public InterestedConfigChangeEvent(String appId, String namespace, Map changes, Set interestedChangedKeys) { - super(namespace, changes); + super(appId, namespace, changes); this.m_interestedChangedKeys = interestedChangedKeys; } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/JsonConfigFile.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/JsonConfigFile.java index 80befc92..f1a04c75 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/JsonConfigFile.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/JsonConfigFile.java @@ -22,9 +22,9 @@ * @author Jason Song(song_s@ctrip.com) */ public class JsonConfigFile extends PlainTextConfigFile { - public JsonConfigFile(String namespace, + public JsonConfigFile(String appId, String namespace, ConfigRepository configRepository) { - super(namespace, configRepository); + super(appId, namespace, configRepository); } @Override diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepository.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepository.java index 1820fd1a..f9e119f6 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepository.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepository.java @@ -49,6 +49,7 @@ public class LocalFileConfigRepository extends AbstractConfigRepository implements RepositoryChangeListener { private static final Logger logger = DeferredLoggerFactory.getLogger(LocalFileConfigRepository.class); private static final String CONFIG_DIR = "/config-cache"; + private final String m_appId; private final String m_namespace; private File m_baseDir; private final ConfigUtil m_configUtil; @@ -62,11 +63,12 @@ public class LocalFileConfigRepository extends AbstractConfigRepository * * @param namespace the namespace */ - public LocalFileConfigRepository(String namespace) { - this(namespace, null); + public LocalFileConfigRepository(String appId, String namespace) { + this(appId, namespace, null); } - public LocalFileConfigRepository(String namespace, ConfigRepository upstream) { + public LocalFileConfigRepository(String appId, String namespace, ConfigRepository upstream) { + m_appId = appId; m_namespace = namespace; m_configUtil = ApolloInjector.getInstance(ConfigUtil.class); this.setLocalCacheDir(findLocalCacheDir(), false); @@ -83,7 +85,7 @@ void setLocalCacheDir(File baseDir, boolean syncImmediately) { private File findLocalCacheDir() { try { - String defaultCacheDir = m_configUtil.getDefaultLocalCacheDir(); + String defaultCacheDir = m_configUtil.getDefaultLocalCacheDir(m_appId); Path path = Paths.get(defaultCacheDir); if (!Files.exists(path)) { Files.createDirectories(path); @@ -128,13 +130,18 @@ public ConfigSourceType getSourceType() { @Override public void onRepositoryChange(String namespace, Properties newProperties) { + this.onRepositoryChange(m_appId, namespace, newProperties); + } + + @Override + public void onRepositoryChange(String appId, String namespace, Properties newProperties) { if (newProperties.equals(m_fileProperties)) { return; } Properties newFileProperties = propertiesFactory.getPropertiesInstance(); newFileProperties.putAll(newProperties); updateFileProperties(newFileProperties, m_upstream.getSourceType()); - this.fireRepositoryChange(namespace, newProperties); + this.fireRepositoryChange(appId, namespace, newProperties); } @Override @@ -150,7 +157,7 @@ protected void sync() { Throwable exception = null; try { transaction.addData("Basedir", m_baseDir.getAbsolutePath()); - m_fileProperties = this.loadFromLocalCacheFile(m_baseDir, m_namespace); + m_fileProperties = this.loadFromLocalCacheFile(m_baseDir, m_appId, m_namespace); m_sourceType = ConfigSourceType.LOCAL; transaction.setStatus(Transaction.SUCCESS); } catch (Throwable ex) { @@ -191,13 +198,13 @@ private synchronized void updateFileProperties(Properties newProperties, ConfigS return; } this.m_fileProperties = newProperties; - persistLocalCacheFile(m_baseDir, m_namespace); + persistLocalCacheFile(m_baseDir, m_appId, m_namespace); } - private Properties loadFromLocalCacheFile(File baseDir, String namespace) throws IOException { + private Properties loadFromLocalCacheFile(File baseDir, String appId, String namespace) throws IOException { Preconditions.checkNotNull(baseDir, "Basedir cannot be null"); - File file = assembleLocalCacheFile(baseDir, namespace); + File file = assembleLocalCacheFile(baseDir, appId, namespace); Properties properties = null; if (file.isFile() && file.canRead()) { @@ -229,11 +236,11 @@ private Properties loadFromLocalCacheFile(File baseDir, String namespace) throws return properties; } - void persistLocalCacheFile(File baseDir, String namespace) { + void persistLocalCacheFile(File baseDir, String appId, String namespace) { if (baseDir == null) { return; } - File file = assembleLocalCacheFile(baseDir, namespace); + File file = assembleLocalCacheFile(baseDir, appId, namespace); OutputStream out = null; @@ -287,10 +294,10 @@ private void checkLocalConfigCacheDir(File baseDir) { } } - File assembleLocalCacheFile(File baseDir, String namespace) { + File assembleLocalCacheFile(File baseDir, String appId, String namespace) { String fileName = String.format("%s.properties", Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR) - .join(m_configUtil.getAppId(), m_configUtil.getCluster(), namespace)); + .join(appId, m_configUtil.getCluster(), namespace)); return new File(baseDir, fileName); } } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/PlainTextConfigFile.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/PlainTextConfigFile.java index f5f05d0e..ae1c197c 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/PlainTextConfigFile.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/PlainTextConfigFile.java @@ -24,8 +24,8 @@ */ public abstract class PlainTextConfigFile extends AbstractConfigFile { - public PlainTextConfigFile(String namespace, ConfigRepository configRepository) { - super(namespace, configRepository); + public PlainTextConfigFile(String appId, String namespace, ConfigRepository configRepository) { + super(appId, namespace, configRepository); } @Override diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/PropertiesCompatibleFileConfigRepository.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/PropertiesCompatibleFileConfigRepository.java index e505d18a..b58fbe48 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/PropertiesCompatibleFileConfigRepository.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/PropertiesCompatibleFileConfigRepository.java @@ -43,7 +43,7 @@ protected synchronized void sync() { if (cachedProperties != current) { cachedProperties = current; - this.fireRepositoryChange(configFile.getNamespace(), cachedProperties); + this.fireRepositoryChange(configFile.getAppId(), configFile.getNamespace(), cachedProperties); } } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/PropertiesConfigFile.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/PropertiesConfigFile.java index 205941a7..6109417a 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/PropertiesConfigFile.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/PropertiesConfigFile.java @@ -36,9 +36,9 @@ public class PropertiesConfigFile extends AbstractConfigFile implements protected AtomicReference m_contentCache; - public PropertiesConfigFile(String namespace, + public PropertiesConfigFile(String appId, String namespace, ConfigRepository configRepository) { - super(namespace, configRepository); + super(appId, namespace, configRepository); m_contentCache = new AtomicReference<>(); } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RemoteConfigLongPollService.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RemoteConfigLongPollService.java index 59806b2a..5246782f 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RemoteConfigLongPollService.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RemoteConfigLongPollService.java @@ -39,11 +39,14 @@ import com.ctrip.framework.foundation.internals.ServiceBootstrap; import com.google.common.base.Joiner; import com.google.common.base.Strings; +import com.google.common.collect.HashBasedTable; import com.google.common.collect.HashMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; +import com.google.common.collect.Table; +import com.google.common.collect.Tables; import com.google.common.escape.Escaper; import com.google.common.net.UrlEscapers; import com.google.common.reflect.TypeToken; @@ -52,11 +55,7 @@ import java.lang.reflect.Type; import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -76,9 +75,9 @@ public class RemoteConfigLongPollService { private final AtomicBoolean m_longPollingStopped; private SchedulePolicy m_longPollFailSchedulePolicyInSecond; private RateLimiter m_longPollRateLimiter; - private final AtomicBoolean m_longPollStarted; - private final Multimap m_longPollNamespaces; - private final ConcurrentMap m_notifications; + private final ConcurrentHashMap m_longPollStarted; + private final Map> m_longPollNamespaces; + private final Table m_notifications; private final Map m_remoteNotificationMessages;//namespaceName -> watchedKey -> notificationId private Type m_responseType; private static final Gson GSON = new Gson(); @@ -94,12 +93,11 @@ public class RemoteConfigLongPollService { public RemoteConfigLongPollService() { m_longPollFailSchedulePolicyInSecond = new ExponentialSchedulePolicy(1, 120); //in second m_longPollingStopped = new AtomicBoolean(false); - m_longPollingService = Executors.newSingleThreadExecutor( + m_longPollingService = Executors.newCachedThreadPool( ApolloThreadFactory.create("RemoteConfigLongPollService", true)); - m_longPollStarted = new AtomicBoolean(false); - m_longPollNamespaces = - Multimaps.synchronizedSetMultimap(HashMultimap.create()); - m_notifications = Maps.newConcurrentMap(); + m_longPollStarted = new ConcurrentHashMap<>(); + m_longPollNamespaces = Maps.newConcurrentMap(); + m_notifications = Tables.synchronizedTable(HashBasedTable.create()); m_remoteNotificationMessages = Maps.newConcurrentMap(); m_responseType = new TypeToken>() { }.getType(); @@ -109,25 +107,34 @@ public RemoteConfigLongPollService() { m_longPollRateLimiter = RateLimiter.create(m_configUtil.getLongPollQPS()); } - public boolean submit(String namespace, RemoteConfigRepository remoteConfigRepository) { - boolean added = m_longPollNamespaces.put(namespace, remoteConfigRepository); - m_notifications.putIfAbsent(namespace, INIT_NOTIFICATION_ID); - if (!m_longPollStarted.get()) { - startLongPolling(); + public boolean submit(String appId, String namespace, RemoteConfigRepository remoteConfigRepository) { + Multimap repositoryMultimap = m_longPollNamespaces.get( + appId); + boolean result = false; + if(repositoryMultimap == null){ + repositoryMultimap = Multimaps.synchronizedSetMultimap(HashMultimap.create()); + result = repositoryMultimap.put(namespace, remoteConfigRepository); + m_longPollNamespaces.put(appId, repositoryMultimap); + }else{ + result = repositoryMultimap.put(namespace, remoteConfigRepository); } - return added; + m_notifications.put(appId, namespace, INIT_NOTIFICATION_ID); + if (m_longPollStarted.get(appId) == null) { + startLongPolling(appId); + } + return result; } - private void startLongPolling() { - if (!m_longPollStarted.compareAndSet(false, true)) { + private void startLongPolling(String sysAppId) { + if (Boolean.TRUE.equals(m_longPollStarted.putIfAbsent(sysAppId, true))) { //already started return; } try { - final String appId = m_configUtil.getAppId(); + final String appId = sysAppId; final String cluster = m_configUtil.getCluster(); final String dataCenter = m_configUtil.getDataCenter(); - final String secret = m_configUtil.getAccessKeySecret(); + final String secret = m_configUtil.getAccessKeySecret(appId); final long longPollingInitialDelayInMills = m_configUtil.getLongPollingInitialDelayInMills(); m_longPollingService.submit(new Runnable() { @Override @@ -144,7 +151,7 @@ public void run() { } }); } catch (Throwable ex) { - m_longPollStarted.set(false); + m_longPollStarted.remove(sysAppId); ApolloConfigException exception = new ApolloConfigException("Schedule long polling refresh failed", ex); Tracer.logError(exception); @@ -175,7 +182,7 @@ private void doLongPollingRefresh(String appId, String cluster, String dataCente url = assembleLongPollRefreshUrl(lastServiceDto.getHomepageUrl(), appId, cluster, dataCenter, - m_notifications); + m_notifications.row(appId)); logger.debug("Long polling from {}", url); @@ -193,10 +200,10 @@ private void doLongPollingRefresh(String appId, String cluster, String dataCente logger.debug("Long polling response: {}, url: {}", response.getStatusCode(), url); if (response.getStatusCode() == 200 && response.getBody() != null) { - updateNotifications(response.getBody()); + updateNotifications(appId, response.getBody()); updateRemoteNotifications(response.getBody()); transaction.addData("Result", response.getBody().toString()); - notify(lastServiceDto, response.getBody()); + notify(appId, lastServiceDto, response.getBody()); } //try to load balance @@ -214,7 +221,7 @@ private void doLongPollingRefresh(String appId, String cluster, String dataCente long sleepTimeInSecond = m_longPollFailSchedulePolicyInSecond.fail(); logger.warn( "Long polling failed, will retry in {} seconds. appId: {}, cluster: {}, namespaces: {}, long polling url: {}, reason: {}", - sleepTimeInSecond, appId, cluster, assembleNamespaces(), url, ExceptionUtil.getDetailMessage(ex)); + sleepTimeInSecond, appId, cluster, assembleNamespaces(appId), url, ExceptionUtil.getDetailMessage(ex)); try { TimeUnit.SECONDS.sleep(sleepTimeInSecond); } catch (InterruptedException ie) { @@ -226,7 +233,7 @@ private void doLongPollingRefresh(String appId, String cluster, String dataCente } } - private void notify(ServiceDTO lastServiceDto, List notifications) { + private void notify(String appId, ServiceDTO lastServiceDto, List notifications) { if (notifications == null || notifications.isEmpty()) { return; } @@ -234,12 +241,12 @@ private void notify(ServiceDTO lastServiceDto, List no String namespaceName = notification.getNamespaceName(); //create a new list to avoid ConcurrentModificationException List toBeNotified = - Lists.newArrayList(m_longPollNamespaces.get(namespaceName)); + Lists.newArrayList(m_longPollNamespaces.get(appId).get(namespaceName)); ApolloNotificationMessages originalMessages = m_remoteNotificationMessages.get(namespaceName); ApolloNotificationMessages remoteMessages = originalMessages == null ? null : originalMessages.clone(); //since .properties are filtered out by default, so we need to check if there is any listener for it toBeNotified.addAll(m_longPollNamespaces - .get(String.format("%s.%s", namespaceName, ConfigFileFormat.Properties.getValue()))); + .get(appId).get(String.format("%s.%s", namespaceName, ConfigFileFormat.Properties.getValue()))); for (RemoteConfigRepository remoteConfigRepository : toBeNotified) { try { remoteConfigRepository.onLongPollNotified(lastServiceDto, remoteMessages); @@ -250,20 +257,20 @@ private void notify(ServiceDTO lastServiceDto, List no } } - private void updateNotifications(List deltaNotifications) { + private void updateNotifications(String appId, List deltaNotifications) { for (ApolloConfigNotification notification : deltaNotifications) { if (Strings.isNullOrEmpty(notification.getNamespaceName())) { continue; } String namespaceName = notification.getNamespaceName(); - if (m_notifications.containsKey(namespaceName)) { - m_notifications.put(namespaceName, notification.getNotificationId()); + if (m_notifications.contains(appId, namespaceName)) { + m_notifications.put(appId, namespaceName, notification.getNotificationId()); } //since .properties are filtered out by default, so we need to check if there is notification with .properties suffix String namespaceNameWithPropertiesSuffix = String.format("%s.%s", namespaceName, ConfigFileFormat.Properties.getValue()); - if (m_notifications.containsKey(namespaceNameWithPropertiesSuffix)) { - m_notifications.put(namespaceNameWithPropertiesSuffix, notification.getNotificationId()); + if (m_notifications.contains(appId, namespaceNameWithPropertiesSuffix)) { + m_notifications.put(appId, namespaceNameWithPropertiesSuffix, notification.getNotificationId()); } } } @@ -289,8 +296,8 @@ private void updateRemoteNotifications(List deltaNotif } } - private String assembleNamespaces() { - return STRING_JOINER.join(m_longPollNamespaces.keySet()); + private String assembleNamespaces(String appId) { + return STRING_JOINER.join(m_longPollNamespaces.get(appId).keySet()); } String assembleLongPollRefreshUrl(String uri, String appId, String cluster, String dataCenter, diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RemoteConfigRepository.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RemoteConfigRepository.java index c3aab684..29be4ac4 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RemoteConfigRepository.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RemoteConfigRepository.java @@ -72,6 +72,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository { private final ConfigUtil m_configUtil; private final RemoteConfigLongPollService remoteConfigLongPollService; private volatile AtomicReference m_configCache; + private final String m_appId; private final String m_namespace; private final static ScheduledExecutorService m_executorService; private final AtomicReference m_longPollServiceDto; @@ -89,9 +90,11 @@ public class RemoteConfigRepository extends AbstractConfigRepository { /** * Constructor. * + * @param appId the appId * @param namespace the namespace */ - public RemoteConfigRepository(String namespace) { + public RemoteConfigRepository(String appId, String namespace) { + m_appId = appId; m_namespace = namespace; m_configCache = new AtomicReference<>(); m_configUtil = ApolloInjector.getInstance(ConfigUtil.class); @@ -154,7 +157,7 @@ protected synchronized void sync() { if (previous != current) { logger.debug("Remote Config refreshed!"); m_configCache.set(current); - this.fireRepositoryChange(m_namespace, this.getConfig()); + this.fireRepositoryChange(m_appId, m_namespace, this.getConfig()); } if (current != null) { @@ -185,10 +188,10 @@ private ApolloConfig loadApolloConfig() { } catch (InterruptedException e) { } } - String appId = m_configUtil.getAppId(); + String appId = this.m_appId; String cluster = m_configUtil.getCluster(); String dataCenter = m_configUtil.getDataCenter(); - String secret = m_configUtil.getAccessKeySecret(); + String secret = m_configUtil.getAccessKeySecret(appId); Tracer.logEvent("Apollo.Client.ConfigMeta", STRING_JOINER.join(appId, cluster, m_namespace)); int maxRetries = m_configNeedForceRefresh.get() ? 2 : 1; long onErrorSleepTime = 0; // 0 means no sleep @@ -330,7 +333,7 @@ String assembleQueryConfigUrl(String uri, String appId, String cluster, String n } private void scheduleLongPollingRefresh() { - remoteConfigLongPollService.submit(m_namespace, this); + remoteConfigLongPollService.submit(m_appId, m_namespace, this); } public void onLongPollNotified(ServiceDTO longPollNotifiedServiceDto, ApolloNotificationMessages remoteMessages) { diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RepositoryChangeListener.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RepositoryChangeListener.java index 77334d96..df58fd31 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RepositoryChangeListener.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RepositoryChangeListener.java @@ -28,4 +28,12 @@ public interface RepositoryChangeListener { * @param newProperties the properties after change */ void onRepositoryChange(String namespace, Properties newProperties); + + /** + * Invoked when config repository changes. + * @param appId the appId of this repository change + * @param namespace the namespace of this repository change + * @param newProperties the properties after change + */ + void onRepositoryChange(String appId, String namespace, Properties newProperties); } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/SimpleConfig.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/SimpleConfig.java index c8897bbd..c3ca9688 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/SimpleConfig.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/SimpleConfig.java @@ -16,6 +16,7 @@ */ package com.ctrip.framework.apollo.internals; +import com.ctrip.framework.apollo.build.ApolloInjector; import com.ctrip.framework.apollo.enums.ConfigSourceType; import java.util.Collections; import java.util.List; @@ -23,6 +24,7 @@ import java.util.Properties; import java.util.Set; +import com.ctrip.framework.apollo.util.ConfigUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,11 +39,14 @@ */ public class SimpleConfig extends AbstractConfig implements RepositoryChangeListener { private static final Logger logger = LoggerFactory.getLogger(SimpleConfig.class); + private final String m_appId; private final String m_namespace; private final ConfigRepository m_configRepository; private volatile Properties m_configProperties; private volatile ConfigSourceType m_sourceType = ConfigSourceType.NONE; + private static ConfigUtil m_configUtil = ApolloInjector.getInstance(ConfigUtil.class); + /** * Constructor. * @@ -49,6 +54,21 @@ public class SimpleConfig extends AbstractConfig implements RepositoryChangeList * @param configRepository the config repository for this config instance */ public SimpleConfig(String namespace, ConfigRepository configRepository) { + this(null, namespace, configRepository); + } + + /** + * Constructor. + * + * @param appId the appId for this config instance + * @param namespace the namespace for this config instance + * @param configRepository the config repository for this config instance + */ + public SimpleConfig(String appId, String namespace, ConfigRepository configRepository) { + if (appId == null) { + appId = ApolloInjector.getInstance(ConfigUtil.class).getAppId(); + } + m_appId = appId; m_namespace = namespace; m_configRepository = configRepository; this.initialize(); @@ -93,13 +113,18 @@ public ConfigSourceType getSourceType() { @Override public synchronized void onRepositoryChange(String namespace, Properties newProperties) { + this.onRepositoryChange(m_appId, namespace, newProperties); + } + + @Override + public synchronized void onRepositoryChange(String appId, String namespace, Properties newProperties) { if (newProperties.equals(m_configProperties)) { return; } Properties newConfigProperties = propertiesFactory.getPropertiesInstance(); newConfigProperties.putAll(newProperties); - List changes = calcPropertyChanges(namespace, m_configProperties, newConfigProperties); + List changes = calcPropertyChanges(appId, namespace, m_configProperties, newConfigProperties); Map changeMap = Maps.uniqueIndex(changes, new Function() { @Override @@ -111,7 +136,7 @@ public String apply(ConfigChange input) { updateConfig(newConfigProperties, m_configRepository.getSourceType()); clearConfigCache(); - this.fireConfigChange(m_namespace, changeMap); + this.fireConfigChange(appId, m_namespace, changeMap); Tracer.logEvent("Apollo.Client.ConfigChanges", m_namespace); } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/TxtConfigFile.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/TxtConfigFile.java index dcffbcd6..c580f599 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/TxtConfigFile.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/TxtConfigFile.java @@ -20,8 +20,8 @@ public class TxtConfigFile extends PlainTextConfigFile { - public TxtConfigFile(String namespace, ConfigRepository configRepository) { - super(namespace, configRepository); + public TxtConfigFile(String appId, String namespace, ConfigRepository configRepository) { + super(appId, namespace, configRepository); } @Override diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/XmlConfigFile.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/XmlConfigFile.java index 8300a836..67bdf7fc 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/XmlConfigFile.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/XmlConfigFile.java @@ -22,9 +22,9 @@ * @author Jason Song(song_s@ctrip.com) */ public class XmlConfigFile extends PlainTextConfigFile { - public XmlConfigFile(String namespace, + public XmlConfigFile(String appId, String namespace, ConfigRepository configRepository) { - super(namespace, configRepository); + super(appId, namespace, configRepository); } @Override diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/YamlConfigFile.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/YamlConfigFile.java index 3443d582..e81de6c9 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/YamlConfigFile.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/YamlConfigFile.java @@ -36,8 +36,8 @@ public class YamlConfigFile extends PlainTextConfigFile implements PropertiesCom private static final Logger logger = LoggerFactory.getLogger(YamlConfigFile.class); private volatile Properties cachedProperties; - public YamlConfigFile(String namespace, ConfigRepository configRepository) { - super(namespace, configRepository); + public YamlConfigFile(String appId, String namespace, ConfigRepository configRepository) { + super(appId, namespace, configRepository); tryTransformToProperties(); } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/YmlConfigFile.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/YmlConfigFile.java index 5e922a53..838aae88 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/YmlConfigFile.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/YmlConfigFile.java @@ -22,8 +22,8 @@ * @author Jason Song(song_s@ctrip.com) */ public class YmlConfigFile extends YamlConfigFile { - public YmlConfigFile(String namespace, ConfigRepository configRepository) { - super(namespace, configRepository); + public YmlConfigFile(String appId, String namespace, ConfigRepository configRepository) { + super(appId, namespace, configRepository); } @Override diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/model/ConfigChange.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/model/ConfigChange.java index bcc6e4e6..19b82f60 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/model/ConfigChange.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/model/ConfigChange.java @@ -24,6 +24,7 @@ * @author Jason Song(song_s@ctrip.com) */ public class ConfigChange { + private final String appId; private final String namespace; private final String propertyName; private String oldValue; @@ -32,21 +33,22 @@ public class ConfigChange { /** * Constructor. + * @param appId the appId of the key * @param namespace the namespace of the key * @param propertyName the key whose value is changed * @param oldValue the value before change * @param newValue the value after change * @param changeType the change type */ - public ConfigChange(String namespace, String propertyName, String oldValue, String newValue, + public ConfigChange(String appId, String namespace, String propertyName, String oldValue, String newValue, PropertyChangeType changeType) { + this.appId = appId; this.namespace = namespace; this.propertyName = propertyName; this.oldValue = oldValue; this.newValue = newValue; this.changeType = changeType; } - public String getPropertyName() { return propertyName; } @@ -75,6 +77,10 @@ public void setChangeType(PropertyChangeType changeType) { this.changeType = changeType; } + public String getAppId() { + return appId; + } + public String getNamespace() { return namespace; } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/model/ConfigChangeEvent.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/model/ConfigChangeEvent.java index eddf003f..2e3563e9 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/model/ConfigChangeEvent.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/model/ConfigChangeEvent.java @@ -25,6 +25,7 @@ * @author Jason Song(song_s@ctrip.com) */ public class ConfigChangeEvent { + private final String m_appId; private final String m_namespace; private final Map m_changes; /** @@ -32,8 +33,9 @@ public class ConfigChangeEvent { * @param namespace the namespace of this change * @param changes the actual changes */ - public ConfigChangeEvent(String namespace, + public ConfigChangeEvent(String appId, String namespace, Map changes) { + this.m_appId = appId; this.m_namespace = namespace; this.m_changes = changes; } @@ -73,6 +75,14 @@ public boolean isChanged(String key) { return m_changes.containsKey(key); } + /** + * Get the appId of this change event. + * @return the namespace + */ + public String getAppId() { + return m_appId; + } + /** * Get the namespace of this change event. * @return the namespace diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/model/ConfigFileChangeEvent.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/model/ConfigFileChangeEvent.java index 4c3569bf..3025879c 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/model/ConfigFileChangeEvent.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/model/ConfigFileChangeEvent.java @@ -22,6 +22,8 @@ * @author Jason Song(song_s@ctrip.com) */ public class ConfigFileChangeEvent { + + private final String appId; private final String namespace; private final String oldValue; private final String newValue; @@ -30,19 +32,25 @@ public class ConfigFileChangeEvent { /** * Constructor. * + * @param appId the appId of the config file change event * @param namespace the namespace of the config file change event * @param oldValue the value before change * @param newValue the value after change * @param changeType the change type */ - public ConfigFileChangeEvent(String namespace, String oldValue, String newValue, + public ConfigFileChangeEvent(String appId, String namespace, String oldValue, String newValue, PropertyChangeType changeType) { + this.appId = appId; this.namespace = namespace; this.oldValue = oldValue; this.newValue = newValue; this.changeType = changeType; } + public String getAppId() { + return appId; + } + public String getNamespace() { return namespace; } @@ -62,7 +70,8 @@ public PropertyChangeType getChangeType() { @Override public String toString() { final StringBuilder sb = new StringBuilder("ConfigFileChangeEvent{"); - sb.append("namespace='").append(namespace).append('\''); + sb.append(", appId='").append(appId).append('\''); + sb.append(", namespace='").append(namespace).append('\''); sb.append(", oldValue='").append(oldValue).append('\''); sb.append(", newValue='").append(newValue).append('\''); sb.append(", changeType=").append(changeType); diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/ConfigFactory.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/ConfigFactory.java index da4223f8..c369aaeb 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/ConfigFactory.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/ConfigFactory.java @@ -32,10 +32,27 @@ public interface ConfigFactory { */ Config create(String namespace); + /** + * Create the config instance for the appId and namespace. + * + * @param appId the appId + * @param namespace the namespace + * @return the newly created config instance + */ + Config create(String appId, String namespace); + /** * Create the config file instance for the namespace * @param namespace the namespace * @return the newly created config file instance */ ConfigFile createConfigFile(String namespace, ConfigFileFormat configFileFormat); + + /** + * Create the config file instance for the appId and namespace. + * @param appId the appId + * @param namespace the namespace + * @return the newly created config file instance + */ + ConfigFile createConfigFile(String appId, String namespace, ConfigFileFormat configFileFormat); } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/ConfigFactoryManager.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/ConfigFactoryManager.java index 5d77a2bc..c1fbff73 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/ConfigFactoryManager.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/ConfigFactoryManager.java @@ -27,4 +27,12 @@ public interface ConfigFactoryManager { * @return the config factory for this namespace */ ConfigFactory getFactory(String namespace); + + /** + * Get the config factory for the namespace. + * + * @param namespace the namespace + * @return the config factory for this namespace + */ + ConfigFactory getFactory(String appId, String namespace); } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/ConfigRegistry.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/ConfigRegistry.java index 8e34df6d..0632ae44 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/ConfigRegistry.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/ConfigRegistry.java @@ -30,6 +30,15 @@ public interface ConfigRegistry { */ void register(String namespace, ConfigFactory factory); + /** + * Register the config factory for the namespace specified. + * + * @param appId the appId + * @param namespace the namespace + * @param factory the factory for this appId and namespace + */ + void register(String appId, String namespace, ConfigFactory factory); + /** * Get the registered config factory for the namespace. * @@ -37,4 +46,13 @@ public interface ConfigRegistry { * @return the factory registered for this namespace */ ConfigFactory getFactory(String namespace); + + /** + * Get the registered config factory for the namespace. + * + * @param appId the appId + * @param namespace the namespace + * @return the factory registered for this appId and namespace + */ + ConfigFactory getFactory(String appId, String namespace); } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigFactory.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigFactory.java index 36c300f4..35af934d 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigFactory.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigFactory.java @@ -64,6 +64,11 @@ public DefaultConfigFactory() { @Override public Config create(String namespace) { + return this.create(m_configUtil.getAppId(), namespace); + } + + @Override + public Config create(String appId, String namespace) { ConfigFileFormat format = determineFileFormat(namespace); ConfigRepository configRepository = null; @@ -73,73 +78,79 @@ public Config create(String namespace) { // calling the method `createLocalConfigRepository(...)` is more suitable // for ConfigFileFormat.Properties if (ConfigFileFormat.isPropertiesCompatible(format) && - format != ConfigFileFormat.Properties) { - configRepository = createPropertiesCompatibleFileConfigRepository(namespace, format); + format != ConfigFileFormat.Properties) { + configRepository = createPropertiesCompatibleFileConfigRepository(appId, namespace, format); } else { - configRepository = createConfigRepository(namespace); + configRepository = createConfigRepository(appId, namespace); } logger.debug("Created a configuration repository of type [{}] for namespace [{}]", - configRepository.getClass().getName(), namespace); + configRepository.getClass().getName(), namespace); + + return this.createRepositoryConfig(appId, namespace, configRepository); + } - return this.createRepositoryConfig(namespace, configRepository); + @Override + public ConfigFile createConfigFile(String namespace, ConfigFileFormat configFileFormat) { + return this.createConfigFile(m_configUtil.getAppId(), namespace, configFileFormat); } - protected Config createRepositoryConfig(String namespace, ConfigRepository configRepository) { - return new DefaultConfig(namespace, configRepository); + protected Config createRepositoryConfig(String appId, String namespace, ConfigRepository configRepository) { + return new DefaultConfig(appId, namespace, configRepository); } @Override - public ConfigFile createConfigFile(String namespace, ConfigFileFormat configFileFormat) { - ConfigRepository configRepository = createConfigRepository(namespace); + public ConfigFile createConfigFile(String appId, String namespace, ConfigFileFormat configFileFormat) { + ConfigRepository configRepository = createConfigRepository(appId, namespace); switch (configFileFormat) { case Properties: - return new PropertiesConfigFile(namespace, configRepository); + return new PropertiesConfigFile(appId, namespace, configRepository); case XML: - return new XmlConfigFile(namespace, configRepository); + return new XmlConfigFile(appId, namespace, configRepository); case JSON: - return new JsonConfigFile(namespace, configRepository); + return new JsonConfigFile(appId, namespace, configRepository); case YAML: - return new YamlConfigFile(namespace, configRepository); + return new YamlConfigFile(appId, namespace, configRepository); case YML: - return new YmlConfigFile(namespace, configRepository); + return new YmlConfigFile(appId, namespace, configRepository); case TXT: - return new TxtConfigFile(namespace, configRepository); + return new TxtConfigFile(appId, namespace, configRepository); } return null; } - ConfigRepository createConfigRepository(String namespace) { + ConfigRepository createConfigRepository(String appId, String namespace) { if (m_configUtil.isPropertyFileCacheEnabled()) { - return createLocalConfigRepository(namespace); + return createLocalConfigRepository(appId, namespace); } - return createRemoteConfigRepository(namespace); + return createRemoteConfigRepository(appId, namespace); } /** * Creates a local repository for a given namespace * + * @param appId the appId of the repository * @param namespace the namespace of the repository * @return the newly created repository for the given namespace */ - LocalFileConfigRepository createLocalConfigRepository(String namespace) { + LocalFileConfigRepository createLocalConfigRepository(String appId, String namespace) { if (m_configUtil.isInLocalMode()) { logger.warn( "==== Apollo is in local mode! Won't pull configs from remote server for namespace {} ! ====", namespace); - return new LocalFileConfigRepository(namespace); + return new LocalFileConfigRepository(appId, namespace); } - return new LocalFileConfigRepository(namespace, createRemoteConfigRepository(namespace)); + return new LocalFileConfigRepository(appId, namespace, createRemoteConfigRepository(appId, namespace)); } - RemoteConfigRepository createRemoteConfigRepository(String namespace) { - return new RemoteConfigRepository(namespace); + RemoteConfigRepository createRemoteConfigRepository(String appId, String namespace) { + return new RemoteConfigRepository(appId, namespace); } PropertiesCompatibleFileConfigRepository createPropertiesCompatibleFileConfigRepository( - String namespace, ConfigFileFormat format) { - String actualNamespaceName = trimNamespaceFormat(namespace, format); + String appId, String namespace, ConfigFileFormat format) { + String actualNamespaceName = trimNamespaceFormat(appId, namespace, format); PropertiesCompatibleConfigFile configFile = (PropertiesCompatibleConfigFile) ConfigService .getConfigFile(actualNamespaceName, format); @@ -158,7 +169,7 @@ ConfigFileFormat determineFileFormat(String namespaceName) { return ConfigFileFormat.Properties; } - String trimNamespaceFormat(String namespaceName, ConfigFileFormat format) { + String trimNamespaceFormat(String appId, String namespaceName, ConfigFileFormat format) { String extension = "." + format.getValue(); if (!namespaceName.toLowerCase().endsWith(extension)) { return namespaceName; diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryManager.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryManager.java index b57a89b5..44103bb8 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryManager.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryManager.java @@ -16,9 +16,12 @@ */ package com.ctrip.framework.apollo.spi; +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Table; import java.util.Map; import com.ctrip.framework.apollo.build.ApolloInjector; +import com.ctrip.framework.apollo.util.ConfigUtil; import com.google.common.collect.Maps; /** @@ -27,23 +30,31 @@ public class DefaultConfigFactoryManager implements ConfigFactoryManager { private ConfigRegistry m_registry; - private Map m_factories = Maps.newConcurrentMap(); + private Table m_factories = HashBasedTable.create(); + + private ConfigUtil m_configUtil; public DefaultConfigFactoryManager() { m_registry = ApolloInjector.getInstance(ConfigRegistry.class); + m_configUtil = ApolloInjector.getInstance(ConfigUtil.class); } @Override public ConfigFactory getFactory(String namespace) { + return getFactory(m_configUtil.getAppId(), namespace); + } + + @Override + public ConfigFactory getFactory(String appId, String namespace) { // step 1: check hacked factory - ConfigFactory factory = m_registry.getFactory(namespace); + ConfigFactory factory = m_registry.getFactory(appId, namespace); if (factory != null) { return factory; } // step 2: check cache - factory = m_factories.get(namespace); + factory = m_factories.get(appId, namespace); if (factory != null) { return factory; @@ -59,7 +70,7 @@ public ConfigFactory getFactory(String namespace) { // step 4: check default config factory factory = ApolloInjector.getInstance(ConfigFactory.class); - m_factories.put(namespace, factory); + m_factories.put(appId, namespace, factory); // factory should not be null return factory; diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigRegistry.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigRegistry.java index 02acc24c..f77d1e49 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigRegistry.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigRegistry.java @@ -16,33 +16,51 @@ */ package com.ctrip.framework.apollo.spi; -import java.util.Map; - +import com.ctrip.framework.apollo.build.ApolloInjector; +import com.ctrip.framework.apollo.util.ConfigUtil; +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Table; +import com.google.common.collect.Tables; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.collect.Maps; - /** * @author Jason Song(song_s@ctrip.com) */ public class DefaultConfigRegistry implements ConfigRegistry { private static final Logger s_logger = LoggerFactory.getLogger(DefaultConfigRegistry.class); - private Map m_instances = Maps.newConcurrentMap(); + + private ConfigUtil m_configUtil; + + private Table m_instances = Tables.synchronizedTable( + HashBasedTable.create()); + + public DefaultConfigRegistry() { + m_configUtil = ApolloInjector.getInstance(ConfigUtil.class); + } @Override public void register(String namespace, ConfigFactory factory) { - if (m_instances.containsKey(namespace)) { - s_logger.warn("ConfigFactory({}) is overridden by {}!", namespace, factory.getClass()); + register(m_configUtil.getAppId(), namespace, factory); + } + + @Override + public void register(String appId, String namespace, ConfigFactory factory) { + if (m_instances.contains(appId, namespace)) { + s_logger.warn("ConfigFactory({}-{}) is overridden by {}!", appId, namespace, factory.getClass()); } - m_instances.put(namespace, factory); + m_instances.put(appId, namespace, factory); } @Override public ConfigFactory getFactory(String namespace) { - ConfigFactory config = m_instances.get(namespace); + return getFactory(m_configUtil.getAppId(), namespace); + } + @Override + public ConfigFactory getFactory(String appId, String namespace) { + ConfigFactory config = m_instances.get(appId, namespace); return config; } } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloAnnotationProcessor.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloAnnotationProcessor.java index a7426871..9af00eaf 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloAnnotationProcessor.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloAnnotationProcessor.java @@ -106,9 +106,11 @@ private void processApolloConfig(Object bean, Field field) { Preconditions.checkArgument(Config.class.isAssignableFrom(field.getType()), "Invalid type: %s for field: %s, should be Config", field.getType(), field); + final String appId = StringUtils.defaultIfBlank(annotation.appId(), configUtil.getAppId()); final String namespace = annotation.value(); + final String resolvedAppId = this.environment.resolveRequiredPlaceholders(appId); final String resolvedNamespace = this.environment.resolveRequiredPlaceholders(namespace); - Config config = ConfigService.getConfig(resolvedNamespace); + Config config = ConfigService.getConfig(resolvedAppId, resolvedNamespace); ReflectionUtils.makeAccessible(field); ReflectionUtils.setField(field, bean, config); diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloConfig.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloConfig.java index 5b465ad1..8276ec41 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloConfig.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloConfig.java @@ -49,6 +49,13 @@ @Target(ElementType.FIELD) @Documented public @interface ApolloConfig { + /** + * Apollo appId for the config, if not specified then default to the global appid + * + * @since 2.4.0 + */ + String appId() default ""; + /** * Apollo namespace for the config, if not specified then default to application */ diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/EnableApolloConfig.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/EnableApolloConfig.java index 6b670945..26f990a5 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/EnableApolloConfig.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/EnableApolloConfig.java @@ -69,4 +69,11 @@ * @return */ int order() default Ordered.LOWEST_PRECEDENCE; + + /** + * Additional appId and namespace configurations. Will not participate in bootstrap + * + * @since 2.4.0 + */ + MultipleConfig[] multipleConfigs() default {}; } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/MultipleConfig.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/MultipleConfig.java new file mode 100644 index 00000000..e55962b5 --- /dev/null +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/MultipleConfig.java @@ -0,0 +1,51 @@ +/* + * Copyright 2022 Apollo Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package com.ctrip.framework.apollo.spring.annotation; + +import java.lang.annotation.*; + +/** + * @author Terry.Lam + * This annotation is used as a supplement to @EnableApolloConfig to fill in multiple appid + * + * @since 2.4.0 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Documented +public @interface MultipleConfig { + + /** + * multiple appId + * @return + */ + String appId(); + + /** + * Add the namespace you need to load + * @return + */ + String[] namespaces(); + + /** + * Configure the key corresponding to the appId. If the key is not required, you do not need to configure this item + * The secret could also be specified as a placeholder + * eg. ${apollo.multiple.shop.secret} + * @return + */ + String secret() default ""; +} diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/PropertySourcesProcessor.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/PropertySourcesProcessor.java index a6363948..cbc7e409 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/PropertySourcesProcessor.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/PropertySourcesProcessor.java @@ -20,6 +20,7 @@ import com.ctrip.framework.apollo.ConfigChangeListener; import com.ctrip.framework.apollo.ConfigService; import com.ctrip.framework.apollo.build.ApolloInjector; +import com.ctrip.framework.apollo.core.ConfigConsts; import com.ctrip.framework.apollo.spring.events.ApolloConfigChangeEvent; import com.ctrip.framework.apollo.spring.util.PropertySourcesUtil; import com.ctrip.framework.apollo.spring.util.SpringInjector; @@ -55,7 +56,7 @@ */ public class PropertySourcesProcessor implements BeanFactoryPostProcessor, EnvironmentAware, ApplicationEventPublisherAware, PriorityOrdered { - private static final Multimap NAMESPACE_NAMES = LinkedHashMultimap.create(); + private static final Multimap> APP_NAMESPACE_NAMES = LinkedHashMultimap.create(); private static final Set AUTO_UPDATE_INITIALIZED_BEAN_FACTORIES = Sets.newConcurrentHashSet(); private final ConfigPropertySourceFactory configPropertySourceFactory = SpringInjector @@ -65,7 +66,13 @@ public class PropertySourcesProcessor implements BeanFactoryPostProcessor, Envir private ApplicationEventPublisher applicationEventPublisher; public static boolean addNamespaces(Collection namespaces, int order) { - return NAMESPACE_NAMES.putAll(order, namespaces); + return addNamespaces(ApolloInjector.getInstance(ConfigUtil.class).getAppId(), namespaces, order); + } + + public static boolean addNamespaces(String appId, Collection namespaces, int order) { + Multimap appNamespaceNames = LinkedHashMultimap.create(); + appNamespaceNames.putAll(appId, namespaces); + return APP_NAMESPACE_NAMES.put(order, appNamespaceNames); } @Override @@ -88,20 +95,29 @@ private void initializePropertySources() { } //sort by order asc - ImmutableSortedSet orders = ImmutableSortedSet.copyOf(NAMESPACE_NAMES.keySet()); + ImmutableSortedSet orders = ImmutableSortedSet.copyOf(APP_NAMESPACE_NAMES.keySet()); Iterator iterator = orders.iterator(); while (iterator.hasNext()) { int order = iterator.next(); - for (String namespace : NAMESPACE_NAMES.get(order)) { - Config config = ConfigService.getConfig(namespace); + for (Multimap appMultimap : APP_NAMESPACE_NAMES.get(order)) { + + // app and namespace + Set appIds = appMultimap.keySet(); + for (String appId : appIds) { + Collection namespaces = appMultimap.get(appId); + for (String namespace : namespaces) { + Config config = ConfigService.getConfig(appId, namespace); - composite.addPropertySource(configPropertySourceFactory.getConfigPropertySource(namespace, config)); + composite.addPropertySource(configPropertySourceFactory.getConfigPropertySource(appId + ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR + namespace, config)); + } + } } + } // clean up - NAMESPACE_NAMES.clear(); + APP_NAMESPACE_NAMES.clear(); // add after the bootstrap property source or to the first if (environment.getPropertySources() @@ -153,7 +169,7 @@ public int getOrder() { // for test only static void reset() { - NAMESPACE_NAMES.clear(); + APP_NAMESPACE_NAMES.clear(); AUTO_UPDATE_INITIALIZED_BEAN_FACTORIES.clear(); } diff --git a/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/spi/DefaultApolloConfigRegistrarHelper.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/spi/DefaultApolloConfigRegistrarHelper.java index 8bd2b761..87680357 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/spi/DefaultApolloConfigRegistrarHelper.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/spi/DefaultApolloConfigRegistrarHelper.java @@ -16,6 +16,7 @@ */ package com.ctrip.framework.apollo.spring.spi; +import com.ctrip.framework.apollo.build.ApolloInjector; import com.ctrip.framework.apollo.core.spi.Ordered; import com.ctrip.framework.apollo.spring.annotation.ApolloAnnotationProcessor; import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig; @@ -24,9 +25,8 @@ import com.ctrip.framework.apollo.spring.property.AutoUpdateConfigChangeListener; import com.ctrip.framework.apollo.spring.property.SpringValueDefinitionProcessor; import com.ctrip.framework.apollo.spring.util.BeanRegistrationUtil; +import com.ctrip.framework.apollo.util.ConfigUtil; import com.google.common.collect.Lists; -import java.util.HashMap; -import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; @@ -35,10 +35,15 @@ import org.springframework.core.env.Environment; import org.springframework.core.type.AnnotationMetadata; +import java.util.HashMap; +import java.util.Map; + public class DefaultApolloConfigRegistrarHelper implements ApolloConfigRegistrarHelper { private static final Logger logger = LoggerFactory.getLogger( DefaultApolloConfigRegistrarHelper.class); + private final ConfigUtil configUtil = ApolloInjector.getInstance(ConfigUtil.class); + private Environment environment; @Override @@ -47,8 +52,29 @@ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, B .fromMap(importingClassMetadata.getAnnotationAttributes(EnableApolloConfig.class.getName())); final String[] namespaces = attributes.getStringArray("value"); final int order = attributes.getNumber("order"); - final String[] resolvedNamespaces = this.resolveNamespaces(namespaces); - PropertySourcesProcessor.addNamespaces(Lists.newArrayList(resolvedNamespaces), order); + + Map configMap = new HashMap<>(); + + configMap.put(configUtil.getAppId(), this.resolveNamespaces(namespaces)); + + AnnotationAttributes[] multipleConfigs = attributes.getAnnotationArray("multipleConfigs"); + if (multipleConfigs != null) { + for (AnnotationAttributes multipleConfig : multipleConfigs) { + String appId = multipleConfig.getString("appId"); + String[] multipleNamespaces = this.resolveNamespaces(multipleConfig.getStringArray("namespaces")); + configMap.put(appId, multipleNamespaces); + String secret = resolveSecret(multipleConfig.getString("secret")); + + // put multiple secret into system property + System.setProperty("apollo.accesskey." + appId + ".secret", secret); + } + } + + + // put appId and namespace into PropertySourcesProcessor + for (Map.Entry configEntry : configMap.entrySet()) { + PropertySourcesProcessor.addNamespaces(configEntry.getKey(), Lists.newArrayList(configEntry.getValue()), order); + } Map propertySourcesPlaceholderPropertyValues = new HashMap<>(); // to make sure the default PropertySourcesPlaceholderConfigurer's priority is higher than PropertyPlaceholderConfigurer @@ -77,6 +103,14 @@ private String[] resolveNamespaces(String[] namespaces) { return resolvedNamespaces; } + private String resolveSecret(String secret){ + if (this.environment == null) { + logger.warn("secret placeholder {} is not supported for Spring version prior to 3.2.x", secret); + return secret; + } + return this.environment.resolveRequiredPlaceholders(secret); + } + private void logNamespacePlaceholderNotSupportedMessage(String[] namespaces) { for (String namespace : namespaces) { if (namespace.contains("${")) { 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 9b99a4bf..731634a3 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 @@ -308,6 +308,17 @@ public String getDefaultLocalCacheDir() { return String.format(cacheRoot, getAppId()); } + public String getDefaultLocalCacheDir(String appId) { + String cacheRoot = getCustomizedCacheRoot(); + + if (!Strings.isNullOrEmpty(cacheRoot)) { + return cacheRoot + File.separator + appId; + } + + cacheRoot = isOSWindows() ? "C:\\opt\\data\\%s" : "/opt/data/%s"; + return String.format(cacheRoot, appId); + } + private String getCustomizedCacheRoot() { // 1. Get from System Property String cacheRoot = System.getProperty(ApolloClientSystemConsts.APOLLO_CACHE_DIR); @@ -509,4 +520,8 @@ private boolean getPropertyBoolean(String propertyName, String envName, boolean } return defaultVal; } + + public String getAccessKeySecret(String appId){ + return Foundation.app().getAccessKeySecret(appId); + } } diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/BaseIntegrationTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/BaseIntegrationTest.java index aadb34fd..d9ee925e 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/BaseIntegrationTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/BaseIntegrationTest.java @@ -17,6 +17,7 @@ package com.ctrip.framework.apollo; import com.ctrip.framework.apollo.build.ApolloInjector; +import com.ctrip.framework.apollo.core.ApolloClientSystemConsts; import com.ctrip.framework.apollo.core.ConfigConsts; import com.ctrip.framework.apollo.core.MetaDomainConsts; import com.ctrip.framework.apollo.core.dto.ApolloConfig; @@ -117,6 +118,7 @@ public void setUp() throws Exception { metaServiceUrl = configServiceURL = "http://localhost:" + port; System.setProperty(ConfigConsts.APOLLO_META_KEY, metaServiceUrl); + System.setProperty(ApolloClientSystemConsts.APP_ID, someAppId); ReflectionTestUtils.invokeMethod(MetaDomainConsts.class, "reset"); MockInjector.setInstance(ConfigUtil.class, new MockConfigUtil()); @@ -275,6 +277,11 @@ public long getLongPollingInitialDelayInMills() { public boolean isPropertiesOrderEnabled() { return propertiesOrderEnabled; } + + @Override + public String getDefaultLocalCacheDir(String appId) { + return ClassLoaderUtil.getClassPath() + "/" + appId; + } } /** diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/ConfigServiceTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/ConfigServiceTest.java index 4eb934a2..c8ae7a4f 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/ConfigServiceTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/ConfigServiceTest.java @@ -18,8 +18,10 @@ import static org.junit.Assert.assertEquals; +import com.ctrip.framework.apollo.build.ApolloInjector; import com.ctrip.framework.apollo.core.MetaDomainConsts; import com.ctrip.framework.apollo.enums.ConfigSourceType; +import java.lang.reflect.Field; import java.util.Set; import org.junit.After; @@ -43,8 +45,12 @@ public class ConfigServiceTest { @Before public void setUp() throws Exception { someAppId = "someAppId"; - MockInjector.setInstance(ConfigUtil.class, new MockConfigUtil()); +/* Field field = ConfigService.class.getDeclaredField("m_configUtil"); + field.setAccessible(true); + MockInjector.setInstance(ConfigUtil.class, new MockConfigUtil()); + field.set(null, ApolloInjector.getInstance(ConfigUtil.class));*/ + } @After @@ -59,11 +65,11 @@ public void tearDown() throws Exception { public void testHackConfig() { String someNamespace = "hack"; String someKey = "first"; - ConfigService.setConfig(new MockConfig(someNamespace)); + ConfigService.setConfig(new MockConfig(someAppId, someNamespace)); Config config = ConfigService.getAppConfig(); - assertEquals(someNamespace + ":" + someKey, config.getProperty(someKey, null)); + assertEquals(someAppId + ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR + someNamespace + ":" + someKey, config.getProperty(someKey, null)); assertEquals(null, config.getProperty("unknown", null)); } @@ -74,7 +80,7 @@ public void testHackConfigFactory() throws Exception { Config config = ConfigService.getAppConfig(); - assertEquals(ConfigConsts.NAMESPACE_APPLICATION + ":" + someKey, + assertEquals(someAppId + ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR + ConfigConsts.NAMESPACE_APPLICATION + ":" + someKey, config.getProperty(someKey, null)); } @@ -86,7 +92,7 @@ public void testMockConfigFactory() throws Exception { Config config = ConfigService.getConfig(someNamespace); - assertEquals(someNamespace + ":" + someKey, config.getProperty(someKey, null)); + assertEquals(someAppId + ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR + someNamespace + ":" + someKey, config.getProperty(someKey, null)); assertEquals(null, config.getProperty("unknown", null)); } @@ -97,7 +103,6 @@ public void testMockConfigFactoryForConfigFile() throws Exception { String someNamespaceFileName = String.format("%s.%s", someNamespace, someConfigFileFormat.getValue()); MockInjector.setInstance(ConfigFactory.class, someNamespaceFileName, new MockConfigFactory()); - ConfigFile configFile = ConfigService.getConfigFile(someNamespace, someConfigFileFormat); assertEquals(someNamespaceFileName, configFile.getNamespace()); @@ -105,9 +110,11 @@ public void testMockConfigFactoryForConfigFile() throws Exception { } private static class MockConfig extends AbstractConfig { + private final String m_appId; private final String m_namespace; - public MockConfig(String namespace) { + public MockConfig(String appId, String namespace) { + m_appId = appId; m_namespace = namespace; } @@ -117,7 +124,7 @@ public String getProperty(String key, String defaultValue) { return null; } - return m_namespace + ":" + key; + return m_appId + ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR + m_namespace + ":" + key; } @Override @@ -133,6 +140,7 @@ public ConfigSourceType getSourceType() { private static class MockConfigFile implements ConfigFile { private ConfigFileFormat m_configFileFormat; + private String m_appId; private String m_namespace; public MockConfigFile(String namespace, @@ -141,6 +149,13 @@ public MockConfigFile(String namespace, m_configFileFormat = configFileFormat; } + public MockConfigFile(String appId, String namespace, + ConfigFileFormat configFileFormat) { + m_appId = appId; + m_namespace = namespace; + m_configFileFormat = configFileFormat; + } + @Override public String getContent() { return m_namespace + ":" + m_configFileFormat.getValue(); @@ -151,6 +166,11 @@ public boolean hasContent() { return true; } + @Override + public String getAppId() { + return null; + } + @Override public String getNamespace() { return m_namespace; @@ -180,12 +200,22 @@ public ConfigSourceType getSourceType() { public static class MockConfigFactory implements ConfigFactory { @Override public Config create(String namespace) { - return new MockConfig(namespace); + return this.create(someAppId, namespace); + } + + @Override + public Config create(String appId, String namespace) { + return new MockConfig(appId, namespace); } @Override public ConfigFile createConfigFile(String namespace, ConfigFileFormat configFileFormat) { - return new MockConfigFile(namespace, configFileFormat); + return createConfigFile(someAppId, namespace, configFileFormat); + } + + @Override + public ConfigFile createConfigFile(String appId, String namespace, ConfigFileFormat configFileFormat) { + return new MockConfigFile(appId, namespace, configFileFormat); } } diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/build/MockInjector.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/build/MockInjector.java index 896f02f5..9ec0dd27 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/build/MockInjector.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/build/MockInjector.java @@ -36,7 +36,8 @@ public class MockInjector implements Injector { @Override public T getInstance(Class clazz) { if (delegate != null) { - return delegate.getInstance(clazz); + T instance = delegate.getInstance(clazz); + return instance; } return null; @@ -73,7 +74,8 @@ public static class InjectCustomizer implements ApolloInjectorCustomizer { @Override public T getInstance(Class clazz) { - return (T) classMap.get(clazz); + T instance = (T) classMap.get(clazz); + return instance; } @Override diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/integration/ConfigIntegrationTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/integration/ConfigIntegrationTest.java index cc6aeced..cbf2cfba 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/integration/ConfigIntegrationTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/integration/ConfigIntegrationTest.java @@ -371,7 +371,7 @@ public void onChange(ConfigChangeEvent changeEvent) { new ApolloConfigNotification(apolloConfig.getNamespaceName(), someNotificationId)) ); - longPollFinished.get(5000, TimeUnit.MILLISECONDS); + longPollFinished.get(10000, TimeUnit.MILLISECONDS); assertEquals(anotherValue, config.getProperty(someKey, null)); diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/AbstractConfigTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/AbstractConfigTest.java index 55d3e317..32499ae5 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/AbstractConfigTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/AbstractConfigTest.java @@ -44,6 +44,8 @@ */ public class AbstractConfigTest { + private static String someAppId = "someAppId"; + /** * @see AbstractConfig#fireConfigChange(ConfigChangeEvent) */ @@ -63,11 +65,11 @@ public void onChange(ConfigChangeEvent changeEvent) { Map changes = new HashMap<>(); changes.put("key1", - new ConfigChange(namespace, "key1", null, "new-value", PropertyChangeType.ADDED)); - ConfigChangeEvent configChangeEvent = new ConfigChangeEvent(namespace, changes); + new ConfigChange(someAppId, namespace, "key1", null, "new-value", PropertyChangeType.ADDED)); + ConfigChangeEvent configChangeEvent = new ConfigChangeEvent(someAppId, namespace, changes); abstractConfig.fireConfigChange(configChangeEvent); - abstractConfig.fireConfigChange(namespace, changes); + abstractConfig.fireConfigChange(someAppId, namespace, changes); // wait a minute for invoking Thread.sleep(100); @@ -106,8 +108,8 @@ public void onChange(ConfigChangeEvent changeEvent) { Map changes = new HashMap<>(); changes.put(key, - new ConfigChange(namespace, key, "old-value", "new-value", PropertyChangeType.MODIFIED)); - ConfigChangeEvent configChangeEvent = new ConfigChangeEvent(namespace, changes); + new ConfigChange(someAppId, namespace, key, "old-value", "new-value", PropertyChangeType.MODIFIED)); + ConfigChangeEvent configChangeEvent = new ConfigChangeEvent(someAppId, namespace, changes); abstractConfig.fireConfigChange(configChangeEvent); @@ -151,9 +153,9 @@ public void onChange(ConfigChangeEvent changeEvent) { Map changes = new HashMap<>(); changes.put(key, - new ConfigChange(namespace, key, "old-value", "new-value", PropertyChangeType.MODIFIED)); + new ConfigChange(someAppId, namespace, key, "old-value", "new-value", PropertyChangeType.MODIFIED)); - abstractConfig.fireConfigChange(namespace, changes); + abstractConfig.fireConfigChange(someAppId, namespace, changes); assertEquals(Collections.singleton(key), future1.get(500, TimeUnit.MILLISECONDS).changedKeys()); assertEquals(Collections.singleton(key), future2.get(500, TimeUnit.MILLISECONDS).changedKeys()); diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigManagerTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigManagerTest.java index fdc9bb41..63dcdac4 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigManagerTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigManagerTest.java @@ -43,6 +43,7 @@ public class DefaultConfigManagerTest { private DefaultConfigManager defaultConfigManager; private static String someConfigContent; + private static String someAppId; @Before public void setUp() throws Exception { @@ -50,6 +51,7 @@ public void setUp() throws Exception { MockInjector.setInstance(ConfigUtil.class, new ConfigUtil()); defaultConfigManager = new DefaultConfigManager(); someConfigContent = "someContent"; + someAppId = "someAppId"; } @After @@ -111,10 +113,10 @@ public void testGetConfigFileMultipleTimesWithSameNamespace() throws Exception { public static class MockConfigFactoryManager implements ConfigFactoryManager { @Override - public ConfigFactory getFactory(String namespace) { + public ConfigFactory getFactory(String appId, String namespace) { return new ConfigFactory() { @Override - public Config create(final String namespace) { + public Config create(final String appId, final String namespace) { return new AbstractConfig() { @Override public String getProperty(String key, String defaultValue) { @@ -134,9 +136,14 @@ public ConfigSourceType getSourceType() { } @Override - public ConfigFile createConfigFile(String namespace, final ConfigFileFormat configFileFormat) { + public Config create(String namespace) { + return this.create(someAppId, namespace); + } + + @Override + public ConfigFile createConfigFile(String appId, String namespace, final ConfigFileFormat configFileFormat) { ConfigRepository someConfigRepository = mock(ConfigRepository.class); - return new AbstractConfigFile(namespace, someConfigRepository) { + return new AbstractConfigFile(appId, namespace, someConfigRepository) { @Override protected void update(Properties newProperties) { @@ -159,7 +166,17 @@ public ConfigFileFormat getConfigFileFormat() { } }; } + + @Override + public ConfigFile createConfigFile(String namespace, ConfigFileFormat configFileFormat) { + return createConfigFile(someAppId, namespace, configFileFormat); + } }; } + + @Override + public ConfigFactory getFactory(String namespace) { + return getFactory(someAppId, namespace); + } } } diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigTest.java index 93792b41..1054d230 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigTest.java @@ -71,6 +71,7 @@ public class DefaultConfigTest { private File someResourceDir; private String someNamespace; + private String someAppId; private ConfigRepository configRepository; private Properties someProperties; private ConfigSourceType someSourceType; @@ -91,6 +92,7 @@ public Properties answer(InvocationOnMock invocation) { someResourceDir = new File(ClassLoaderUtil.getClassPath() + "/META-INF/config"); someResourceDir.mkdirs(); + someAppId = "someAppId"; someNamespace = "someName"; configRepository = mock(ConfigRepository.class); } @@ -137,7 +139,7 @@ public void testGetPropertyWithAllPropertyHierarchy() throws Exception { when(configRepository.getSourceType()).thenReturn(someSourceType); //set up resource file - File resourceFile = new File(someResourceDir, someNamespace + ".properties"); + File resourceFile = new File(someResourceDir, someAppId + "+" +someNamespace + ".properties"); Files.write(someKey + "=" + someResourceValue, resourceFile, Charsets.UTF_8); Files.append(System.getProperty("line.separator"), resourceFile, Charsets.UTF_8); Files.append(anotherKey + "=" + someResourceValue, resourceFile, Charsets.UTF_8); @@ -145,7 +147,7 @@ public void testGetPropertyWithAllPropertyHierarchy() throws Exception { Files.append(lastKey + "=" + someResourceValue, resourceFile, Charsets.UTF_8); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); String someKeyValue = defaultConfig.getProperty(someKey, null); String anotherKeyValue = defaultConfig.getProperty(anotherKey, null); @@ -178,7 +180,7 @@ public void testGetIntProperty() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertEquals(someValue, defaultConfig.getIntProperty(someKey, someDefaultValue)); assertEquals(someDefaultValue, defaultConfig.getIntProperty(someStringKey, someDefaultValue)); @@ -197,7 +199,7 @@ public void testGetIntPropertyMultipleTimesWithCache() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertEquals(someValue, defaultConfig.getIntProperty(someKey, someDefaultValue)); assertEquals(someValue, defaultConfig.getIntProperty(someKey, someDefaultValue)); @@ -220,7 +222,7 @@ public void testGetIntPropertyMultipleTimesWithPropertyChanges() throws Exceptio when(configRepository.getConfig()).thenReturn(someProperties); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertEquals(someValue, defaultConfig.getIntProperty(someKey, someDefaultValue)); @@ -251,7 +253,7 @@ public void testGetIntPropertyMultipleTimesWithSmallCache() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertEquals(someValue, defaultConfig.getIntProperty(someKey, someDefaultValue)); assertEquals(someValue, defaultConfig.getIntProperty(someKey, someDefaultValue)); @@ -283,7 +285,7 @@ public void testGetIntPropertyMultipleTimesWithShortExpireTime() throws Exceptio when(configRepository.getConfig()).thenReturn(someProperties); final DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertEquals(someValue, defaultConfig.getIntProperty(someKey, someDefaultValue)); assertEquals(someValue, defaultConfig.getIntProperty(someKey, someDefaultValue)); @@ -318,7 +320,7 @@ public void testGetLongProperty() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertEquals(someValue, defaultConfig.getLongProperty(someKey, someDefaultValue)); assertEquals(someDefaultValue, defaultConfig.getLongProperty(someStringKey, someDefaultValue)); @@ -341,7 +343,7 @@ public void testGetShortProperty() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertEquals(someValue, defaultConfig.getShortProperty(someKey, someDefaultValue)); assertEquals(someDefaultValue, defaultConfig.getShortProperty(someStringKey, someDefaultValue)); @@ -364,7 +366,7 @@ public void testGetFloatProperty() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertEquals(someValue, defaultConfig.getFloatProperty(someKey, someDefaultValue), 0.001); assertEquals(someDefaultValue, defaultConfig.getFloatProperty(someStringKey, someDefaultValue), 0.001); @@ -387,7 +389,7 @@ public void testGetDoubleProperty() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertEquals(someValue, defaultConfig.getDoubleProperty(someKey, someDefaultValue), 0.001); assertEquals(someDefaultValue, defaultConfig.getDoubleProperty(someStringKey, someDefaultValue), 0.001); @@ -410,7 +412,7 @@ public void testGetByteProperty() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertEquals(someValue, defaultConfig.getByteProperty(someKey, someDefaultValue)); assertEquals(someDefaultValue, defaultConfig.getByteProperty(someStringKey, someDefaultValue)); @@ -433,7 +435,7 @@ public void testGetBooleanProperty() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertEquals(someValue, defaultConfig.getBooleanProperty(someKey, someDefaultValue)); assertEquals(someDefaultValue, defaultConfig.getBooleanProperty(someStringKey, someDefaultValue)); @@ -456,7 +458,7 @@ public void testGetArrayProperty() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertArrayEquals(values, defaultConfig.getArrayProperty(someKey, someDelimiter, someDefaultValue)); assertArrayEquals(someDefaultValue, defaultConfig.getArrayProperty(someKey, someInvalidDelimiter, @@ -480,7 +482,7 @@ public void testGetArrayPropertyMultipleTimesWithCache() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertArrayEquals(values, defaultConfig.getArrayProperty(someKey, someDelimiter, someDefaultValue)); assertArrayEquals(values, defaultConfig.getArrayProperty(someKey, someDelimiter, someDefaultValue)); @@ -516,7 +518,7 @@ public void testGetArrayPropertyMultipleTimesWithCacheAndValueChanges() throws E anotherProperties.setProperty(someKey, anotherValue); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertArrayEquals(values, defaultConfig.getArrayProperty(someKey, someDelimiter, someDefaultValue)); @@ -542,7 +544,7 @@ public void testGetDatePropertyWithFormat() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); checkDatePropertyWithFormat(defaultConfig, shortDate, "shortDateProperty", "yyyy-MM-dd", someDefaultValue); checkDatePropertyWithFormat(defaultConfig, mediumDate, "mediumDateProperty", "yyyy-MM-dd HH:mm:ss", @@ -572,7 +574,7 @@ public void testGetDatePropertyWithNoFormat() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); checkDatePropertyWithoutFormat(defaultConfig, shortDate, "shortDateProperty", someDefaultValue); checkDatePropertyWithoutFormat(defaultConfig, mediumDate, "mediumDateProperty", someDefaultValue); @@ -591,7 +593,7 @@ public void testGetEnumProperty() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertEquals(SomeEnum.someValue, defaultConfig.getEnumProperty("enumProperty", SomeEnum.class, someDefaultValue)); assertEquals(someDefaultValue, defaultConfig.getEnumProperty("stringProperty", SomeEnum.class, someDefaultValue)); @@ -609,7 +611,7 @@ public void testGetDurationProperty() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertEquals(result, defaultConfig.getDurationProperty("durationProperty", someDefaultValue)); assertEquals(someDefaultValue, defaultConfig.getDurationProperty("stringProperty", someDefaultValue)); @@ -643,11 +645,11 @@ public void testOnRepositoryChange() throws Exception { when(configRepository.getSourceType()).thenReturn(someSourceType); //set up resource file - File resourceFile = new File(someResourceDir, someNamespace + ".properties"); + File resourceFile = new File(someResourceDir, someAppId + "+" + someNamespace + ".properties"); Files.append(yetAnotherKey + "=" + yetAnotherResourceValue, resourceFile, Charsets.UTF_8); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertEquals(someSourceType, defaultConfig.getSourceType()); @@ -714,7 +716,7 @@ public void testFireConfigChangeWithInterestedKeys() throws Exception { Map changes = Maps.newHashMap(); changes.put(someKeyChanged, mock(ConfigChange.class)); changes.put(anotherKeyChanged, mock(ConfigChange.class)); - ConfigChangeEvent someChangeEvent = new ConfigChangeEvent(someNamespace, changes); + ConfigChangeEvent someChangeEvent = new ConfigChangeEvent(someAppId, someNamespace, changes); final SettableFuture interestedInAllKeysFuture = SettableFuture.create(); ConfigChangeListener interestedInAllKeys = new ConfigChangeListener() { @@ -740,7 +742,7 @@ public void onChange(ConfigChangeEvent changeEvent) { } }; - DefaultConfig config = new DefaultConfig(someNamespace, mock(ConfigRepository.class)); + DefaultConfig config = new DefaultConfig(someAppId, someNamespace, mock(ConfigRepository.class)); config.addChangeListener(interestedInAllKeys); config.addChangeListener(interestedInSomeKey, Sets.newHashSet(someKeyChanged)); @@ -800,7 +802,7 @@ public void onChange(ConfigChangeEvent changeEvent) { ConfigChangeListener yetAnotherListener = mock(ConfigChangeListener.class); - DefaultConfig config = new DefaultConfig(someNamespace, mock(ConfigRepository.class)); + DefaultConfig config = new DefaultConfig(someAppId, someNamespace, mock(ConfigRepository.class)); config.addChangeListener(someListener); config.addChangeListener(anotherListener); @@ -835,7 +837,7 @@ public void testGetPropertyNames() { when(configRepository.getConfig()).thenReturn(someProperties); - DefaultConfig defaultConfig = new DefaultConfig(someNamespace, configRepository); + DefaultConfig defaultConfig = new DefaultConfig(someAppId, someNamespace, configRepository); Set propertyNames = defaultConfig.getPropertyNames(); @@ -862,7 +864,7 @@ public Properties answer(InvocationOnMock invocation) { when(configRepository.getConfig()).thenReturn(someProperties); - DefaultConfig defaultConfig = new DefaultConfig(someNamespace, configRepository); + DefaultConfig defaultConfig = new DefaultConfig(someAppId, someNamespace, configRepository); Set propertyNames = defaultConfig.getPropertyNames(); @@ -875,7 +877,7 @@ public void testGetPropertyNamesWithNullProp() { when(configRepository.getConfig()).thenReturn(null); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); Set propertyNames = defaultConfig.getPropertyNames(); assertEquals(Collections.emptySet(), propertyNames); @@ -895,7 +897,7 @@ public void testGetPropertyWithFunction() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); assertEquals(defaultConfig.getProperty(someKey, new Function>() { @Override @@ -921,7 +923,7 @@ public void testLoadFromRepositoryFailedAndThenRecovered() { when(configRepository.getConfig()).thenThrow(mock(RuntimeException.class)); DefaultConfig defaultConfig = - new DefaultConfig(someNamespace, configRepository); + new DefaultConfig(someAppId, someNamespace, configRepository); verify(configRepository, times(1)).addChangeListener(defaultConfig); diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/InterestedConfigChangeEventTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/InterestedConfigChangeEventTest.java index 9ffdfcb8..36faf1ac 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/InterestedConfigChangeEventTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/InterestedConfigChangeEventTest.java @@ -42,6 +42,8 @@ */ public class InterestedConfigChangeEventTest { + private static String someAppId = "someAppId"; + @Test public void TestInterestedChangedKeys() throws ExecutionException, InterruptedException, TimeoutException { @@ -69,10 +71,10 @@ public void onChange(ConfigChangeEvent changeEvent) { Map changes = new HashMap<>(); - changes.put(key, new ConfigChange(namespace, key, "123", "456", PropertyChangeType.MODIFIED)); + changes.put(key, new ConfigChange(someAppId, namespace, key, "123", "456", PropertyChangeType.MODIFIED)); changes.put(anotherKey, - new ConfigChange(namespace, anotherKey, null, "someValue", PropertyChangeType.ADDED)); - config.fireConfigChange(namespace, changes); + new ConfigChange(someAppId, namespace, anotherKey, null, "someValue", PropertyChangeType.ADDED)); + config.fireConfigChange(someAppId, namespace, changes); onChangeFuture.get(500, TimeUnit.MILLISECONDS); diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/JsonConfigFileTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/JsonConfigFileTest.java index cf93cd41..eaf98184 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/JsonConfigFileTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/JsonConfigFileTest.java @@ -39,6 +39,7 @@ */ @RunWith(MockitoJUnitRunner.class) public class JsonConfigFileTest { + private String someAppId; private String someNamespace; @Mock private ConfigRepository configRepository; @@ -47,6 +48,7 @@ public class JsonConfigFileTest { @Before public void setUp() throws Exception { + someAppId = "someAppId"; someNamespace = "someName"; } @@ -62,7 +64,7 @@ public void testWhenHasContent() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); when(configRepository.getSourceType()).thenReturn(someSourceType); - JsonConfigFile configFile = new JsonConfigFile(someNamespace, configRepository); + JsonConfigFile configFile = new JsonConfigFile(someAppId, someNamespace, configRepository); assertEquals(ConfigFileFormat.JSON, configFile.getConfigFileFormat()); assertEquals(someNamespace, configFile.getNamespace()); @@ -75,7 +77,7 @@ public void testWhenHasContent() throws Exception { public void testWhenHasNoContent() throws Exception { when(configRepository.getConfig()).thenReturn(null); - JsonConfigFile configFile = new JsonConfigFile(someNamespace, configRepository); + JsonConfigFile configFile = new JsonConfigFile(someAppId, someNamespace, configRepository); assertFalse(configFile.hasContent()); assertNull(configFile.getContent()); @@ -85,7 +87,7 @@ public void testWhenHasNoContent() throws Exception { public void testWhenConfigRepositoryHasError() throws Exception { when(configRepository.getConfig()).thenThrow(new RuntimeException("someError")); - JsonConfigFile configFile = new JsonConfigFile(someNamespace, configRepository); + JsonConfigFile configFile = new JsonConfigFile(someAppId, someNamespace, configRepository); assertFalse(configFile.hasContent()); assertNull(configFile.getContent()); @@ -105,7 +107,7 @@ public void testOnRepositoryChange() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); when(configRepository.getSourceType()).thenReturn(someSourceType); - JsonConfigFile configFile = new JsonConfigFile(someNamespace, configRepository); + JsonConfigFile configFile = new JsonConfigFile(someAppId, someNamespace, configRepository); assertEquals(someValue, configFile.getContent()); assertEquals(someSourceType, configFile.getSourceType()); @@ -116,7 +118,7 @@ public void testOnRepositoryChange() throws Exception { ConfigSourceType anotherSourceType = ConfigSourceType.REMOTE; when(configRepository.getSourceType()).thenReturn(anotherSourceType); - configFile.onRepositoryChange(someNamespace, anotherProperties); + configFile.onRepositoryChange(someAppId, someNamespace, anotherProperties); assertEquals(anotherValue, configFile.getContent()); assertEquals(anotherSourceType, configFile.getSourceType()); @@ -134,13 +136,13 @@ public void testWhenConfigRepositoryHasErrorAndThenRecovered() throws Exception when(configRepository.getConfig()).thenThrow(new RuntimeException("someError")); when(configRepository.getSourceType()).thenReturn(someSourceType); - JsonConfigFile configFile = new JsonConfigFile(someNamespace, configRepository); + JsonConfigFile configFile = new JsonConfigFile(someAppId, someNamespace, configRepository); assertFalse(configFile.hasContent()); assertNull(configFile.getContent()); assertEquals(ConfigSourceType.NONE, configFile.getSourceType()); - configFile.onRepositoryChange(someNamespace, someProperties); + configFile.onRepositoryChange(someAppId, someNamespace, someProperties); assertTrue(configFile.hasContent()); assertEquals(someValue, configFile.getContent()); diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepositoryTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepositoryTest.java index 8bf7b7be..2c84bde9 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepositoryTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepositoryTest.java @@ -119,7 +119,7 @@ public void testLoadConfigWithLocalFile() throws Exception { someProperties.setProperty(someKey, someValue); createLocalCachePropertyFile(someProperties); - LocalFileConfigRepository localRepo = new LocalFileConfigRepository(someNamespace); + LocalFileConfigRepository localRepo = new LocalFileConfigRepository(someAppId, someNamespace); localRepo.setLocalCacheDir(someBaseDir, true); Properties properties = localRepo.getConfig(); @@ -135,7 +135,7 @@ public void testLoadConfigWithLocalFileAndFallbackRepo() throws Exception { Files.write(defaultKey + "=" + someValue, file, Charsets.UTF_8); - LocalFileConfigRepository localRepo = new LocalFileConfigRepository(someNamespace, upstreamRepo); + LocalFileConfigRepository localRepo = new LocalFileConfigRepository(someAppId, someNamespace, upstreamRepo); localRepo.setLocalCacheDir(someBaseDir, true); Properties properties = localRepo.getConfig(); @@ -147,7 +147,7 @@ public void testLoadConfigWithLocalFileAndFallbackRepo() throws Exception { @Test public void testLoadConfigWithNoLocalFile() throws Exception { LocalFileConfigRepository localFileConfigRepository = - new LocalFileConfigRepository(someNamespace, upstreamRepo); + new LocalFileConfigRepository(someAppId, someNamespace, upstreamRepo); localFileConfigRepository.setLocalCacheDir(someBaseDir, true); Properties result = localFileConfigRepository.getConfig(); @@ -161,14 +161,14 @@ public void testLoadConfigWithNoLocalFile() throws Exception { @Test public void testLoadConfigWithNoLocalFileMultipleTimes() throws Exception { LocalFileConfigRepository localRepo = - new LocalFileConfigRepository(someNamespace, upstreamRepo); + new LocalFileConfigRepository(someAppId, someNamespace, upstreamRepo); localRepo.setLocalCacheDir(someBaseDir, true); Properties someProperties = localRepo.getConfig(); LocalFileConfigRepository anotherLocalRepoWithNoFallback = - new LocalFileConfigRepository(someNamespace); + new LocalFileConfigRepository(someAppId, someNamespace); anotherLocalRepoWithNoFallback.setLocalCacheDir(someBaseDir, true); Properties anotherProperties = anotherLocalRepoWithNoFallback.getConfig(); @@ -184,7 +184,7 @@ public void testOnRepositoryChange() throws Exception { RepositoryChangeListener someListener = mock(RepositoryChangeListener.class); LocalFileConfigRepository localFileConfigRepository = - new LocalFileConfigRepository(someNamespace, upstreamRepo); + new LocalFileConfigRepository(someAppId, someNamespace, upstreamRepo); assertEquals(ConfigSourceType.LOCAL, localFileConfigRepository.getSourceType()); localFileConfigRepository.initialize(); @@ -201,11 +201,11 @@ public void testOnRepositoryChange() throws Exception { ConfigSourceType anotherSourceType = ConfigSourceType.NONE; when(upstreamRepo.getSourceType()).thenReturn(anotherSourceType); - localFileConfigRepository.onRepositoryChange(someNamespace, anotherProperties); + localFileConfigRepository.onRepositoryChange(someAppId, someNamespace, anotherProperties); final ArgumentCaptor captor = ArgumentCaptor.forClass(Properties.class); - verify(someListener, times(1)).onRepositoryChange(eq(someNamespace), captor.capture()); + verify(someListener, times(1)).onRepositoryChange(eq(someAppId), eq(someNamespace), captor.capture()); assertEquals(anotherProperties, captor.getValue()); assertEquals(anotherSourceType, localFileConfigRepository.getSourceType()); diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/PropertiesCompatibleFileConfigRepositoryTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/PropertiesCompatibleFileConfigRepositoryTest.java index 1b90a355..9350888f 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/PropertiesCompatibleFileConfigRepositoryTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/PropertiesCompatibleFileConfigRepositoryTest.java @@ -40,6 +40,7 @@ public class PropertiesCompatibleFileConfigRepositoryTest { private PropertiesCompatibleConfigFile configFile; private String someNamespaceName; + private String someAppId; @Mock private Properties someProperties; @@ -47,7 +48,9 @@ public class PropertiesCompatibleFileConfigRepositoryTest { @Before public void setUp() throws Exception { someNamespaceName = "someNamespaceName"; + someAppId = "someAppId"; when(configFile.getNamespace()).thenReturn(someNamespaceName); + when(configFile.getAppId()).thenReturn(someAppId); when(configFile.asProperties()).thenReturn(someProperties); } @@ -129,6 +132,6 @@ public void testOnChange() throws Exception { configFileRepository.onChange(someChangeEvent); assertSame(anotherProperties, configFileRepository.getConfig()); - verify(someListener, times(1)).onRepositoryChange(someNamespaceName, anotherProperties); + verify(someListener, times(1)).onRepositoryChange(someAppId, someNamespaceName, anotherProperties); } } diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/PropertiesConfigFileTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/PropertiesConfigFileTest.java index 41add46b..b109e394 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/PropertiesConfigFileTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/PropertiesConfigFileTest.java @@ -48,6 +48,7 @@ @RunWith(MockitoJUnitRunner.class) public class PropertiesConfigFileTest { + private String someAppId; private String someNamespace; @Mock private ConfigRepository configRepository; @@ -56,6 +57,7 @@ public class PropertiesConfigFileTest { @Before public void setUp() throws Exception { + someAppId = "someAppId"; someNamespace = "someName"; when(propertiesFactory.getPropertiesInstance()).thenAnswer(new Answer() { @Override @@ -80,7 +82,7 @@ public void testWhenHasContent() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); - PropertiesConfigFile configFile = new PropertiesConfigFile(someNamespace, configRepository); + PropertiesConfigFile configFile = new PropertiesConfigFile(someAppId, someNamespace, configRepository); assertEquals(ConfigFileFormat.Properties, configFile.getConfigFileFormat()); assertEquals(someNamespace, configFile.getNamespace()); @@ -92,7 +94,7 @@ public void testWhenHasContent() throws Exception { public void testWhenHasNoContent() throws Exception { when(configRepository.getConfig()).thenReturn(null); - PropertiesConfigFile configFile = new PropertiesConfigFile(someNamespace, configRepository); + PropertiesConfigFile configFile = new PropertiesConfigFile(someAppId, someNamespace, configRepository); assertFalse(configFile.hasContent()); assertNull(configFile.getContent()); @@ -102,7 +104,7 @@ public void testWhenHasNoContent() throws Exception { public void testWhenConfigRepositoryHasError() throws Exception { when(configRepository.getConfig()).thenThrow(new RuntimeException("someError")); - PropertiesConfigFile configFile = new PropertiesConfigFile(someNamespace, configRepository); + PropertiesConfigFile configFile = new PropertiesConfigFile(someAppId, someNamespace, configRepository); assertFalse(configFile.hasContent()); assertNull(configFile.getContent()); @@ -118,7 +120,7 @@ public void testOnRepositoryChange() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); - PropertiesConfigFile configFile = new PropertiesConfigFile(someNamespace, configRepository); + PropertiesConfigFile configFile = new PropertiesConfigFile(someAppId, someNamespace, configRepository); assertTrue(configFile.getContent().contains(String.format("%s=%s", someKey, someValue))); @@ -157,7 +159,7 @@ public void testWhenConfigRepositoryHasErrorAndThenRecovered() throws Exception when(configRepository.getConfig()).thenThrow(new RuntimeException("someError")); - PropertiesConfigFile configFile = new PropertiesConfigFile(someNamespace, configRepository); + PropertiesConfigFile configFile = new PropertiesConfigFile(someAppId, someNamespace, configRepository); assertFalse(configFile.hasContent()); assertNull(configFile.getContent()); @@ -177,7 +179,7 @@ public void testIfCompatibleWithProperties() { when(configRepository.getConfig()).thenReturn(someProperties); - PropertiesConfigFile configFile = new PropertiesConfigFile(someNamespace, configRepository); + PropertiesConfigFile configFile = new PropertiesConfigFile(someAppId, someNamespace, configRepository); assertEquals(configFile.asProperties(),someProperties); assertEquals(ConfigFileFormat.Properties, configFile.getConfigFileFormat()); @@ -192,7 +194,7 @@ public void testIfCompatibleWithEmptyProperties() { when(configRepository.getConfig()).thenReturn(someProperties); - PropertiesConfigFile configFile = new PropertiesConfigFile(someNamespace, configRepository); + PropertiesConfigFile configFile = new PropertiesConfigFile(someAppId, someNamespace, configRepository); assertEquals(configFile.asProperties(),someProperties); assertEquals(ConfigFileFormat.Properties, configFile.getConfigFileFormat()); diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/RemoteConfigLongPollServiceTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/RemoteConfigLongPollServiceTest.java index 37fd27c0..687a993b 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/RemoteConfigLongPollServiceTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/RemoteConfigLongPollServiceTest.java @@ -28,11 +28,14 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import com.ctrip.framework.apollo.build.ApolloInjector; import com.ctrip.framework.apollo.build.MockInjector; +import com.ctrip.framework.apollo.core.ApolloClientSystemConsts; import com.ctrip.framework.apollo.core.dto.ApolloConfigNotification; import com.ctrip.framework.apollo.core.dto.ApolloNotificationMessages; import com.ctrip.framework.apollo.core.dto.ServiceDTO; import com.ctrip.framework.apollo.core.signature.Signature; +import com.ctrip.framework.apollo.spring.config.PropertySourcesProcessor; import com.ctrip.framework.apollo.util.ConfigUtil; import com.ctrip.framework.apollo.util.http.HttpRequest; import com.ctrip.framework.apollo.util.http.HttpResponse; @@ -41,6 +44,7 @@ import com.google.common.collect.Lists; import com.google.common.net.HttpHeaders; import com.google.common.util.concurrent.SettableFuture; +import java.lang.reflect.Field; import java.lang.reflect.Type; import java.util.List; import java.util.Map; @@ -80,6 +84,12 @@ public class RemoteConfigLongPollServiceTest { @Before public void setUp() throws Exception { + + someAppId = "someAppId"; + someCluster = "someCluster"; + + System.setProperty(ApolloClientSystemConsts.APP_ID, someAppId); + MockInjector.setInstance(HttpClient.class, httpClient); someServerUrl = "http://someServer"; @@ -90,13 +100,16 @@ public void setUp() throws Exception { MockInjector.setInstance(ConfigUtil.class, new MockConfigUtil()); +/* Field field = PropertySourcesProcessor.class.getDeclaredField("configUtil"); + field.setAccessible(true); + field.set(null, ApolloInjector.getInstance(ConfigUtil.class));*/ + remoteConfigLongPollService = new RemoteConfigLongPollService(); responseType = (Type) ReflectionTestUtils.getField(remoteConfigLongPollService, "m_responseType"); - someAppId = "someAppId"; - someCluster = "someCluster"; + } @After @@ -133,7 +146,7 @@ public HttpResponse> answer(InvocationOnMock invo } }).when(httpClient).doGet(any(HttpRequest.class), eq(responseType)); - remoteConfigLongPollService.submit(someNamespace, someRepository); + remoteConfigLongPollService.submit(someAppId, someNamespace, someRepository); longPollFinished.get(5000, TimeUnit.MILLISECONDS); @@ -184,7 +197,7 @@ public Void answer(InvocationOnMock invocation) throws Throwable { } }).when(someRepository).onLongPollNotified(any(ServiceDTO.class), any(ApolloNotificationMessages.class)); - remoteConfigLongPollService.submit(someNamespace, someRepository); + remoteConfigLongPollService.submit(someAppId, someNamespace, someRepository); onNotified.get(5000, TimeUnit.MILLISECONDS); @@ -246,8 +259,8 @@ public Void answer(InvocationOnMock invocation) throws Throwable { } }).when(someRepository).onLongPollNotified(any(ServiceDTO.class), any(ApolloNotificationMessages.class)); - remoteConfigLongPollService.submit(someNamespace, someRepository); - onNotified.get(5000, TimeUnit.MILLISECONDS); + remoteConfigLongPollService.submit(someAppId, someNamespace, someRepository); + onNotified.get(50000, TimeUnit.MILLISECONDS); remoteConfigLongPollService.stopLongPollingRefresh(); verify(someRepository, times(1)).onLongPollNotified(any(ServiceDTO.class), any(ApolloNotificationMessages.class)); @@ -317,10 +330,10 @@ public Void answer(InvocationOnMock invocation) throws Throwable { } }).when(anotherRepository).onLongPollNotified(Mockito.any(ServiceDTO.class), Mockito.nullable(ApolloNotificationMessages.class)); - remoteConfigLongPollService.submit(someNamespace, someRepository); + remoteConfigLongPollService.submit(someAppId, someNamespace, someRepository); submitAnotherNamespaceStart.get(5000, TimeUnit.MILLISECONDS); - remoteConfigLongPollService.submit(anotherNamespace, anotherRepository); + remoteConfigLongPollService.submit(someAppId, anotherNamespace, anotherRepository); submitAnotherNamespaceFinish.set(true); onAnotherRepositoryNotified.get(5000, TimeUnit.MILLISECONDS); @@ -388,8 +401,8 @@ public Void answer(InvocationOnMock invocation) throws Throwable { } }).when(anotherRepository).onLongPollNotified(any(ServiceDTO.class), any(ApolloNotificationMessages.class)); - remoteConfigLongPollService.submit(someNamespace, someRepository); - remoteConfigLongPollService.submit(anotherNamespace, anotherRepository); + remoteConfigLongPollService.submit(someAppId, someNamespace, someRepository); + remoteConfigLongPollService.submit(someAppId, anotherNamespace, anotherRepository); someRepositoryNotified.get(5000, TimeUnit.MILLISECONDS); anotherRepositoryNotified.get(5000, TimeUnit.MILLISECONDS); @@ -449,7 +462,7 @@ public Void answer(InvocationOnMock invocation) throws Throwable { } }).when(someRepository).onLongPollNotified(any(ServiceDTO.class), any(ApolloNotificationMessages.class)); - remoteConfigLongPollService.submit(someNamespace, someRepository); + remoteConfigLongPollService.submit(someAppId, someNamespace, someRepository); onNotified.get(5000, TimeUnit.MILLISECONDS); @@ -577,6 +590,14 @@ public int getLongPollQPS() { public long getLongPollingInitialDelayInMills() { return 0; } + + @Override + public String getAccessKeySecret(String appId){ + if(appId.equals(someAppId)){ + return someSecret; + } + return null; + } } } diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/RemoteConfigRepositoryTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/RemoteConfigRepositoryTest.java index a8e7c020..ec2eb1d5 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/RemoteConfigRepositoryTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/RemoteConfigRepositoryTest.java @@ -39,6 +39,7 @@ import com.ctrip.framework.apollo.enums.ConfigSourceType; import com.ctrip.framework.apollo.exceptions.ApolloConfigException; import com.ctrip.framework.apollo.exceptions.ApolloConfigStatusCodeException; +import com.ctrip.framework.apollo.spring.config.PropertySourcesProcessor; import com.ctrip.framework.apollo.util.ConfigUtil; import com.ctrip.framework.apollo.util.OrderedProperties; import com.ctrip.framework.apollo.util.factory.PropertiesFactory; @@ -52,6 +53,7 @@ import com.google.common.net.UrlEscapers; import com.google.common.util.concurrent.SettableFuture; import com.google.gson.Gson; +import java.lang.reflect.Field; import java.lang.reflect.Type; import java.util.List; import java.util.Map; @@ -101,6 +103,10 @@ public void setUp() throws Exception { configUtil = new MockConfigUtil(); MockInjector.setInstance(ConfigUtil.class, configUtil); +/* Field field = PropertySourcesProcessor.class.getDeclaredField("configUtil"); + field.setAccessible(true); + field.set(null, configUtil);*/ + someServerUrl = "http://someServer"; ServiceDTO serviceDTO = mock(ServiceDTO.class); @@ -126,6 +132,7 @@ public Properties answer(InvocationOnMock invocation) { someAppId = "someAppId"; someCluster = "someCluster"; + } @After @@ -145,7 +152,7 @@ public void testLoadConfig() throws Exception { when(someResponse.getStatusCode()).thenReturn(200); when(someResponse.getBody()).thenReturn(someApolloConfig); - RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someNamespace); + RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someAppId, someNamespace); Properties config = remoteConfigRepository.getConfig(); @@ -171,7 +178,7 @@ public Properties answer(InvocationOnMock invocation) { } }); - RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someNamespace); + RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someAppId, someNamespace); Properties config = remoteConfigRepository.getConfig(); @@ -208,7 +215,7 @@ public HttpResponse answer(InvocationOnMock invocation) throws Thr } }).when(httpClient).doGet(any(HttpRequest.class), any(Class.class)); - RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someNamespace); + RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someAppId, someNamespace); Properties config = remoteConfigRepository.getConfig(); @@ -221,7 +228,7 @@ public void testGetRemoteConfigWithServerError() throws Exception { when(someResponse.getStatusCode()).thenReturn(500); - RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someNamespace); + RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someAppId, someNamespace); //must stop the long polling before exception occurred remoteConfigLongPollService.stopLongPollingRefresh(); @@ -234,7 +241,7 @@ public void testGetRemoteConfigWithNotFount() throws Exception { when(someResponse.getStatusCode()).thenReturn(404); - RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someNamespace); + RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someAppId, someNamespace); //must stop the long polling before exception occurred remoteConfigLongPollService.stopLongPollingRefresh(); @@ -251,7 +258,7 @@ public void testRepositoryChangeListener() throws Exception { when(someResponse.getBody()).thenReturn(someApolloConfig); RepositoryChangeListener someListener = mock(RepositoryChangeListener.class); - RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someNamespace); + RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someAppId, someNamespace); remoteConfigRepository.addChangeListener(someListener); final ArgumentCaptor captor = ArgumentCaptor.forClass(Properties.class); @@ -262,7 +269,7 @@ public void testRepositoryChangeListener() throws Exception { remoteConfigRepository.sync(); - verify(someListener, times(1)).onRepositoryChange(eq(someNamespace), captor.capture()); + verify(someListener, times(1)).onRepositoryChange(eq(someAppId), eq(someNamespace), captor.capture()); assertEquals(newConfigurations, captor.getValue()); } @@ -285,9 +292,9 @@ public Void answer(InvocationOnMock invocation) throws Throwable { return null; } - }).when(someListener).onRepositoryChange(any(String.class), any(Properties.class)); + }).when(someListener).onRepositoryChange(any(String.class), any(String.class), any(Properties.class)); - RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someNamespace); + RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someAppId, someNamespace); remoteConfigRepository.addChangeListener(someListener); final ArgumentCaptor captor = ArgumentCaptor.forClass(Properties.class); @@ -311,7 +318,7 @@ public Void answer(InvocationOnMock invocation) throws Throwable { remoteConfigLongPollService.stopLongPollingRefresh(); - verify(someListener, times(1)).onRepositoryChange(eq(someNamespace), captor.capture()); + verify(someListener, times(1)).onRepositoryChange(eq(someAppId), eq(someNamespace), captor.capture()); assertEquals(newConfigurations, captor.getValue()); final ArgumentCaptor httpRequestArgumentCaptor = ArgumentCaptor @@ -339,7 +346,7 @@ public void testAssembleQueryConfigUrl() throws Exception { notificationMessages.put(someKey, someNotificationId); notificationMessages.put(anotherKey, anotherNotificationId); - RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someNamespace); + RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someAppId, someNamespace); ApolloConfig someApolloConfig = mock(ApolloConfig.class); when(someApolloConfig.getReleaseKey()).thenReturn(someReleaseKey); @@ -416,6 +423,14 @@ public TimeUnit getOnErrorRetryIntervalTimeUnit() { public long getLongPollingInitialDelayInMills() { return 0; } + + @Override + public String getAccessKeySecret(String appId){ + if(appId.equals(someAppId)){ + return someSecret; + } + return null; + } } public static class MockHttpClient implements HttpClient { diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/SimpleConfigTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/SimpleConfigTest.java index ee3fd753..b192002d 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/SimpleConfigTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/SimpleConfigTest.java @@ -49,6 +49,7 @@ @RunWith(MockitoJUnitRunner.class) public class SimpleConfigTest { + private String someAppId; private String someNamespace; @Mock private ConfigRepository configRepository; @@ -58,6 +59,7 @@ public class SimpleConfigTest { @Before public void setUp() throws Exception { + someAppId = "someAppId"; someNamespace = "someName"; when(propertiesFactory.getPropertiesInstance()).thenAnswer(new Answer() { @@ -86,7 +88,7 @@ public void testGetProperty() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); when(configRepository.getSourceType()).thenReturn(someSourceType); - SimpleConfig config = new SimpleConfig(someNamespace, configRepository); + SimpleConfig config = new SimpleConfig(someAppId, someNamespace, configRepository); assertEquals(someValue, config.getProperty(someKey, null)); assertEquals(someSourceType, config.getSourceType()); @@ -99,7 +101,7 @@ public void testLoadConfigFromConfigRepositoryError() throws Exception { when(configRepository.getConfig()).thenThrow(mock(RuntimeException.class)); - Config config = new SimpleConfig(someNamespace, configRepository); + Config config = new SimpleConfig(someAppId, someNamespace, configRepository); assertEquals(anyValue, config.getProperty(someKey, anyValue)); assertEquals(ConfigSourceType.NONE, config.getSourceType()); @@ -133,7 +135,7 @@ public void onChange(ConfigChangeEvent changeEvent) { } }; - SimpleConfig config = new SimpleConfig(someNamespace, configRepository); + SimpleConfig config = new SimpleConfig(someAppId, someNamespace, configRepository); assertEquals(someSourceType, config.getSourceType()); @@ -142,10 +144,11 @@ public void onChange(ConfigChangeEvent changeEvent) { ConfigSourceType anotherSourceType = ConfigSourceType.REMOTE; when(configRepository.getSourceType()).thenReturn(anotherSourceType); - config.onRepositoryChange(someNamespace, anotherProperties); + config.onRepositoryChange(someAppId, someNamespace, anotherProperties); ConfigChangeEvent changeEvent = configChangeFuture.get(500, TimeUnit.MILLISECONDS); + assertEquals(someAppId, changeEvent.getAppId()); assertEquals(someNamespace, changeEvent.getNamespace()); assertEquals(3, changeEvent.changedKeys().size()); diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/TxtConfigFileTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/TxtConfigFileTest.java index ee712e08..b9d3e238 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/TxtConfigFileTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/TxtConfigFileTest.java @@ -31,12 +31,14 @@ @RunWith(MockitoJUnitRunner.class) public class TxtConfigFileTest { + private String someAppId; private String someNamespace; @Mock private ConfigRepository configRepository; @Before public void setUp() throws Exception { + someAppId = "someAppId"; someNamespace = "someName"; } @@ -49,9 +51,10 @@ public void testWhenHasContent() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); - TxtConfigFile configFile = new TxtConfigFile(someNamespace, configRepository); + TxtConfigFile configFile = new TxtConfigFile(someAppId, someNamespace, configRepository); assertEquals(ConfigFileFormat.TXT, configFile.getConfigFileFormat()); + assertEquals(someAppId, configFile.getAppId()); assertEquals(someNamespace, configFile.getNamespace()); assertTrue(configFile.hasContent()); assertEquals(someValue, configFile.getContent()); diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/XmlConfigFileTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/XmlConfigFileTest.java index a875cab6..e4511f88 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/XmlConfigFileTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/XmlConfigFileTest.java @@ -49,6 +49,7 @@ @RunWith(MockitoJUnitRunner.class) public class XmlConfigFileTest { + private String someAppId; private String someNamespace; @Mock private ConfigRepository configRepository; @@ -57,6 +58,7 @@ public class XmlConfigFileTest { @Before public void setUp() throws Exception { + someAppId = "someAppId"; someNamespace = "someName"; when(propertiesFactory.getPropertiesInstance()).thenAnswer(new Answer() { @@ -83,7 +85,7 @@ public void testWhenHasContent() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); - XmlConfigFile configFile = new XmlConfigFile(someNamespace, configRepository); + XmlConfigFile configFile = new XmlConfigFile(someAppId, someNamespace, configRepository); assertEquals(ConfigFileFormat.XML, configFile.getConfigFileFormat()); assertEquals(someNamespace, configFile.getNamespace()); @@ -95,7 +97,7 @@ public void testWhenHasContent() throws Exception { public void testWhenHasNoContent() throws Exception { when(configRepository.getConfig()).thenReturn(null); - XmlConfigFile configFile = new XmlConfigFile(someNamespace, configRepository); + XmlConfigFile configFile = new XmlConfigFile(someAppId, someNamespace, configRepository); assertFalse(configFile.hasContent()); assertNull(configFile.getContent()); @@ -105,7 +107,7 @@ public void testWhenHasNoContent() throws Exception { public void testWhenConfigRepositoryHasError() throws Exception { when(configRepository.getConfig()).thenThrow(new RuntimeException("someError")); - XmlConfigFile configFile = new XmlConfigFile(someNamespace, configRepository); + XmlConfigFile configFile = new XmlConfigFile(someAppId, someNamespace, configRepository); assertFalse(configFile.hasContent()); assertNull(configFile.getContent()); @@ -121,7 +123,7 @@ public void testOnRepositoryChange() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); - XmlConfigFile configFile = new XmlConfigFile(someNamespace, configRepository); + XmlConfigFile configFile = new XmlConfigFile(someAppId, someNamespace, configRepository); assertEquals(someValue, configFile.getContent()); @@ -138,7 +140,7 @@ public void onChange(ConfigFileChangeEvent changeEvent) { configFile.addChangeListener(someListener); - configFile.onRepositoryChange(someNamespace, anotherProperties); + configFile.onRepositoryChange(someAppId, someNamespace, anotherProperties); ConfigFileChangeEvent changeEvent = configFileChangeFuture.get(500, TimeUnit.MILLISECONDS); @@ -157,7 +159,7 @@ public void testOnRepositoryChangeWithContentAdded() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); - XmlConfigFile configFile = new XmlConfigFile(someNamespace, configRepository); + XmlConfigFile configFile = new XmlConfigFile(someAppId, someNamespace, configRepository); assertEquals(null, configFile.getContent()); @@ -194,7 +196,7 @@ public void testOnRepositoryChangeWithContentDeleted() throws Exception { when(configRepository.getConfig()).thenReturn(someProperties); - XmlConfigFile configFile = new XmlConfigFile(someNamespace, configRepository); + XmlConfigFile configFile = new XmlConfigFile(someAppId, someNamespace, configRepository); assertEquals(someValue, configFile.getContent()); @@ -230,12 +232,12 @@ public void testWhenConfigRepositoryHasErrorAndThenRecovered() throws Exception when(configRepository.getConfig()).thenThrow(new RuntimeException("someError")); - XmlConfigFile configFile = new XmlConfigFile(someNamespace, configRepository); + XmlConfigFile configFile = new XmlConfigFile(someAppId, someNamespace, configRepository); assertFalse(configFile.hasContent()); assertNull(configFile.getContent()); - configFile.onRepositoryChange(someNamespace, someProperties); + configFile.onRepositoryChange(someAppId, someNamespace, someProperties); assertTrue(configFile.hasContent()); assertEquals(someValue, configFile.getContent()); diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/YamlConfigFileTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/YamlConfigFileTest.java index b856d3ec..099953d9 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/YamlConfigFileTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/YamlConfigFileTest.java @@ -39,6 +39,7 @@ @RunWith(MockitoJUnitRunner.class) public class YamlConfigFileTest { + private String someAppId; private String someNamespace; @Mock private ConfigRepository configRepository; @@ -51,6 +52,7 @@ public class YamlConfigFileTest { @Before public void setUp() throws Exception { + someAppId = "someAppId"; someNamespace = "someName"; MockInjector.setInstance(YamlParser.class, yamlParser); @@ -84,7 +86,7 @@ public void testWhenHasContent() throws Exception { when(configRepository.getSourceType()).thenReturn(someSourceType); when(yamlParser.yamlToProperties(someContent)).thenReturn(yamlProperties); - YamlConfigFile configFile = new YamlConfigFile(someNamespace, configRepository); + YamlConfigFile configFile = new YamlConfigFile(someAppId, someNamespace, configRepository); assertSame(someContent, configFile.getContent()); assertSame(yamlProperties, configFile.asProperties()); @@ -110,7 +112,7 @@ public Properties answer(InvocationOnMock invocation) { when(configRepository.getSourceType()).thenReturn(someSourceType); when(yamlParser.yamlToProperties(someContent)).thenReturn(yamlProperties); - YamlConfigFile configFile = new YamlConfigFile(someNamespace, configRepository); + YamlConfigFile configFile = new YamlConfigFile(someAppId, someNamespace, configRepository); assertSame(someContent, configFile.getContent()); assertSame(yamlProperties, configFile.asProperties()); @@ -124,7 +126,7 @@ public Properties answer(InvocationOnMock invocation) { public void testWhenHasNoContent() throws Exception { when(configRepository.getConfig()).thenReturn(null); - YamlConfigFile configFile = new YamlConfigFile(someNamespace, configRepository); + YamlConfigFile configFile = new YamlConfigFile(someAppId, someNamespace, configRepository); assertFalse(configFile.hasContent()); assertNull(configFile.getContent()); @@ -147,7 +149,7 @@ public void testWhenInvalidYamlContent() throws Exception { when(yamlParser.yamlToProperties(someInvalidContent)) .thenThrow(new RuntimeException("some exception")); - YamlConfigFile configFile = new YamlConfigFile(someNamespace, configRepository); + YamlConfigFile configFile = new YamlConfigFile(someAppId, someNamespace, configRepository); assertSame(someInvalidContent, configFile.getContent()); @@ -166,7 +168,7 @@ public void testWhenInvalidYamlContent() throws Exception { public void testWhenConfigRepositoryHasError() throws Exception { when(configRepository.getConfig()).thenThrow(new RuntimeException("someError")); - YamlConfigFile configFile = new YamlConfigFile(someNamespace, configRepository); + YamlConfigFile configFile = new YamlConfigFile(someAppId, someNamespace, configRepository); assertFalse(configFile.hasContent()); assertNull(configFile.getContent()); @@ -198,7 +200,7 @@ public void testOnRepositoryChange() throws Exception { when(yamlParser.yamlToProperties(someValue)).thenReturn(someYamlProperties); when(yamlParser.yamlToProperties(anotherValue)).thenReturn(anotherYamlProperties); - YamlConfigFile configFile = new YamlConfigFile(someNamespace, configRepository); + YamlConfigFile configFile = new YamlConfigFile(someAppId, someNamespace, configRepository); assertEquals(someValue, configFile.getContent()); assertEquals(someSourceType, configFile.getSourceType()); @@ -210,7 +212,7 @@ public void testOnRepositoryChange() throws Exception { ConfigSourceType anotherSourceType = ConfigSourceType.REMOTE; when(configRepository.getSourceType()).thenReturn(anotherSourceType); - configFile.onRepositoryChange(someNamespace, anotherProperties); + configFile.onRepositoryChange(someAppId, someNamespace, anotherProperties); assertEquals(anotherValue, configFile.getContent()); assertEquals(anotherSourceType, configFile.getSourceType()); @@ -233,14 +235,14 @@ public void testWhenConfigRepositoryHasErrorAndThenRecovered() throws Exception when(configRepository.getSourceType()).thenReturn(someSourceType); when(yamlParser.yamlToProperties(someValue)).thenReturn(someYamlProperties); - YamlConfigFile configFile = new YamlConfigFile(someNamespace, configRepository); + YamlConfigFile configFile = new YamlConfigFile(someAppId, someNamespace, configRepository); assertFalse(configFile.hasContent()); assertNull(configFile.getContent()); assertEquals(ConfigSourceType.NONE, configFile.getSourceType()); assertTrue(configFile.asProperties().isEmpty()); - configFile.onRepositoryChange(someNamespace, someProperties); + configFile.onRepositoryChange(someAppId, someNamespace, someProperties); assertTrue(configFile.hasContent()); assertEquals(someValue, configFile.getContent()); diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryFileCachePropertyTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryFileCachePropertyTest.java index 69771900..5e048681 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryFileCachePropertyTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryFileCachePropertyTest.java @@ -38,10 +38,12 @@ public class DefaultConfigFactoryFileCachePropertyTest { private DefaultConfigFactory configFactory; private ConfigUtil someConfigUtil; + private String someAppId; private String someNamespace; @Before public void setUp() throws Exception { + someAppId = "someAppId"; someNamespace = "someNamespace"; someConfigUtil = mock(ConfigUtil.class); MockInjector.setInstance(ConfigUtil.class, someConfigUtil); @@ -53,11 +55,11 @@ public void testCreateFileEnableConfigRepository() throws Exception { LocalFileConfigRepository someLocalConfigRepository = mock(LocalFileConfigRepository.class); when(someConfigUtil.isPropertyFileCacheEnabled()).thenReturn(true); doReturn(someLocalConfigRepository).when(configFactory) - .createLocalConfigRepository(someNamespace); - ConfigRepository configRepository = configFactory.createConfigRepository(someNamespace); + .createLocalConfigRepository(someAppId, someNamespace); + ConfigRepository configRepository = configFactory.createConfigRepository(someAppId, someNamespace); assertSame(someLocalConfigRepository, configRepository); - verify(configFactory, times(1)).createLocalConfigRepository(someNamespace); - verify(configFactory, never()).createRemoteConfigRepository(someNamespace); + verify(configFactory, times(1)).createLocalConfigRepository(someAppId, someNamespace); + verify(configFactory, never()).createRemoteConfigRepository(someAppId, someNamespace); } @Test @@ -65,11 +67,11 @@ public void testCreateFileDisableConfigRepository() throws Exception { RemoteConfigRepository someRemoteConfigRepository = mock(RemoteConfigRepository.class); when(someConfigUtil.isPropertyFileCacheEnabled()).thenReturn(false); doReturn(someRemoteConfigRepository).when(configFactory) - .createRemoteConfigRepository(someNamespace); - ConfigRepository configRepository = configFactory.createConfigRepository(someNamespace); + .createRemoteConfigRepository(someAppId, someNamespace); + ConfigRepository configRepository = configFactory.createConfigRepository(someAppId, someNamespace); assertSame(someRemoteConfigRepository, configRepository); - verify(configFactory, never()).createLocalConfigRepository(someNamespace); - verify(configFactory, times(1)).createRemoteConfigRepository(someNamespace); + verify(configFactory, never()).createLocalConfigRepository(someAppId, someNamespace); + verify(configFactory, times(1)).createRemoteConfigRepository(someAppId, someNamespace); } @After diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryManagerTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryManagerTest.java index e72fcc6d..59b28dcd 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryManagerTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryManagerTest.java @@ -98,11 +98,21 @@ public Config create(String namespace) { return null; } + @Override + public Config create(String appId, String namespace) { + return null; + } + @Override public ConfigFile createConfigFile(String namespace, ConfigFileFormat configFileFormat) { return null; } + @Override + public ConfigFile createConfigFile(String appId, String namespace, ConfigFileFormat configFileFormat) { + return null; + } + }; @Override @@ -110,6 +120,11 @@ public void register(String namespace, ConfigFactory factory) { //do nothing } + @Override + public void register(String appId, String namespace, ConfigFactory factory) { + + } + @Override public ConfigFactory getFactory(String namespace) { if (namespace.equals(NAMESPACE_REGISTERED)) { @@ -117,6 +132,14 @@ public ConfigFactory getFactory(String namespace) { } return null; } + + @Override + public ConfigFactory getFactory(String appId, String namespace) { + if (namespace.equals(NAMESPACE_REGISTERED)) { + return REGISTERED_CONFIGFACTORY; + } + return null; + } } public static class SomeConfigFactory implements ConfigFactory { @@ -125,10 +148,20 @@ public Config create(String namespace) { return null; } + @Override + public Config create(String appId, String namespace) { + return null; + } + @Override public ConfigFile createConfigFile(String namespace, ConfigFileFormat configFileFormat) { return null; } + + @Override + public ConfigFile createConfigFile(String appId, String namespace, ConfigFileFormat configFileFormat) { + return null; + } } public static class AnotherConfigFactory implements ConfigFactory { @@ -137,10 +170,20 @@ public Config create(String namespace) { return null; } + @Override + public Config create(String appId, String namespace) { + return null; + } + @Override public ConfigFile createConfigFile(String namespace, ConfigFileFormat configFileFormat) { return null; } + + @Override + public ConfigFile createConfigFile(String appId, String namespace, ConfigFileFormat configFileFormat) { + return null; + } } } diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryTest.java index fb670fe5..5f2c6f18 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryTest.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; +import com.ctrip.framework.apollo.core.ConfigConsts; import com.ctrip.framework.apollo.internals.PropertiesCompatibleFileConfigRepository; import java.util.Properties; @@ -58,7 +59,7 @@ public class DefaultConfigFactoryTest { @Before public void setUp() throws Exception { - someAppId = "someId"; + someAppId = "someAppId"; someEnv = Env.DEV; MockInjector.setInstance(ConfigUtil.class, new MockConfigUtil()); defaultConfigFactory = spy(new DefaultConfigFactory()); @@ -80,7 +81,7 @@ public void testCreate() throws Exception { LocalFileConfigRepository someLocalConfigRepo = mock(LocalFileConfigRepository.class); when(someLocalConfigRepo.getConfig()).thenReturn(someProperties); - doReturn(someLocalConfigRepo).when(defaultConfigFactory).createConfigRepository(someNamespace); + doReturn(someLocalConfigRepo).when(defaultConfigFactory).createConfigRepository(someAppId, someNamespace); Config result = defaultConfigFactory.create(someNamespace); @@ -95,7 +96,7 @@ public void testCreateLocalConfigRepositoryInLocalDev() throws Exception { someEnv = Env.LOCAL; LocalFileConfigRepository localFileConfigRepository = - defaultConfigFactory.createLocalConfigRepository(someNamespace); + defaultConfigFactory.createLocalConfigRepository(someAppId, someNamespace); assertNull(ReflectionTestUtils.getField(localFileConfigRepository, "m_upstream")); } @@ -113,9 +114,9 @@ public void testCreatePropertiesCompatibleFileConfigRepository() throws Exceptio when(someRepository.getConfig()).thenReturn(someProperties); doReturn(someRepository).when(defaultConfigFactory) - .createPropertiesCompatibleFileConfigRepository(someNamespace, somePropertiesCompatibleFormat); + .createPropertiesCompatibleFileConfigRepository(someAppId, someNamespace, somePropertiesCompatibleFormat); - Config result = defaultConfigFactory.create(someNamespace); + Config result = defaultConfigFactory.create(someAppId, someNamespace); assertThat("DefaultConfigFactory should create DefaultConfig", result, is(instanceOf(DefaultConfig.class))); @@ -132,9 +133,9 @@ public void testCreateConfigFile() throws Exception { LocalFileConfigRepository someLocalConfigRepo = mock(LocalFileConfigRepository.class); when(someLocalConfigRepo.getConfig()).thenReturn(someProperties); - doReturn(someLocalConfigRepo).when(defaultConfigFactory).createLocalConfigRepository(someNamespace); - doReturn(someLocalConfigRepo).when(defaultConfigFactory).createLocalConfigRepository(anotherNamespace); - doReturn(someLocalConfigRepo).when(defaultConfigFactory).createLocalConfigRepository(yetAnotherNamespace); + doReturn(someLocalConfigRepo).when(defaultConfigFactory).createLocalConfigRepository(someAppId, someNamespace); + doReturn(someLocalConfigRepo).when(defaultConfigFactory).createLocalConfigRepository(someAppId, anotherNamespace); + doReturn(someLocalConfigRepo).when(defaultConfigFactory).createLocalConfigRepository(someAppId, yetAnotherNamespace); ConfigFile propertyConfigFile = defaultConfigFactory.createConfigFile(someNamespace, ConfigFileFormat.Properties); @@ -187,27 +188,32 @@ public void testDetermineFileFormat() throws Exception { @Test public void testTrimNamespaceFormat() throws Exception { - checkNamespaceName("abc", ConfigFileFormat.Properties, "abc"); - checkNamespaceName("abc.properties", ConfigFileFormat.Properties, "abc"); - checkNamespaceName("abcproperties", ConfigFileFormat.Properties, "abcproperties"); - checkNamespaceName("abc.pRopErties", ConfigFileFormat.Properties, "abc"); - checkNamespaceName("abc.xml", ConfigFileFormat.XML, "abc"); - checkNamespaceName("abc.xmL", ConfigFileFormat.XML, "abc"); - checkNamespaceName("abc.json", ConfigFileFormat.JSON, "abc"); - checkNamespaceName("abc.jsOn", ConfigFileFormat.JSON, "abc"); - checkNamespaceName("abc.yaml", ConfigFileFormat.YAML, "abc"); - checkNamespaceName("abc.yAml", ConfigFileFormat.YAML, "abc"); - checkNamespaceName("abc.yml", ConfigFileFormat.YML, "abc"); - checkNamespaceName("abc.yMl", ConfigFileFormat.YML, "abc"); - checkNamespaceName("abc.proPerties.yml", ConfigFileFormat.YML, "abc.proPerties"); + checkNamespaceName("abc", ConfigFileFormat.Properties, appIdAndNamespace("abc")); + checkNamespaceName("abc.properties", ConfigFileFormat.Properties, appIdAndNamespace("abc")); + checkNamespaceName("abcproperties", ConfigFileFormat.Properties, appIdAndNamespace("abcproperties")); + checkNamespaceName("abc.pRopErties", ConfigFileFormat.Properties, appIdAndNamespace("abc")); + checkNamespaceName("abc.xml", ConfigFileFormat.XML, appIdAndNamespace("abc")); + checkNamespaceName("abc.xmL", ConfigFileFormat.XML, appIdAndNamespace("abc")); + checkNamespaceName("abc.json", ConfigFileFormat.JSON, appIdAndNamespace("abc")); + checkNamespaceName("abc.jsOn", ConfigFileFormat.JSON, appIdAndNamespace("abc")); + checkNamespaceName("abc.yaml", ConfigFileFormat.YAML, appIdAndNamespace("abc")); + checkNamespaceName("abc.yAml", ConfigFileFormat.YAML, appIdAndNamespace("abc")); + checkNamespaceName("abc.yml", ConfigFileFormat.YML, appIdAndNamespace("abc")); + checkNamespaceName("abc.yMl", ConfigFileFormat.YML, appIdAndNamespace("abc")); + checkNamespaceName("abc.proPerties.yml", ConfigFileFormat.YML, appIdAndNamespace("abc.proPerties")); + } + + private String appIdAndNamespace(String namespace){ + return namespace; } + private void checkFileFormat(String namespaceName, ConfigFileFormat expectedFormat) { assertEquals(expectedFormat, defaultConfigFactory.determineFileFormat(namespaceName)); } private void checkNamespaceName(String namespaceName, ConfigFileFormat format, String expectedNamespaceName) { - assertEquals(expectedNamespaceName, defaultConfigFactory.trimNamespaceFormat(namespaceName, format)); + assertEquals(expectedNamespaceName, defaultConfigFactory.trimNamespaceFormat(someAppId, namespaceName, format)); } public static class MockConfigUtil extends ConfigUtil { diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigRegistryTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigRegistryTest.java index 27d3ce62..cb2da099 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigRegistryTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigRegistryTest.java @@ -63,9 +63,19 @@ public Config create(String namespace) { return null; } + @Override + public Config create(String appId, String namespace) { + return null; + } + @Override public ConfigFile createConfigFile(String namespace, ConfigFileFormat configFileFormat) { return null; } + + @Override + public ConfigFile createConfigFile(String appId, String namespace, ConfigFileFormat configFileFormat) { + return null; + } } } diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/AbstractSpringIntegrationTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/AbstractSpringIntegrationTest.java index c8b22d30..de300f38 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/AbstractSpringIntegrationTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/AbstractSpringIntegrationTest.java @@ -20,6 +20,10 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; +import com.ctrip.framework.apollo.ConfigServiceTest; +import com.ctrip.framework.apollo.ConfigServiceTest.MockConfigUtil; +import com.ctrip.framework.apollo.build.ApolloInjector; +import com.ctrip.framework.apollo.core.ApolloClientSystemConsts; import com.ctrip.framework.apollo.core.ConfigConsts; import com.ctrip.framework.apollo.internals.ConfigRepository; import com.ctrip.framework.apollo.internals.DefaultInjector; @@ -27,6 +31,8 @@ import com.ctrip.framework.apollo.internals.YamlConfigFile; import com.ctrip.framework.apollo.spring.config.PropertySourcesProcessor; import com.ctrip.framework.apollo.util.ConfigUtil; +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Table; import com.google.common.io.CharStreams; import java.io.IOException; import java.io.InputStream; @@ -59,7 +65,7 @@ * @author Jason Song(song_s@ctrip.com) */ public abstract class AbstractSpringIntegrationTest { - private static final Map CONFIG_REGISTRY = Maps.newHashMap(); + private static final Table CONFIG_REGISTRY = HashBasedTable.create(); private static final Map CONFIG_FILE_REGISTRY = Maps.newHashMap(); private static Method CONFIG_SERVICE_RESET; private static Method PROPERTY_SOURCES_PROCESSOR_RESET; @@ -85,14 +91,14 @@ public void tearDown() throws Exception { doTearDown(); } - protected SimpleConfig prepareConfig(String namespaceName, Properties properties) { + protected SimpleConfig prepareConfig(String appId, String namespaceName, Properties properties) { ConfigRepository configRepository = mock(ConfigRepository.class); when(configRepository.getConfig()).thenReturn(properties); - SimpleConfig config = new SimpleConfig(ConfigConsts.NAMESPACE_APPLICATION, configRepository); + SimpleConfig config = new SimpleConfig(appId, ConfigConsts.NAMESPACE_APPLICATION, configRepository); - mockConfig(namespaceName, config); + mockConfig(appId, namespaceName, config); return config; } @@ -113,15 +119,15 @@ protected static Properties readYamlContentAsConfigFileProperties(String caseNam return properties; } - protected static YamlConfigFile prepareYamlConfigFile(String namespaceNameWithFormat, Properties properties) { + protected static YamlConfigFile prepareYamlConfigFile(String appId, String namespaceNameWithFormat, Properties properties) { ConfigRepository configRepository = mock(ConfigRepository.class); when(configRepository.getConfig()).thenReturn(properties); // spy it for testing after - YamlConfigFile configFile = spy(new YamlConfigFile(namespaceNameWithFormat, configRepository)); + YamlConfigFile configFile = spy(new YamlConfigFile(appId, namespaceNameWithFormat, configRepository)); - mockConfigFile(namespaceNameWithFormat, configFile); + mockConfigFile(appId, namespaceNameWithFormat, configFile); return configFile; } @@ -161,15 +167,21 @@ protected Date assembleDate(int year, int month, int day, int hour, int minute, } - protected static void mockConfig(String namespace, Config config) { - CONFIG_REGISTRY.put(namespace, config); + protected static void mockConfig(String appId, String namespace, Config config) { + CONFIG_REGISTRY.put(appId, namespace, config); } protected static void mockConfigFile(String namespaceNameWithFormat, ConfigFile configFile) { CONFIG_FILE_REGISTRY.put(namespaceNameWithFormat, configFile); } - protected static void doSetUp() { + protected static void mockConfigFile(String appId,String namespaceNameWithFormat, ConfigFile configFile) { + CONFIG_FILE_REGISTRY.put(appId + "+" + namespaceNameWithFormat, configFile); + } + + protected static void doSetUp() throws Exception { + System.setProperty(ApolloClientSystemConsts.APP_ID, "someAppId"); + //as ConfigService is singleton, so we must manually clear its container ReflectionUtils.invokeMethod(CONFIG_SERVICE_RESET, null); //as PropertySourcesProcessor has some static variables, so we must manually clear them @@ -178,9 +190,18 @@ protected static void doSetUp() { ConfigManager defaultConfigManager = defaultInjector.getInstance(ConfigManager.class); MockInjector.setInstance(ConfigManager.class, new MockConfigManager(defaultConfigManager)); MockInjector.setDelegate(defaultInjector); + + MockConfigUtil configUtil = new MockConfigUtil(); + configUtil.setAutoUpdateInjectedSpringProperties(true); + MockInjector.setInstance(ConfigUtil.class, configUtil); + +/* Field field = PropertySourcesProcessor.class.getDeclaredField("configUtil"); + field.setAccessible(true); + field.set(null, configUtil);*/ + } - protected static void doTearDown() { + protected static void doTearDown(){ MockInjector.reset(); CONFIG_REGISTRY.clear(); } @@ -195,16 +216,26 @@ public MockConfigManager(ConfigManager delegate) { @Override public Config getConfig(String namespace) { - Config config = CONFIG_REGISTRY.get(namespace); + return getConfig("someAppId", namespace); + } + + @Override + public Config getConfig(String appId, String namespace) { + Config config = CONFIG_REGISTRY.get(appId, namespace); if (config != null) { return config; } - return delegate.getConfig(namespace); + return delegate.getConfig(appId, namespace); } @Override public ConfigFile getConfigFile(String namespace, ConfigFileFormat configFileFormat) { - ConfigFile configFile = CONFIG_FILE_REGISTRY.get(String.format("%s.%s", namespace, configFileFormat.getValue())); + return this.getConfigFile("someAppId", namespace, configFileFormat); + } + + @Override + public ConfigFile getConfigFile(String appId, String namespace, ConfigFileFormat configFileFormat) { + ConfigFile configFile = CONFIG_FILE_REGISTRY.get(String.format("%s+%s.%s", appId, namespace, configFileFormat.getValue())); if (configFile != null) { return configFile; } @@ -224,5 +255,9 @@ public void setAutoUpdateInjectedSpringProperties(boolean autoUpdateInjectedSpri public boolean isAutoUpdateInjectedSpringPropertiesEnabled() { return isAutoUpdateInjectedSpringProperties; } + + public String getAppId() { + return "someAppId"; + } } } diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/BootstrapConfigTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/BootstrapConfigTest.java index 1e0cd750..8a8ae90e 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/BootstrapConfigTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/BootstrapConfigTest.java @@ -57,11 +57,14 @@ public class BootstrapConfigTest { private static final String TEST_BEAN_CONDITIONAL_ON_KEY = "apollo.test.testBean"; private static final String FX_APOLLO_NAMESPACE = "FX.apollo"; + private static final String someAppId = "someAppId"; + @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = ConfigurationWithConditionalOnProperty.class) @DirtiesContext public static class TestWithBootstrapEnabledAndDefaultNamespacesAndConditionalOn extends AbstractSpringIntegrationTest { + private static final String someProperty = "someProperty"; private static final String someValue = "someValue"; @@ -90,7 +93,7 @@ public static void beforeClass() throws Exception { when(mockedConfig.getProperty(eq(TEST_BEAN_CONDITIONAL_ON_KEY), Mockito.nullable(String.class))).thenReturn(Boolean.TRUE.toString()); when(mockedConfig.getProperty(eq(someProperty), Mockito.nullable(String.class))).thenReturn(someValue); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, mockedConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, mockedConfig); } @AfterClass @@ -134,8 +137,8 @@ public static void beforeClass() throws Exception { when(config.getPropertyNames()).thenReturn(Sets.newHashSet(TEST_BEAN_CONDITIONAL_ON_KEY)); when(config.getProperty(eq(TEST_BEAN_CONDITIONAL_ON_KEY), Mockito.nullable(String.class))).thenReturn(Boolean.TRUE.toString()); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, anotherConfig); - mockConfig(FX_APOLLO_NAMESPACE, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, anotherConfig); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, config); } @AfterClass @@ -170,11 +173,11 @@ public static void beforeClass() throws Exception { System.setProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_NAMESPACES, String.format("%s, %s", "application.yml", FX_APOLLO_NAMESPACE)); - prepareYamlConfigFile("application.yml", readYamlContentAsConfigFileProperties("case6.yml")); + prepareYamlConfigFile(someAppId, "application.yml", readYamlContentAsConfigFileProperties("case6.yml")); Config anotherConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, anotherConfig); - mockConfig(FX_APOLLO_NAMESPACE, anotherConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, anotherConfig); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, anotherConfig); } @AfterClass @@ -212,7 +215,7 @@ public static void beforeClass() throws Exception { when(config.getPropertyNames()).thenReturn(Sets.newHashSet(TEST_BEAN_CONDITIONAL_ON_KEY)); when(config.getProperty(eq(TEST_BEAN_CONDITIONAL_ON_KEY), Mockito.nullable(String.class))).thenReturn(Boolean.FALSE.toString()); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); } @AfterClass @@ -244,7 +247,7 @@ public static void beforeClass() throws Exception { System.setProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED, "true"); System.setProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_NAMESPACES, "application.yml"); - prepareYamlConfigFile("application.yml", readYamlContentAsConfigFileProperties("case7.yml")); + prepareYamlConfigFile(someAppId, "application.yml", readYamlContentAsConfigFileProperties("case7.yml")); } @AfterClass @@ -278,7 +281,7 @@ public static void beforeClass() throws Exception { Config config = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); } @AfterClass @@ -311,7 +314,7 @@ public static void beforeClass() throws Exception { System.setProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED, "true"); System.setProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_NAMESPACES, "application.yml"); - prepareYamlConfigFile("application.yml", readYamlContentAsConfigFileProperties("case8.yml")); + prepareYamlConfigFile(someAppId, "application.yml", readYamlContentAsConfigFileProperties("case8.yml")); } @AfterClass @@ -347,7 +350,7 @@ public static void beforeClass() throws Exception { when(config.getPropertyNames()).thenReturn(Sets.newHashSet(TEST_BEAN_CONDITIONAL_ON_KEY)); when(config.getProperty(eq(TEST_BEAN_CONDITIONAL_ON_KEY), Mockito.nullable(String.class))).thenReturn(Boolean.FALSE.toString()); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); } @AfterClass @@ -376,7 +379,7 @@ public static void beforeClass() throws Exception { Config config = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); } @AfterClass @@ -400,7 +403,7 @@ public static class TestWithBootstrapEnabledAndEagerLoadEnabled extends AbstractSpringIntegrationTest { @BeforeClass - public static void beforeClass() { + public static void beforeClass() throws Exception { doSetUp(); System.setProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED, "true"); @@ -408,11 +411,11 @@ public static void beforeClass() { Config config = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); } @AfterClass - public static void afterClass() { + public static void afterClass() throws NoSuchFieldException, IllegalAccessException { System.clearProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED); System.clearProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_EAGER_LOAD_ENABLED); diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigAnnotationTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigAnnotationTest.java index b95131e6..642d6c47 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigAnnotationTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigAnnotationTest.java @@ -19,6 +19,7 @@ import com.ctrip.framework.apollo.Config; import com.ctrip.framework.apollo.ConfigChangeListener; import com.ctrip.framework.apollo.ConfigFileChangeListener; +import com.ctrip.framework.apollo.build.MockInjector; import com.ctrip.framework.apollo.core.ApolloClientSystemConsts; import com.ctrip.framework.apollo.core.ConfigConsts; import com.ctrip.framework.apollo.internals.SimpleConfig; @@ -28,10 +29,14 @@ import com.ctrip.framework.apollo.spring.annotation.ApolloConfig; import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener; import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig; +import com.ctrip.framework.apollo.spring.annotation.MultipleConfig; +import com.ctrip.framework.apollo.spring.config.PropertySourcesProcessor; +import com.ctrip.framework.apollo.util.ConfigUtil; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.common.util.concurrent.SettableFuture; import java.io.IOException; +import java.lang.reflect.Field; import java.util.Collections; import java.util.Properties; import java.util.UUID; @@ -72,6 +77,8 @@ * @author Jason Song(song_s@ctrip.com) */ public class JavaConfigAnnotationTest extends AbstractSpringIntegrationTest { + + private static final String someAppId = "someAppId"; private static final String FX_APOLLO_NAMESPACE = "FX.apollo"; private static final String APPLICATION_YAML_NAMESPACE = "application.yaml"; @@ -106,10 +113,10 @@ public void testApolloConfig() throws Exception { String someKey = "someKey"; String someValue = "someValue"; - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); - mockConfig(FX_APOLLO_NAMESPACE, fxApolloConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, fxApolloConfig); - prepareYamlConfigFile(APPLICATION_YAML_NAMESPACE, readYamlContentAsConfigFileProperties("case9.yml")); + prepareYamlConfigFile(someAppId, APPLICATION_YAML_NAMESPACE, readYamlContentAsConfigFileProperties("case9.yml")); TestApolloConfigBean1 bean = getBean(TestApolloConfigBean1.class, AppConfig1.class); @@ -125,7 +132,7 @@ public void testApolloConfig() throws Exception { public void testApolloConfigWithWrongFieldType() throws Exception { Config applicationConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); getBean(TestApolloConfigBean2.class, AppConfig2.class); } @@ -135,9 +142,9 @@ public void testApolloConfigWithInheritance() throws Exception { Config applicationConfig = mock(Config.class); Config fxApolloConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); - mockConfig(FX_APOLLO_NAMESPACE, fxApolloConfig); - prepareYamlConfigFile(APPLICATION_YAML_NAMESPACE, readYamlContentAsConfigFileProperties("case9.yml")); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, fxApolloConfig); + prepareYamlConfigFile(someAppId, APPLICATION_YAML_NAMESPACE, readYamlContentAsConfigFileProperties("case9.yml")); TestApolloChildConfigBean bean = getBean(TestApolloChildConfigBean.class, AppConfig6.class); @@ -151,10 +158,10 @@ public void testApolloConfigWithInheritance() throws Exception { public void testEnableApolloConfigResolveExpressionSimple() { String someKey = "someKey-2020-11-14-1750"; String someValue = UUID.randomUUID().toString(); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, mock(Config.class)); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, mock(Config.class)); Config xxxConfig = mock(Config.class); when(xxxConfig.getProperty(eq(someKey), Mockito.nullable(String.class))).thenReturn(someValue); - mockConfig("xxx", xxxConfig); + mockConfig(someAppId, "xxx", xxxConfig); TestEnableApolloConfigResolveExpressionWithDefaultValueConfiguration configuration = getSimpleBean(TestEnableApolloConfigResolveExpressionWithDefaultValueConfiguration.class); @@ -166,7 +173,7 @@ public void testEnableApolloConfigResolveExpressionSimple() { @Test public void testEnableApolloConfigResolveExpressionFromSystemProperty() { - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, mock(Config.class)); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, mock(Config.class)); final String someKey = "someKey-2020-11-14-1750"; final String someValue = UUID.randomUUID().toString(); @@ -175,7 +182,7 @@ public void testEnableApolloConfigResolveExpressionFromSystemProperty() { Config yyyConfig = mock(Config.class); when(yyyConfig.getProperty(eq(someKey), Mockito.nullable(String.class))).thenReturn(someValue); - mockConfig(resolvedNamespaceName, yyyConfig); + mockConfig(someAppId, resolvedNamespaceName, yyyConfig); TestEnableApolloConfigResolveExpressionWithDefaultValueConfiguration configuration = getSimpleBean(TestEnableApolloConfigResolveExpressionWithDefaultValueConfiguration.class); @@ -187,8 +194,8 @@ public void testEnableApolloConfigResolveExpressionFromSystemProperty() { @Test(expected = BeanCreationException.class) public void testEnableApolloConfigUnresolvedValueInField() { - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, mock(Config.class)); - mockConfig("xxx", mock(Config.class)); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, mock(Config.class)); + mockConfig(someAppId, "xxx", mock(Config.class)); getSimpleBean(TestEnableApolloConfigResolveExpressionWithDefaultValueConfiguration.class); } @@ -202,8 +209,8 @@ public void testApolloConfigChangeListener() throws Exception { Config applicationConfig = mock(Config.class); Config fxApolloConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); - mockConfig(FX_APOLLO_NAMESPACE, fxApolloConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, fxApolloConfig); final List applicationListeners = Lists.newArrayList(); final List fxApolloListeners = Lists.newArrayList(); @@ -256,7 +263,7 @@ public Object answer(InvocationOnMock invocation) throws Throwable { public void testApolloConfigChangeListenerWithWrongParamType() throws Exception { Config applicationConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); getBean(TestApolloConfigChangeListenerBean2.class, AppConfig4.class); } @@ -265,7 +272,7 @@ public void testApolloConfigChangeListenerWithWrongParamType() throws Exception public void testApolloConfigChangeListenerWithWrongParamCount() throws Exception { Config applicationConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); getBean(TestApolloConfigChangeListenerBean3.class, AppConfig5.class); } @@ -275,8 +282,8 @@ public void testApolloConfigChangeListenerWithInheritance() throws Exception { Config applicationConfig = mock(Config.class); Config fxApolloConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); - mockConfig(FX_APOLLO_NAMESPACE, fxApolloConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, fxApolloConfig); final List applicationListeners = Lists.newArrayList(); final List fxApolloListeners = Lists.newArrayList(); @@ -332,8 +339,8 @@ public void testApolloConfigChangeListenerWithInterestedKeys() throws Exception Config applicationConfig = mock(Config.class); Config fxApolloConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); - mockConfig(FX_APOLLO_NAMESPACE, fxApolloConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, fxApolloConfig); TestApolloConfigChangeListenerWithInterestedKeysBean bean = getBean( TestApolloConfigChangeListenerWithInterestedKeysBean.class, AppConfig8.class); @@ -364,7 +371,7 @@ public void testApolloConfigChangeListenerWithInterestedKeys() throws Exception public void testApolloConfigChangeListenerWithInterestedKeyPrefixes() { Config applicationConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); TestApolloConfigChangeListenerWithInterestedKeyPrefixesBean bean = getBean( TestApolloConfigChangeListenerWithInterestedKeyPrefixesBean.class, AppConfig10.class); @@ -390,14 +397,14 @@ public void testApolloConfigChangeListenerWithInterestedKeyPrefixes_fire() throws InterruptedException { // default mock, useless here // just for speed up test without waiting - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, mock(Config.class)); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, mock(Config.class)); SimpleConfig simpleConfig = spy( - this.prepareConfig( - TestApolloConfigChangeListenerWithInterestedKeyPrefixesBean1.SPECIAL_NAMESPACE, + this.prepareConfig(someAppId, + TestApolloConfigChangeListenerWithInterestedKeyPrefixesBean1.SPECIAL_NAMESPACE, new Properties())); - mockConfig(TestApolloConfigChangeListenerWithInterestedKeyPrefixesBean1.SPECIAL_NAMESPACE, + mockConfig(someAppId, TestApolloConfigChangeListenerWithInterestedKeyPrefixesBean1.SPECIAL_NAMESPACE, simpleConfig); TestApolloConfigChangeListenerWithInterestedKeyPrefixesBean1 bean = getBean( @@ -429,7 +436,7 @@ public void testApolloConfigChangeListenerWithYamlFile() throws Exception { String someValue = "someValue"; String anotherValue = "anotherValue"; - YamlConfigFile configFile = prepareYamlConfigFile(APPLICATION_YAML_NAMESPACE, + YamlConfigFile configFile = prepareYamlConfigFile(someAppId, APPLICATION_YAML_NAMESPACE, readYamlContentAsConfigFileProperties("case9.yml")); TestApolloConfigChangeListenerWithYamlFile bean = getBean(TestApolloConfigChangeListenerWithYamlFile.class, AppConfig9.class); @@ -440,7 +447,7 @@ public void testApolloConfigChangeListenerWithYamlFile() throws Exception { assertEquals(someValue, yamlConfig.getProperty(someKey, null)); assertFalse(future.isDone()); - configFile.onRepositoryChange(APPLICATION_YAML_NAMESPACE, readYamlContentAsConfigFileProperties("case9-new.yml")); + configFile.onRepositoryChange(someAppId, APPLICATION_YAML_NAMESPACE, readYamlContentAsConfigFileProperties("case9-new.yml")); ConfigChangeEvent configChangeEvent = future.get(100, TimeUnit.MILLISECONDS); ConfigChange change = configChangeEvent.getChange(someKey); @@ -454,12 +461,21 @@ public void testApolloConfigChangeListenerWithYamlFile() throws Exception { public void testApolloConfigChangeListenerResolveExpressionSimple() { // for ignore, no listener use it Config ignoreConfig = mock(Config.class); - mockConfig("ignore.for.listener", ignoreConfig); + mockConfig(someAppId, "ignore.for.listener", ignoreConfig); Config applicationConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); System.setProperty(ApolloClientSystemConsts.APOLLO_PROPERTY_NAMES_CACHE_ENABLE, "true"); + MockConfigUtil configUtil = new MockConfigUtil(); + MockInjector.setInstance(ConfigUtil.class, configUtil); + +/* try { + Field field = PropertySourcesProcessor.class.getDeclaredField("configUtil"); + field.setAccessible(true); + field.set(null, configUtil); + } catch (Exception e) { + }*/ getSimpleBean(TestApolloConfigChangeListenerResolveExpressionSimpleConfiguration.class); @@ -483,13 +499,13 @@ public void testApolloConfigChangeListenerWithCommaSeparatedNameSpaces() { System.setProperty(SystemPropertyKeyConstants.DELIMITED_NAMESPACES, propValue); Config app1Config = mock(Config.class); - mockConfig("app1", app1Config); + mockConfig(someAppId, "app1", app1Config); Config app2Config = mock(Config.class); - mockConfig("app2", app2Config); + mockConfig(someAppId, "app2", app2Config); Config app3Config = mock(Config.class); - mockConfig("app3", app3Config); + mockConfig(someAppId, "app3", app3Config); getSimpleBean(TestApolloConfigChangeListenerWithCommaSeparatedNameSpaces.class); @@ -508,13 +524,13 @@ public void testApolloConfigChangeListenerWithCommaSeparatedNameSpacesMergedWith System.setProperty(SystemPropertyKeyConstants.DELIMITED_NAMESPACES, propValue); Config app1Config = mock(Config.class); - mockConfig("app1", app1Config); + mockConfig(someAppId, "app1", app1Config); Config app2Config = mock(Config.class); - mockConfig("app2", app2Config); + mockConfig(someAppId, "app2", app2Config); Config appConfig = mock(Config.class); - mockConfig("app", appConfig); + mockConfig(someAppId, "app", appConfig); getSimpleBean(TestApolloConfigChangeListenerWithCommaSeparatedNameSpacesMergedWithOnesInValue.class); @@ -529,12 +545,12 @@ public void testApolloConfigChangeListenerWithCommaSeparatedNameSpacesMergedWith @Test public void testApolloConfigChangeListenerResolveExpressionFromSystemProperty() { Config applicationConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); final String namespaceName = "magicRedis"; System.setProperty(SystemPropertyKeyConstants.REDIS_NAMESPACE, namespaceName); Config redisConfig = mock(Config.class); - mockConfig(namespaceName, redisConfig); + mockConfig(someAppId, namespaceName, redisConfig); getSimpleBean( TestApolloConfigChangeListenerResolveExpressionFromSystemPropertyConfiguration.class); @@ -553,10 +569,10 @@ public void testApolloConfigChangeListenerResolveExpressionFromApplicationNamesp Properties properties = new Properties(); properties.setProperty(namespaceKey, namespaceName); - this.prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + this.prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); Config mysqlConfig = mock(Config.class); - mockConfig(namespaceName, mysqlConfig); + mockConfig(someAppId, namespaceName, mysqlConfig); getSimpleBean( TestApolloConfigChangeListenerResolveExpressionFromApplicationNamespaceConfiguration.class); @@ -568,27 +584,27 @@ public void testApolloConfigChangeListenerResolveExpressionFromApplicationNamesp @Test(expected = BeanCreationException.class) public void testApolloConfigChangeListenerUnresolvedPlaceholder() { Config applicationConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); getSimpleBean(TestApolloConfigChangeListenerUnresolvedPlaceholderConfiguration.class); } @Test public void testApolloConfigChangeListenerResolveExpressionFromSelfYaml() throws IOException { - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, mock(Config.class)); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, mock(Config.class)); final String resolvedValue = "resolve.from.self.yml"; - YamlConfigFile yamlConfigFile = prepareYamlConfigFile(resolvedValue, readYamlContentAsConfigFileProperties(resolvedValue)); + YamlConfigFile yamlConfigFile = prepareYamlConfigFile(someAppId, resolvedValue, readYamlContentAsConfigFileProperties(resolvedValue)); getSimpleBean(TestApolloConfigChangeListenerResolveExpressionFromSelfYamlConfiguration.class); verify(yamlConfigFile, times(1)).addChangeListener(any(ConfigFileChangeListener.class)); } @Test public void testApolloConfigResolveExpressionDefault() { - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, mock(Config.class)); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, mock(Config.class)); Config defaultConfig = mock(Config.class); Config yamlConfig = mock(Config.class); - mockConfig("default-2020-11-14-1733", defaultConfig); - mockConfig(APPLICATION_YAML_NAMESPACE, yamlConfig); + mockConfig(someAppId, "default-2020-11-14-1733", defaultConfig); + mockConfig(someAppId, APPLICATION_YAML_NAMESPACE, yamlConfig); TestApolloConfigResolveExpressionDefaultConfiguration configuration = getSimpleBean( TestApolloConfigResolveExpressionDefaultConfiguration.class); assertSame(defaultConfig, configuration.getDefaultConfig()); @@ -597,7 +613,7 @@ public void testApolloConfigResolveExpressionDefault() { @Test public void testApolloConfigResolveExpressionFromSystemProperty() { - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, mock(Config.class)); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, mock(Config.class)); final String namespaceName = "xxx6"; final String yamlNamespaceName = "yyy8.yml"; @@ -605,8 +621,8 @@ public void testApolloConfigResolveExpressionFromSystemProperty() { System.setProperty(SystemPropertyKeyConstants.FROM_SYSTEM_YAML_NAMESPACE, yamlNamespaceName); Config config = mock(Config.class); Config yamlConfig = mock(Config.class); - mockConfig(namespaceName, config); - mockConfig(yamlNamespaceName, yamlConfig); + mockConfig(someAppId, namespaceName, config); + mockConfig(someAppId, yamlNamespaceName, yamlConfig); TestApolloConfigResolveExpressionFromSystemPropertyConfiguration configuration = getSimpleBean( TestApolloConfigResolveExpressionFromSystemPropertyConfiguration.class); assertSame(config, configuration.getConfig()); @@ -615,7 +631,7 @@ public void testApolloConfigResolveExpressionFromSystemProperty() { @Test(expected = BeanCreationException.class) public void testApolloConfigUnresolvedExpression() { - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, mock(Config.class)); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, mock(Config.class)); getSimpleBean(TestApolloConfigUnresolvedExpressionConfiguration.class); } @@ -629,18 +645,44 @@ public void testApolloConfigResolveExpressionFromApolloConfigNamespaceApplicatio Properties properties = new Properties(); properties.setProperty(SystemPropertyKeyConstants.FROM_NAMESPACE_APPLICATION_KEY, namespaceName); properties.setProperty(SystemPropertyKeyConstants.FROM_NAMESPACE_APPLICATION_KEY_YAML, yamlNamespaceName); - this.prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + this.prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); } final Config config = mock(Config.class); final Config yamlConfig = mock(Config.class); - mockConfig(namespaceName, config); - mockConfig(yamlNamespaceName, yamlConfig); + mockConfig(someAppId, namespaceName, config); + mockConfig(someAppId, yamlNamespaceName, yamlConfig); TestApolloConfigResolveExpressionFromApolloConfigNamespaceApplication configuration = getSimpleBean( TestApolloConfigResolveExpressionFromApolloConfigNamespaceApplication.class); assertSame(config, configuration.getConfig()); assertSame(yamlConfig, configuration.getYamlConfig()); } + @Test + public void testApolloMultipleConfig() throws IOException { + Config applicationConfig = mock(Config.class); + Config fxApolloConfig = mock(Config.class); + Config multipleConfig = mock(Config.class); + String someKey = "someKey"; + String someValue = "someValue"; + + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig("someAppId2", "namespace2", multipleConfig); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, fxApolloConfig); + + prepareYamlConfigFile(someAppId, APPLICATION_YAML_NAMESPACE, readYamlContentAsConfigFileProperties("case9.yml")); + + TestApolloConfigBean5 bean = getBean(TestApolloConfigBean5.class, TestApolloMultipleConfig.class); + + assertEquals(applicationConfig, bean.getConfig()); + assertEquals(multipleConfig, bean.getMultipleConfig()); + assertEquals(fxApolloConfig, bean.getYetAnotherConfig()); + + Config yamlConfig = bean.getYamlConfig(); + assertEquals(someValue, yamlConfig.getProperty(someKey, null)); + + + } + private static class SystemPropertyKeyConstants { static final String SIMPLE_NAMESPACE = "simple.namespace"; @@ -1057,4 +1099,43 @@ public Config getYamlConfig() { return yamlConfig; } } + + @Configuration + @EnableApolloConfig(value = {"FX_APOLLO_NAMESPACE", "APPLICATION_YAML_NAMESPACE"}, + multipleConfigs = {@MultipleConfig(appId = "someAppId2", namespaces = {"namespace2"})}) + static class TestApolloMultipleConfig{ + + @Bean + public TestApolloConfigBean5 bean(){ + return new TestApolloConfigBean5(); + } + + } + + static class TestApolloConfigBean5 { + @ApolloConfig + private Config config; + @ApolloConfig(appId = "someAppId2",value = "namespace2") + private Config multipleConfig; + @ApolloConfig(FX_APOLLO_NAMESPACE) + private Config yetAnotherConfig; + @ApolloConfig(APPLICATION_YAML_NAMESPACE) + private Config yamlConfig; + + public Config getConfig() { + return config; + } + + public Config getMultipleConfig() { + return multipleConfig; + } + + public Config getYetAnotherConfig() { + return yetAnotherConfig; + } + + public Config getYamlConfig() { + return yamlConfig; + } + } } diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderAutoUpdateTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderAutoUpdateTest.java index c5689049..52808e07 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderAutoUpdateTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderAutoUpdateTest.java @@ -52,6 +52,7 @@ public class JavaConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegrationTest { + private static final String someAppId = "someAppId"; private static final String TIMEOUT_PROPERTY = "timeout"; private static final int DEFAULT_TIMEOUT = 100; private static final String BATCH_PROPERTY = "batch"; @@ -70,7 +71,7 @@ public void testAutoUpdateWithOneNamespace() throws Exception { Properties properties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig1.class); @@ -97,7 +98,7 @@ public void testAutoUpdateWithOneYamlFile() throws Exception { int newTimeout = 1001; int newBatch = 2001; - YamlConfigFile configFile = prepareYamlConfigFile("application.yaml", + YamlConfigFile configFile = prepareYamlConfigFile(someAppId,"application.yaml", readYamlContentAsConfigFileProperties("case1.yaml")); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig12.class); @@ -125,7 +126,7 @@ public void testAutoUpdateWithValueAndXmlProperty() throws Exception { Properties properties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig8.class); @@ -157,7 +158,7 @@ public void testAutoUpdateWithYamlFileWithValueAndXmlProperty() throws Exception int newTimeout = 1001; int newBatch = 2001; - YamlConfigFile configFile = prepareYamlConfigFile("application.yaml", + YamlConfigFile configFile = prepareYamlConfigFile(someAppId, "application.yaml", readYamlContentAsConfigFileProperties("case1.yaml")); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig13.class); @@ -195,7 +196,7 @@ public void testAutoUpdateDisabled() throws Exception { Properties properties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig1.class); @@ -225,8 +226,8 @@ public void testAutoUpdateWithMultipleNamespaces() throws Exception { Properties applicationProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout)); Properties fxApolloProperties = assembleProperties(BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig applicationConfig = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationProperties); - SimpleConfig fxApolloConfig = prepareConfig(FX_APOLLO_NAMESPACE, fxApolloProperties); + SimpleConfig applicationConfig = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationProperties); + SimpleConfig fxApolloConfig = prepareConfig(someAppId, FX_APOLLO_NAMESPACE, fxApolloProperties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig2.class); @@ -237,7 +238,7 @@ public void testAutoUpdateWithMultipleNamespaces() throws Exception { Properties newApplicationProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(newTimeout)); - applicationConfig.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newApplicationProperties); + applicationConfig.onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newApplicationProperties); TimeUnit.MILLISECONDS.sleep(100); @@ -266,8 +267,8 @@ public void testAutoUpdateWithMultipleNamespacesWithSameProperties() throws Exce Properties fxApolloProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(someTimeout), BATCH_PROPERTY, String.valueOf(anotherBatch)); - prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationProperties); - SimpleConfig fxApolloConfig = prepareConfig(FX_APOLLO_NAMESPACE, fxApolloProperties); + prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationProperties); + SimpleConfig fxApolloConfig = prepareConfig(someAppId, FX_APOLLO_NAMESPACE, fxApolloProperties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig2.class); @@ -279,7 +280,7 @@ public void testAutoUpdateWithMultipleNamespacesWithSameProperties() throws Exce Properties newFxApolloProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(someNewTimeout), BATCH_PROPERTY, String.valueOf(someNewBatch)); - fxApolloConfig.onRepositoryChange(FX_APOLLO_NAMESPACE, newFxApolloProperties); + fxApolloConfig.onRepositoryChange(someAppId, FX_APOLLO_NAMESPACE, newFxApolloProperties); TimeUnit.MILLISECONDS.sleep(100); @@ -294,12 +295,12 @@ public void testAutoUpdateWithMultipleNamespacesWithSamePropertiesWithYamlFile() int anotherBatch = 3000; int someNewBatch = 2001; - YamlConfigFile configFile = prepareYamlConfigFile("application.yml", + YamlConfigFile configFile = prepareYamlConfigFile(someAppId,"application.yml", readYamlContentAsConfigFileProperties("case2.yml")); Properties fxApolloProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(someTimeout), BATCH_PROPERTY, String.valueOf(anotherBatch)); - prepareConfig(FX_APOLLO_NAMESPACE, fxApolloProperties); + prepareConfig(someAppId, FX_APOLLO_NAMESPACE, fxApolloProperties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig14.class); @@ -324,7 +325,7 @@ public void testAutoUpdateWithNewProperties() throws Exception { Properties applicationProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout)); - SimpleConfig applicationConfig = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationProperties); + SimpleConfig applicationConfig = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationProperties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig1.class); @@ -336,7 +337,7 @@ public void testAutoUpdateWithNewProperties() throws Exception { Properties newApplicationProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(newTimeout), BATCH_PROPERTY, String.valueOf(newBatch)); - applicationConfig.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newApplicationProperties); + applicationConfig.onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newApplicationProperties); TimeUnit.MILLISECONDS.sleep(100); @@ -350,7 +351,7 @@ public void testAutoUpdateWithNewPropertiesWithYamlFile() throws Exception { int newTimeout = 1001; int newBatch = 2001; - YamlConfigFile configFile = prepareYamlConfigFile("application.yaml", + YamlConfigFile configFile = prepareYamlConfigFile(someAppId,"application.yaml", readYamlContentAsConfigFileProperties("case3.yaml")); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig12.class); @@ -381,7 +382,7 @@ public void testAutoUpdateWithIrrelevantProperties() throws Exception { Properties applicationProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), someIrrelevantKey, someIrrelevantValue); - SimpleConfig applicationConfig = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationProperties); + SimpleConfig applicationConfig = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationProperties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig1.class); @@ -393,7 +394,7 @@ public void testAutoUpdateWithIrrelevantProperties() throws Exception { Properties newApplicationProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), anotherIrrelevantKey, anotherIrrelevantValue); - applicationConfig.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newApplicationProperties); + applicationConfig.onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newApplicationProperties); TimeUnit.MILLISECONDS.sleep(100); @@ -409,7 +410,7 @@ public void testAutoUpdateWithDeletedProperties() throws Exception { Properties properties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig1.class); @@ -420,7 +421,7 @@ public void testAutoUpdateWithDeletedProperties() throws Exception { Properties newProperties = new Properties(); - config.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newProperties); + config.onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newProperties); TimeUnit.MILLISECONDS.sleep(100); @@ -433,7 +434,7 @@ public void testAutoUpdateWithDeletedPropertiesWithYamlFile() throws Exception { int initialTimeout = 1000; int initialBatch = 2000; - YamlConfigFile configFile = prepareYamlConfigFile("application.yaml", + YamlConfigFile configFile = prepareYamlConfigFile(someAppId, "application.yaml", readYamlContentAsConfigFileProperties("case4.yaml")); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig12.class); @@ -443,7 +444,7 @@ public void testAutoUpdateWithDeletedPropertiesWithYamlFile() throws Exception { assertEquals(initialTimeout, bean.getTimeout()); assertEquals(initialBatch, bean.getBatch()); - configFile.onRepositoryChange("application.yaml", readYamlContentAsConfigFileProperties("case4-new.yaml")); + configFile.onRepositoryChange(someAppId, "application.yaml", readYamlContentAsConfigFileProperties("case4-new.yaml")); TimeUnit.MILLISECONDS.sleep(100); @@ -461,8 +462,8 @@ public void testAutoUpdateWithMultipleNamespacesWithSamePropertiesDeleted() thro Properties fxApolloProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(someTimeout), BATCH_PROPERTY, String.valueOf(anotherBatch)); - SimpleConfig applicationConfig = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationProperties); - prepareConfig(FX_APOLLO_NAMESPACE, fxApolloProperties); + SimpleConfig applicationConfig = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationProperties); + prepareConfig(someAppId, FX_APOLLO_NAMESPACE, fxApolloProperties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig2.class); @@ -490,7 +491,7 @@ public void testAutoUpdateWithDeletedPropertiesWithNoDefaultValue() throws Excep Properties properties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig6.class); @@ -519,7 +520,7 @@ public void testAutoUpdateWithTypeMismatch() throws Exception { Properties properties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig1.class); @@ -545,7 +546,7 @@ public void testAutoUpdateWithTypeMismatchWithYamlFile() throws Exception { int initialBatch = 2000; int newTimeout = 1001; - YamlConfigFile configFile = prepareYamlConfigFile("application.yaml", + YamlConfigFile configFile = prepareYamlConfigFile(someAppId, "application.yaml", readYamlContentAsConfigFileProperties("case5.yaml")); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig12.class); @@ -573,7 +574,7 @@ public void testAutoUpdateWithValueInjectedAsParameter() throws Exception { Properties properties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig3.class); @@ -604,7 +605,7 @@ public void testApplicationPropertySourceWithValueInjectedInConfiguration() thro Properties properties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig7.class); @@ -635,7 +636,7 @@ public void testAutoUpdateWithValueInjectedAsConstructorArgs() throws Exception Properties properties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig4.class); @@ -666,7 +667,7 @@ public void testAutoUpdateWithInvalidSetter() throws Exception { Properties properties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig5.class); @@ -698,7 +699,7 @@ public void testAutoUpdateWithNestedProperty() throws Exception { Properties properties = assembleProperties(SOME_KEY_PROPERTY, someKeyValue, ANOTHER_KEY_PROPERTY, anotherKeyValue, String.format("%s.%s", someKeyValue, anotherKeyValue), String.valueOf(someValue)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(NestedPropertyConfig1.class); @@ -726,7 +727,7 @@ public void testAutoUpdateWithNotSupportedNestedProperty() throws Exception { Properties properties = assembleProperties(SOME_KEY_PROPERTY, someKeyValue, ANOTHER_KEY_PROPERTY, anotherKeyValue, String.format("%s.%s", someKeyValue, anotherKeyValue), String.valueOf(someValue)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(NestedPropertyConfig1.class); @@ -755,7 +756,7 @@ public void testAutoUpdateWithNestedPropertyWithDefaultValue() throws Exception Properties properties = assembleProperties(SOME_KEY_PROPERTY, someKeyValue, ANOTHER_KEY_PROPERTY, String.valueOf(someValue)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(NestedPropertyConfig2.class); @@ -790,7 +791,7 @@ public void testAutoUpdateWithMultipleNestedProperty() throws Exception { properties.setProperty(someNestedKey, String.valueOf(someValue)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(NestedPropertyConfig2.class); @@ -855,7 +856,7 @@ public void testAutoUpdateWithAllKindsOfDataTypes() throws Exception { properties.setProperty("jsonProperty", someJsonProperty); properties.setProperty("jsonDateProperty", someJsonDateProperty); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig9.class); @@ -890,7 +891,7 @@ public void testAutoUpdateWithAllKindsOfDataTypes() throws Exception { newProperties.setProperty("jsonProperty", someNewJsonProperty); newProperties.setProperty("jsonDateProperty", someNewJsonDateProperty); - config.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newProperties); + config.onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newProperties); TimeUnit.MILLISECONDS.sleep(100); @@ -916,7 +917,7 @@ public void testAutoUpdateJsonValueWithInvalidValue() throws Exception { Properties properties = assembleProperties("jsonProperty", someValidValue); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig10.class); @@ -929,7 +930,7 @@ public void testAutoUpdateJsonValueWithInvalidValue() throws Exception { Properties newProperties = assembleProperties("jsonProperty", someInvalidValue); - config.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newProperties); + config.onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newProperties); TimeUnit.MILLISECONDS.sleep(300); @@ -943,7 +944,7 @@ public void testAutoUpdateJsonValueWithNoValueAndNoDefaultValue() throws Excepti Properties properties = assembleProperties("jsonProperty", someValidValue); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig10.class); @@ -956,7 +957,7 @@ public void testAutoUpdateJsonValueWithNoValueAndNoDefaultValue() throws Excepti Properties newProperties = new Properties(); - config.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newProperties); + config.onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newProperties); TimeUnit.MILLISECONDS.sleep(300); @@ -970,7 +971,7 @@ public void testAutoUpdateJsonValueWithNoValueAndDefaultValue() throws Exception Properties properties = assembleProperties("jsonProperty", someValidValue); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig11.class); @@ -983,7 +984,7 @@ public void testAutoUpdateJsonValueWithNoValueAndDefaultValue() throws Exception Properties newProperties = new Properties(); - config.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newProperties); + config.onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newProperties); TimeUnit.MILLISECONDS.sleep(100); diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderTest.java index feaa4d73..5d80aba1 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderTest.java @@ -60,6 +60,7 @@ public class JavaConfigPlaceholderTest extends AbstractSpringIntegrationTest { private static final String DATE_FORMAT_JSON_PROPERTY1 = "jsonDateProperty1"; private static final String DATE_FORMAT_JSON_PROPERTY2 = "jsonDateProperty2"; private static final String DATE_FORMAT_JSON_PROPERTY3 = "jsonDateProperty3"; + private static final String someAppId = "someAppId"; @Test public void testPropertySourceWithNoNamespace() throws Exception { @@ -70,7 +71,7 @@ public void testPropertySourceWithNoNamespace() throws Exception { when(config.getProperty(eq(TIMEOUT_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someTimeout)); when(config.getProperty(eq(BATCH_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someBatch)); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); check(someTimeout, someBatch, AppConfig1.class); } @@ -78,7 +79,7 @@ public void testPropertySourceWithNoNamespace() throws Exception { @Test public void testPropertySourceWithNoConfig() throws Exception { Config config = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); check(DEFAULT_TIMEOUT, DEFAULT_BATCH, AppConfig1.class); } @@ -91,7 +92,7 @@ public void testApplicationPropertySource() throws Exception { when(config.getProperty(eq(TIMEOUT_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someTimeout)); when(config.getProperty(eq(BATCH_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someBatch)); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); check(someTimeout, someBatch, AppConfig2.class); } @@ -107,7 +108,7 @@ public void testPropertiesCompatiblePropertySource() throws Exception { PropertiesCompatibleConfigFile configFile = mock(PropertiesCompatibleConfigFile.class); when(configFile.asProperties()).thenReturn(properties); - mockConfigFile("application.yaml", configFile); + mockConfigFile(someAppId, "application.yaml", configFile); check(someTimeout, someBatch, AppConfig9.class); } @@ -123,7 +124,7 @@ public void testPropertiesCompatiblePropertySourceWithNonNormalizedCase() throws PropertiesCompatibleConfigFile configFile = mock(PropertiesCompatibleConfigFile.class); when(configFile.asProperties()).thenReturn(properties); - mockConfigFile("application.yaml", configFile); + mockConfigFile(someAppId, "application.yaml", configFile); check(someTimeout, someBatch, AppConfig10.class); } @@ -135,11 +136,11 @@ public void testMultiplePropertySources() throws Exception { Config application = mock(Config.class); when(application.getProperty(eq(TIMEOUT_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someTimeout)); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, application); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, application); Config fxApollo = mock(Config.class); when(application.getProperty(eq(BATCH_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someBatch)); - mockConfig(FX_APOLLO_NAMESPACE, fxApollo); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, fxApollo); check(someTimeout, someBatch, AppConfig3.class); } @@ -157,11 +158,11 @@ public void testMultiplePropertiesCompatiblePropertySourcesWithSameProperties() PropertiesCompatibleConfigFile configFile = mock(PropertiesCompatibleConfigFile.class); when(configFile.asProperties()).thenReturn(properties); - mockConfigFile("application.yml", configFile); + mockConfigFile(someAppId, "application.yml", configFile); Config fxApollo = mock(Config.class); when(fxApollo.getProperty(eq(TIMEOUT_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(anotherTimeout)); - mockConfig(FX_APOLLO_NAMESPACE, fxApollo); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, fxApollo); check(someTimeout, someBatch, AppConfig11.class); } @@ -176,11 +177,11 @@ public void testMultiplePropertySourcesCoverWithSameProperties() throws Exceptio Config fxApollo = mock(Config.class); when(fxApollo.getProperty(eq(TIMEOUT_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someTimeout)); when(fxApollo.getProperty(eq(BATCH_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someBatch)); - mockConfig(FX_APOLLO_NAMESPACE, fxApollo); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, fxApollo); Config application = mock(Config.class); when(application.getProperty(eq(TIMEOUT_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(anotherTimeout)); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, application); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, application); check(someTimeout, someBatch, AppConfig6.class); } @@ -195,11 +196,11 @@ public void testMultiplePropertySourcesCoverWithSamePropertiesWithPropertiesComp Config fxApollo = mock(Config.class); when(fxApollo.getProperty(eq(TIMEOUT_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someTimeout)); when(fxApollo.getProperty(eq(BATCH_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someBatch)); - mockConfig(FX_APOLLO_NAMESPACE, fxApollo); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, fxApollo); Config application = mock(Config.class); when(application.getProperty(eq(TIMEOUT_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(anotherTimeout)); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, application); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, application); check(someTimeout, someBatch, AppConfig6.class); } @@ -213,11 +214,11 @@ public void testMultiplePropertySourcesWithSamePropertiesWithWeight() throws Exc Config application = mock(Config.class); when(application.getProperty(eq(TIMEOUT_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someTimeout)); when(application.getProperty(eq(BATCH_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someBatch)); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, application); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, application); Config fxApollo = mock(Config.class); when(fxApollo.getProperty(eq(TIMEOUT_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(anotherTimeout)); - mockConfig(FX_APOLLO_NAMESPACE, fxApollo); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, fxApollo); check(anotherTimeout, someBatch, AppConfig2.class, AppConfig4.class); } @@ -231,7 +232,7 @@ public void testApplicationPropertySourceWithValueInjectedAsParameter() throws E when(config.getProperty(eq(TIMEOUT_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someTimeout)); when(config.getProperty(eq(BATCH_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someBatch)); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig5.class); @@ -250,7 +251,7 @@ public void testApplicationPropertySourceWithValueInjectedAsConstructorArgs() th when(config.getProperty(eq(TIMEOUT_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someTimeout)); when(config.getProperty(eq(BATCH_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someBatch)); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig7.class); @@ -272,7 +273,7 @@ public void testNestedProperty() throws Exception { when(config.getProperty(eq(String.format("%s.%s", a, b)), Mockito.nullable(String.class))) .thenReturn(String.valueOf(someValue)); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(NestedPropertyConfig1.class); @@ -293,7 +294,7 @@ public void testNestedPropertyWithDefaultValue() throws Exception { when(config.getProperty(eq(b), Mockito.nullable(String.class))).thenReturn(b); when(config.getProperty(eq(c), Mockito.nullable(String.class))).thenReturn(String.valueOf(someValue)); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(NestedPropertyConfig1.class); @@ -311,7 +312,7 @@ public void testNestedPropertyWithNestedDefaultValue() throws Exception { when(config.getProperty(eq(a), Mockito.nullable(String.class))).thenReturn(a); when(config.getProperty(eq(b), Mockito.nullable(String.class))).thenReturn(b); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(NestedPropertyConfig1.class); @@ -334,7 +335,7 @@ public void testMultipleNestedProperty() throws Exception { when(config.getProperty(eq(String.format("%s.%s", a, b)), Mockito.nullable(String.class))).thenReturn(nestedProperty); when(config.getProperty(eq(nestedKey), Mockito.nullable(String.class))).thenReturn(String.valueOf(someValue)); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(NestedPropertyConfig1.class); @@ -356,7 +357,7 @@ public void testMultipleNestedPropertyWithDefaultValue() throws Exception { when(config.getProperty(eq(b), Mockito.nullable(String.class))).thenReturn(b); when(config.getProperty(eq(String.format("%s.%s", a, b)), Mockito.nullable(String.class))).thenReturn(nestedProperty); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(NestedPropertyConfig1.class); @@ -374,7 +375,7 @@ public void testApolloJsonValue() { when(config.getProperty(eq(JSON_PROPERTY), Mockito.nullable(String.class))).thenReturn(someJson); when(config.getProperty(eq(OTHER_JSON_PROPERTY), Mockito.nullable(String.class))).thenReturn(otherJson); when(config.getProperty(eq("a"), Mockito.nullable(String.class))).thenReturn(JSON_PROPERTY); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( AppConfig8.class); @@ -405,7 +406,7 @@ public void testApolloDateJsonValue() { when(config.getProperty(eq(DATE_FORMAT_JSON_PROPERTY1), Mockito.nullable(String.class))).thenReturn(dateFormatJson1); when(config.getProperty(eq(DATE_FORMAT_JSON_PROPERTY2), Mockito.nullable(String.class))).thenReturn(dateFormatJson2); when(config.getProperty(eq(DATE_FORMAT_JSON_PROPERTY3), Mockito.nullable(String.class))).thenReturn(dateFormatJson3); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( AppConfig12.class); @@ -424,7 +425,7 @@ public void testApolloJsonValueWithInvalidJson() throws Exception { when(config.getProperty(eq(JSON_PROPERTY), Mockito.nullable(String.class))).thenReturn(someInvalidJson); when(config.getProperty(eq(OTHER_JSON_PROPERTY), Mockito.nullable(String.class))).thenReturn(someInvalidJson); when(config.getProperty(eq("a"), Mockito.nullable(String.class))).thenReturn(JSON_PROPERTY); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); new AnnotationConfigApplicationContext(AppConfig8.class).getBean(TestJsonPropertyBean.class); } @@ -432,7 +433,7 @@ public void testApolloJsonValueWithInvalidJson() throws Exception { @Test(expected = BeanCreationException.class) public void testApolloJsonValueWithNoPropertyValue() throws Exception { Config config = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); new AnnotationConfigApplicationContext(AppConfig8.class); } diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XMLConfigAnnotationTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XMLConfigAnnotationTest.java index 09fd566a..64a57df2 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XMLConfigAnnotationTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XMLConfigAnnotationTest.java @@ -50,13 +50,15 @@ public class XMLConfigAnnotationTest extends AbstractSpringIntegrationTest { private static final String FX_APOLLO_NAMESPACE = "FX.apollo"; + private static final String someAppId = "someAppId"; + @Test public void testApolloConfig() throws Exception { Config applicationConfig = mock(Config.class); Config fxApolloConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); - mockConfig(FX_APOLLO_NAMESPACE, fxApolloConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, fxApolloConfig); TestApolloConfigBean1 bean = getBean("spring/XmlConfigAnnotationTest1.xml", TestApolloConfigBean1.class); @@ -69,7 +71,7 @@ public void testApolloConfig() throws Exception { public void testApolloConfigWithWrongFieldType() throws Exception { Config applicationConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); getBean("spring/XmlConfigAnnotationTest2.xml", TestApolloConfigBean2.class); } @@ -79,8 +81,8 @@ public void testApolloConfigChangeListener() throws Exception { Config applicationConfig = mock(Config.class); Config fxApolloConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); - mockConfig(FX_APOLLO_NAMESPACE, fxApolloConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, fxApolloConfig); final List applicationListeners = Lists.newArrayList(); final List fxApolloListeners = Lists.newArrayList(); @@ -134,7 +136,7 @@ public Object answer(InvocationOnMock invocation) throws Throwable { public void testApolloConfigChangeListenerWithWrongParamType() throws Exception { Config applicationConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); getBean("spring/XmlConfigAnnotationTest4.xml", TestApolloConfigChangeListenerBean2.class); } @@ -143,7 +145,7 @@ public void testApolloConfigChangeListenerWithWrongParamType() throws Exception public void testApolloConfigChangeListenerWithWrongParamCount() throws Exception { Config applicationConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); getBean("spring/XmlConfigAnnotationTest5.xml", TestApolloConfigChangeListenerBean3.class); } @@ -153,8 +155,8 @@ public void testApolloConfigChangeListenerWithInterestedKeys() throws Exception Config applicationConfig = mock(Config.class); Config fxApolloConfig = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); - mockConfig(FX_APOLLO_NAMESPACE, fxApolloConfig); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationConfig); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, fxApolloConfig); TestApolloConfigChangeListenerWithInterestedKeysBean bean = getBean( "spring/XmlConfigAnnotationTest6.xml", TestApolloConfigChangeListenerWithInterestedKeysBean.class); diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XmlConfigPlaceholderAutoUpdateTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XmlConfigPlaceholderAutoUpdateTest.java index 109e334f..3fa94a2f 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XmlConfigPlaceholderAutoUpdateTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XmlConfigPlaceholderAutoUpdateTest.java @@ -41,6 +41,8 @@ public class XmlConfigPlaceholderAutoUpdateTest extends AbstractSpringIntegratio private static final int DEFAULT_BATCH = 200; private static final String FX_APOLLO_NAMESPACE = "FX.apollo"; + private static final String someAppId = "someAppId"; + @Test public void testAutoUpdateWithOneNamespace() throws Exception { int initialTimeout = 1000; @@ -51,7 +53,7 @@ public void testAutoUpdateWithOneNamespace() throws Exception { Properties properties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/XmlConfigPlaceholderTest1.xml"); @@ -63,7 +65,7 @@ public void testAutoUpdateWithOneNamespace() throws Exception { Properties newProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(newTimeout), BATCH_PROPERTY, String.valueOf(newBatch)); - config.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newProperties); + config.onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newProperties); TimeUnit.MILLISECONDS.sleep(100); @@ -86,7 +88,7 @@ public void testAutoUpdateDisabled() throws Exception { Properties properties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/XmlConfigPlaceholderTest1.xml"); @@ -98,7 +100,7 @@ public void testAutoUpdateDisabled() throws Exception { Properties newProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(newTimeout), BATCH_PROPERTY, String.valueOf(newBatch)); - config.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newProperties); + config.onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newProperties); TimeUnit.MILLISECONDS.sleep(100); @@ -118,9 +120,9 @@ public void testAutoUpdateWithMultipleNamespaces() throws Exception { Properties fxApolloProperties = assembleProperties(BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig applicationConfig = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, + SimpleConfig applicationConfig = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationProperties); - SimpleConfig fxApolloConfig = prepareConfig(FX_APOLLO_NAMESPACE, fxApolloProperties); + SimpleConfig fxApolloConfig = prepareConfig(someAppId, FX_APOLLO_NAMESPACE, fxApolloProperties); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/XmlConfigPlaceholderTest3.xml"); @@ -163,8 +165,8 @@ public void testAutoUpdateWithMultipleNamespacesWithSameProperties() throws Exce Properties fxApolloProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(someTimeout), BATCH_PROPERTY, String.valueOf(anotherBatch)); - prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationProperties); - SimpleConfig fxApolloConfig = prepareConfig(FX_APOLLO_NAMESPACE, fxApolloProperties); + prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationProperties); + SimpleConfig fxApolloConfig = prepareConfig(someAppId, FX_APOLLO_NAMESPACE, fxApolloProperties); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/XmlConfigPlaceholderTest3.xml"); @@ -176,7 +178,7 @@ public void testAutoUpdateWithMultipleNamespacesWithSameProperties() throws Exce Properties newFxApolloProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(someNewTimeout), BATCH_PROPERTY, String.valueOf(someNewBatch)); - fxApolloConfig.onRepositoryChange(FX_APOLLO_NAMESPACE, newFxApolloProperties); + fxApolloConfig.onRepositoryChange(someAppId, FX_APOLLO_NAMESPACE, newFxApolloProperties); TimeUnit.MILLISECONDS.sleep(100); @@ -193,7 +195,7 @@ public void testAutoUpdateWithNewProperties() throws Exception { Properties applicationProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout)); - SimpleConfig applicationConfig = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, + SimpleConfig applicationConfig = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationProperties); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/XmlConfigPlaceholderTest1.xml"); @@ -207,7 +209,7 @@ public void testAutoUpdateWithNewProperties() throws Exception { String.valueOf(newTimeout), BATCH_PROPERTY, String.valueOf(newBatch)); applicationConfig - .onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newApplicationProperties); + .onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newApplicationProperties); TimeUnit.MILLISECONDS.sleep(100); @@ -228,7 +230,7 @@ public void testAutoUpdateWithIrrelevantProperties() throws Exception { Properties applicationProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), someIrrelevantKey, someIrrelevantValue); - SimpleConfig applicationConfig = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, + SimpleConfig applicationConfig = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationProperties); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/XmlConfigPlaceholderTest1.xml"); @@ -242,7 +244,7 @@ public void testAutoUpdateWithIrrelevantProperties() throws Exception { String.valueOf(initialTimeout), anotherIrrelevantKey, anotherIrrelevantValue); applicationConfig - .onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newApplicationProperties); + .onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newApplicationProperties); TimeUnit.MILLISECONDS.sleep(100); @@ -258,7 +260,7 @@ public void testAutoUpdateWithDeletedProperties() throws Exception { Properties properties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/XmlConfigPlaceholderTest1.xml"); @@ -269,7 +271,7 @@ public void testAutoUpdateWithDeletedProperties() throws Exception { Properties newProperties = new Properties(); - config.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newProperties); + config.onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newProperties); TimeUnit.MILLISECONDS.sleep(100); @@ -288,9 +290,9 @@ public void testAutoUpdateWithMultipleNamespacesWithSamePropertiesDeleted() thro Properties fxApolloProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(someTimeout), BATCH_PROPERTY, String.valueOf(anotherBatch)); - SimpleConfig applicationConfig = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, + SimpleConfig applicationConfig = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, applicationProperties); - prepareConfig(FX_APOLLO_NAMESPACE, fxApolloProperties); + prepareConfig(someAppId, FX_APOLLO_NAMESPACE, fxApolloProperties); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/XmlConfigPlaceholderTest3.xml"); @@ -318,7 +320,7 @@ public void testAutoUpdateWithDeletedPropertiesWithNoDefaultValue() throws Excep Properties properties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/XmlConfigPlaceholderTest7.xml"); @@ -329,7 +331,7 @@ public void testAutoUpdateWithDeletedPropertiesWithNoDefaultValue() throws Excep Properties newProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(newTimeout)); - config.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newProperties); + config.onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newProperties); TimeUnit.MILLISECONDS.sleep(300); @@ -347,7 +349,7 @@ public void testAutoUpdateWithTypeMismatch() throws Exception { Properties properties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/XmlConfigPlaceholderTest1.xml"); @@ -359,7 +361,7 @@ public void testAutoUpdateWithTypeMismatch() throws Exception { Properties newProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(newTimeout), BATCH_PROPERTY, newBatch); - config.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newProperties); + config.onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newProperties); TimeUnit.MILLISECONDS.sleep(300); @@ -377,7 +379,7 @@ public void testAutoUpdateWithValueInjectedAsConstructorArgs() throws Exception Properties properties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/XmlConfigPlaceholderTest8.xml"); @@ -389,7 +391,7 @@ public void testAutoUpdateWithValueInjectedAsConstructorArgs() throws Exception Properties newProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(newTimeout), BATCH_PROPERTY, String.valueOf(newBatch)); - config.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newProperties); + config.onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newProperties); TimeUnit.MILLISECONDS.sleep(100); @@ -408,7 +410,7 @@ public void testAutoUpdateWithValueAndProperty() throws Exception { Properties properties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(initialTimeout), BATCH_PROPERTY, String.valueOf(initialBatch)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/XmlConfigPlaceholderTest9.xml"); @@ -420,7 +422,7 @@ public void testAutoUpdateWithValueAndProperty() throws Exception { Properties newProperties = assembleProperties(TIMEOUT_PROPERTY, String.valueOf(newTimeout), BATCH_PROPERTY, String.valueOf(newBatch)); - config.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newProperties); + config.onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newProperties); TimeUnit.MILLISECONDS.sleep(100); @@ -467,7 +469,7 @@ public void testAutoUpdateWithAllKindsOfDataTypes() throws Exception { properties.setProperty("dateFormat", someDateFormat); properties.setProperty("dateProperty", simpleDateFormat.format(someDate)); - SimpleConfig config = prepareConfig(ConfigConsts.NAMESPACE_APPLICATION, properties); + SimpleConfig config = prepareConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, properties); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/XmlConfigPlaceholderTest10.xml"); TestAllKindsOfDataTypesBean bean = context.getBean(TestAllKindsOfDataTypesBean.class); @@ -496,7 +498,7 @@ public void testAutoUpdateWithAllKindsOfDataTypes() throws Exception { newProperties.setProperty("dateFormat", someDateFormat); newProperties.setProperty("dateProperty", simpleDateFormat.format(someNewDate)); - config.onRepositoryChange(ConfigConsts.NAMESPACE_APPLICATION, newProperties); + config.onRepositoryChange(someAppId, ConfigConsts.NAMESPACE_APPLICATION, newProperties); TimeUnit.MILLISECONDS.sleep(100); diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XmlConfigPlaceholderTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XmlConfigPlaceholderTest.java index 5227734c..c1004250 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XmlConfigPlaceholderTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XmlConfigPlaceholderTest.java @@ -36,6 +36,7 @@ */ public class XmlConfigPlaceholderTest extends AbstractSpringIntegrationTest { + private static final String someAppId = "someAppId"; private static final String TIMEOUT_PROPERTY = "timeout"; private static final int DEFAULT_TIMEOUT = 100; private static final String BATCH_PROPERTY = "batch"; @@ -62,7 +63,7 @@ public void testPropertySourceWithNoNamespace() throws Exception { .thenReturn(String.valueOf(someTimeout)); when(config.getProperty(eq(BATCH_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someBatch)); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); check("spring/XmlConfigPlaceholderTest1.xml", someTimeout, someBatch); } @@ -70,7 +71,7 @@ public void testPropertySourceWithNoNamespace() throws Exception { @Test public void testPropertySourceWithNoConfig() throws Exception { Config config = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); check("spring/XmlConfigPlaceholderTest1.xml", DEFAULT_TIMEOUT, DEFAULT_BATCH); } @@ -84,7 +85,7 @@ public void testApplicationPropertySource() throws Exception { .thenReturn(String.valueOf(someTimeout)); when(config.getProperty(eq(BATCH_PROPERTY), Mockito.nullable(String.class))).thenReturn(String.valueOf(someBatch)); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); check("spring/XmlConfigPlaceholderTest2.xml", someTimeout, someBatch); } @@ -97,12 +98,12 @@ public void testMultiplePropertySources() throws Exception { Config application = mock(Config.class); when(application.getProperty(eq(TIMEOUT_PROPERTY), Mockito.nullable(String.class))) .thenReturn(String.valueOf(someTimeout)); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, application); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, application); Config fxApollo = mock(Config.class); when(application.getProperty(eq(BATCH_PROPERTY), Mockito.nullable(String.class))) .thenReturn(String.valueOf(someBatch)); - mockConfig(FX_APOLLO_NAMESPACE, fxApollo); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, fxApollo); check("spring/XmlConfigPlaceholderTest3.xml", someTimeout, someBatch); } @@ -113,12 +114,12 @@ private void prepare(int someTimeout, int anotherTimeout, int someBatch) { .thenReturn(String.valueOf(someTimeout)); when(application.getProperty(eq(BATCH_PROPERTY), Mockito.nullable(String.class))) .thenReturn(String.valueOf(someBatch)); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, application); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, application); Config fxApollo = mock(Config.class); when(fxApollo.getProperty(eq(TIMEOUT_PROPERTY), Mockito.nullable(String.class))) .thenReturn(String.valueOf(anotherTimeout)); - mockConfig(FX_APOLLO_NAMESPACE, fxApollo); + mockConfig(someAppId, FX_APOLLO_NAMESPACE, fxApollo); } @Test diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/config/CachedCompositePropertySourceTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/config/CachedCompositePropertySourceTest.java index 9d6e11f8..e3dd5ad1 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/config/CachedCompositePropertySourceTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/config/CachedCompositePropertySourceTest.java @@ -82,7 +82,7 @@ public void testGetPropertyNames() { assertArrayEquals(propertyNames, returnedPropertyNames); assertSame(returnedPropertyNames, compositeSource.getPropertyNames()); - listeners.get(0).onChange(new ConfigChangeEvent(null, null)); + listeners.get(0).onChange(new ConfigChangeEvent(null,null, null)); returnedPropertyNames = compositeSource.getPropertyNames(); assertArrayEquals(anotherPropertyNames, returnedPropertyNames); diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/config/PropertySourcesProcessorTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/config/PropertySourcesProcessorTest.java index be6ec4bf..22ac4b06 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/config/PropertySourcesProcessorTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/spring/config/PropertySourcesProcessorTest.java @@ -19,6 +19,8 @@ import static org.junit.Assert.*; import static org.mockito.Mockito.*; +import com.ctrip.framework.apollo.BaseIntegrationTest; +import com.ctrip.framework.apollo.BaseIntegrationTest.MockConfigUtil; import com.ctrip.framework.apollo.Config; import com.ctrip.framework.apollo.ConfigChangeListener; import com.ctrip.framework.apollo.build.ApolloInjector; @@ -48,9 +50,13 @@ public class PropertySourcesProcessorTest extends AbstractSpringIntegrationTest private MutablePropertySources propertySources; private ApplicationEventPublisher applicationEventPublisher; + private final static String someAppId = "someAppId"; + @Override @Before public void setUp() throws Exception { + System.setProperty(ApolloClientSystemConsts.APP_ID, someAppId); + //MockInjector.setInstance(ConfigUtil.class, new BaseIntegrationTest.MockConfigUtil()); super.setUp(); propertySources = mock(MutablePropertySources.class); environment = mock(ConfigurableEnvironment.class); @@ -60,6 +66,7 @@ public void setUp() throws Exception { processor = new PropertySourcesProcessor(); processor.setEnvironment(environment); processor.setApplicationEventPublisher(applicationEventPublisher); + } @Override @@ -71,12 +78,13 @@ public void tearDown() throws Exception { @Test public void testInitializePropertySources() { + String someAppId = "someAppId"; String namespaceName = "someNamespace"; String anotherNamespaceName = "anotherNamespace"; Config config = mock(Config.class); Config anotherConfig = mock(Config.class); - mockConfig(namespaceName, config); - mockConfig(anotherNamespaceName, anotherConfig); + mockConfig(someAppId, namespaceName, config); + mockConfig(someAppId, anotherNamespaceName, anotherConfig); PropertySourcesProcessor.addNamespaces(Lists.newArrayList(namespaceName, anotherNamespaceName), 0); @@ -94,17 +102,18 @@ public void testInitializePropertySources() { ConfigPropertySource anotherPropertySource = (ConfigPropertySource) Lists.newArrayList( compositePropertySource.getPropertySources()).get(1); - assertEquals(namespaceName, propertySource.getName()); + assertEquals(someAppId + ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR + namespaceName, propertySource.getName()); assertSame(config, propertySource.getSource()); - assertEquals(anotherNamespaceName, anotherPropertySource.getName()); + assertEquals(someAppId + ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR + anotherNamespaceName, anotherPropertySource.getName()); assertSame(anotherConfig, anotherPropertySource.getSource()); } @Test public void testApplicationEvent() { + String someAppId = "someAppId"; String namespaceName = "someNamespace"; Config config = mock(Config.class); - mockConfig(namespaceName, config); + mockConfig(someAppId, namespaceName, config); PropertySourcesProcessor.addNamespaces(Lists.newArrayList(namespaceName), 0); ConfigChangeEvent someConfigChangeEvent = mock(ConfigChangeEvent.class); @@ -149,6 +158,6 @@ public void testOverrideSystemProperties() { processor.postProcessBeanFactory(beanFactory); assertTrue(propertySources.contains(PropertySourcesConstants.APOLLO_PROPERTY_SOURCE_NAME)); - assertEquals(propertySources.iterator().next().getName(), StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME); + assertEquals(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, propertySources.iterator().next().getName()); } } diff --git a/apollo-client/src/test/java/com/ctrip/framework/apollo/util/ConfigUtilTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/util/ConfigUtilTest.java index 23a37362..f0c68be4 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/util/ConfigUtilTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/util/ConfigUtilTest.java @@ -223,7 +223,7 @@ public void testLocalCacheDirWithSystemProperty() throws Exception { doReturn(someAppId).when(configUtil).getAppId(); - assertEquals(someCacheDir + File.separator + someAppId, configUtil.getDefaultLocalCacheDir()); + assertEquals(someCacheDir + File.separator + someAppId, configUtil.getDefaultLocalCacheDir(someAppId)); } @Test @@ -236,11 +236,11 @@ public void testDefaultLocalCacheDir() throws Exception { doReturn(true).when(configUtil).isOSWindows(); - assertEquals("C:\\opt\\data\\" + someAppId, configUtil.getDefaultLocalCacheDir()); + assertEquals("C:\\opt\\data\\" + someAppId, configUtil.getDefaultLocalCacheDir(someAppId)); doReturn(false).when(configUtil).isOSWindows(); - assertEquals("/opt/data/" + someAppId, configUtil.getDefaultLocalCacheDir()); + assertEquals("/opt/data/" + someAppId, configUtil.getDefaultLocalCacheDir(someAppId)); } @Test diff --git a/apollo-core/src/main/java/com/ctrip/framework/apollo/core/utils/StringUtils.java b/apollo-core/src/main/java/com/ctrip/framework/apollo/core/utils/StringUtils.java index 4ffde2c5..73bdbfa1 100644 --- a/apollo-core/src/main/java/com/ctrip/framework/apollo/core/utils/StringUtils.java +++ b/apollo-core/src/main/java/com/ctrip/framework/apollo/core/utils/StringUtils.java @@ -340,6 +340,10 @@ public static boolean isNumeric(String str) { return true; } + public static String defaultIfBlank(String s, String appId) { + return isBlank(s) ? appId : s; + } + public interface StringFormatter { String format(T obj); } diff --git a/apollo-core/src/main/java/com/ctrip/framework/foundation/internals/provider/DefaultApplicationProvider.java b/apollo-core/src/main/java/com/ctrip/framework/foundation/internals/provider/DefaultApplicationProvider.java index aaf88085..b7e559c5 100644 --- a/apollo-core/src/main/java/com/ctrip/framework/foundation/internals/provider/DefaultApplicationProvider.java +++ b/apollo-core/src/main/java/com/ctrip/framework/foundation/internals/provider/DefaultApplicationProvider.java @@ -26,6 +26,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; +import java.util.Objects; import java.util.Properties; import org.slf4j.Logger; @@ -116,6 +117,14 @@ public Class getType() { return ApplicationProvider.class; } + @Override + public String getAccessKeySecret(String appId){ + if (Objects.equals(appId, m_appId)) { + return getAccessKeySecret(); + } + return System.getProperty("apollo.accesskey." + appId + ".secret", ""); + } + private void initAppId() { // 1. Get app.id from System Property m_appId = System.getProperty(ApolloClientSystemConsts.APP_ID); diff --git a/apollo-core/src/main/java/com/ctrip/framework/foundation/internals/provider/NullProvider.java b/apollo-core/src/main/java/com/ctrip/framework/foundation/internals/provider/NullProvider.java index 838dbadd..6bede04a 100644 --- a/apollo-core/src/main/java/com/ctrip/framework/foundation/internals/provider/NullProvider.java +++ b/apollo-core/src/main/java/com/ctrip/framework/foundation/internals/provider/NullProvider.java @@ -84,6 +84,11 @@ public void initialize(InputStream in) { } + @Override + public String getAccessKeySecret(String appId) { + return null; + } + @Override public String getHostAddress() { return null; diff --git a/apollo-core/src/main/java/com/ctrip/framework/foundation/spi/provider/ApplicationProvider.java b/apollo-core/src/main/java/com/ctrip/framework/foundation/spi/provider/ApplicationProvider.java index 17275e2d..e2c0ae3e 100644 --- a/apollo-core/src/main/java/com/ctrip/framework/foundation/spi/provider/ApplicationProvider.java +++ b/apollo-core/src/main/java/com/ctrip/framework/foundation/spi/provider/ApplicationProvider.java @@ -46,4 +46,13 @@ public interface ApplicationProvider extends Provider { * Initialize the application provider with the specified input stream */ void initialize(InputStream in); + + /** + * @return the application's access key secret by appId + * + * @since 2.4.0 + */ + default String getAccessKeySecret(String appId){ + return null; + } } diff --git a/apollo-mockserver/src/main/java/com/ctrip/framework/apollo/mockserver/ApolloTestingServer.java b/apollo-mockserver/src/main/java/com/ctrip/framework/apollo/mockserver/ApolloTestingServer.java index 15c81a9e..cb9b7400 100644 --- a/apollo-mockserver/src/main/java/com/ctrip/framework/apollo/mockserver/ApolloTestingServer.java +++ b/apollo-mockserver/src/main/java/com/ctrip/framework/apollo/mockserver/ApolloTestingServer.java @@ -52,6 +52,7 @@ public class ApolloTestingServer implements AutoCloseable { private static final Type notificationType = new TypeToken>() { }.getType(); + private static String someAppId = "someAppId"; private static Method CONFIG_SERVICE_LOCATOR_CLEAR; private static ConfigServiceLocator CONFIG_SERVICE_LOCATOR; @@ -175,7 +176,7 @@ private Properties loadPropertiesOfNamespace(String namespace) { logger.debug("load {} from {}", namespace, filename); return ResourceUtils.readConfigFile(filename, new Properties()); } - return new LocalFileConfigRepository(namespace).getConfig(); + return new LocalFileConfigRepository(someAppId, namespace).getConfig(); } private String mockLongPollBody(String notificationsStr) { diff --git a/apollo-mockserver/src/test/java/com/ctrip/framework/apollo/mockserver/ApolloMockServerApiWhileCacheDirSpecifiedTest.java b/apollo-mockserver/src/test/java/com/ctrip/framework/apollo/mockserver/ApolloMockServerApiWhileCacheDirSpecifiedTest.java index 2d12609e..f9b3fc2f 100644 --- a/apollo-mockserver/src/test/java/com/ctrip/framework/apollo/mockserver/ApolloMockServerApiWhileCacheDirSpecifiedTest.java +++ b/apollo-mockserver/src/test/java/com/ctrip/framework/apollo/mockserver/ApolloMockServerApiWhileCacheDirSpecifiedTest.java @@ -57,7 +57,7 @@ public void testLoadDefaultLocalCacheDir() throws Exception { assertEquals(someCacheDir + "/" + someAppId, defaultLocalCacheDir); // LocalFileConfigRepository.CONFIG_DIR - LocalFileConfigRepository localFileConfigRepository = new LocalFileConfigRepository(someNamespace); + LocalFileConfigRepository localFileConfigRepository = new LocalFileConfigRepository(someAppId, someNamespace); Field FIELD_CONFIG_DIR = localFileConfigRepository.getClass().getDeclaredField("CONFIG_DIR"); FIELD_CONFIG_DIR.setAccessible(true); String configDir = (String) FIELD_CONFIG_DIR.get(localFileConfigRepository); diff --git a/changes/changes-2.3.0.md b/changes/changes-2.3.0.md new file mode 100644 index 00000000..ac8b61a9 --- /dev/null +++ b/changes/changes-2.3.0.md @@ -0,0 +1,16 @@ +Changes by Version +================== +Release Notes. + +Apollo Java 2.3.0 + +------------------ +* [add an initialize method to avoid DefaultProviderManager's logic being triggered when using custom ProviderManager.](https://github.com/apolloconfig/apollo-java/pull/50) +* [Implement parsing time based on pattern for @ApolloJsonValue](https://github.com/apolloconfig/apollo-java/pull/53) +* [Enhance to load mocked properties from apollo.cache-dir](https://github.com/apolloconfig/apollo-java/pull/58) +* [perf: speed up the first loading of namespace when startup meet 404](https://github.com/apolloconfig/apollo-java/pull/61) +* [perf: speed up when startup meets timeout](https://github.com/apolloconfig/apollo-java/pull/64) +* [upgrade spring boot to 2.7.18](https://github.com/apolloconfig/apollo-java/pull/68) + +------------------ +All issues and pull requests are [here](https://github.com/apolloconfig/apollo-java/milestone/3?closed=1) \ No newline at end of file diff --git a/pom.xml b/pom.xml index c153af5d..d153bf11 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT 1.8 UTF-8 2.7.18