diff --git a/CHANGES.md b/CHANGES.md index c0c6ad24..56acae01 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,7 @@ Apollo Java 2.4.0 * [Feature openapi query namespace support not fill item](https://github.com/apolloconfig/apollo-java/pull/83) * [Add more observability in apollo config client](https://github.com/apolloconfig/apollo-java/pull/74) * [Feature Support Kubernetes ConfigMap cache for Apollo java, golang client](https://github.com/apolloconfig/apollo-java/pull/79) +* [Feature support pulling configuration information from multiple AppIds](https://github.com/apolloconfig/apollo-java/pull/70) ------------------ 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 02ccdc36..2886823b 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,11 +19,13 @@ 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.internals.ConfigMonitorInitializer; import com.ctrip.framework.apollo.monitor.api.ConfigMonitor; 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 @@ -91,6 +93,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); } @@ -111,16 +117,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("Provided appId '" + appId + "' does not match the default appId '" + m_configUtil.getAppId() + "'"); + } + 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 22ba6cde..3afddcbe 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 5ef1d37f..368725d4 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 @@ -47,6 +47,7 @@ public abstract class AbstractConfigFile implements ConfigFile, RepositoryChange private static final Logger logger = DeferredLoggerFactory.getLogger(AbstractConfigFile.class); protected 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(); @@ -59,8 +60,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); @@ -82,6 +84,11 @@ private void initialize() { } } + @Override + public String getAppId() { + return m_appId; + } + @Override public String getNamespace() { return m_namespace; @@ -91,6 +98,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; } @@ -112,7 +124,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 6b00c4c0..c21a4abb 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 @@ -64,10 +64,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 586391f0..6bc3cf51 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,9 +16,12 @@ */ package com.ctrip.framework.apollo.internals; +import com.ctrip.framework.apollo.build.ApolloInjector; import static com.ctrip.framework.apollo.monitor.internal.ApolloClientMonitorConstant.*; 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; @@ -47,6 +50,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; @@ -62,8 +66,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 @@ -219,6 +238,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; } @@ -235,7 +259,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); } @@ -248,7 +272,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<>(); @@ -299,11 +323,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(); @@ -311,7 +341,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 81c4081c..6cfb88ac 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 @@ -25,8 +25,12 @@ import com.ctrip.framework.apollo.enums.ConfigSourceType; 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.ctrip.framework.apollo.tracer.Tracer; import com.google.common.collect.Maps; +import com.google.common.collect.Table; +import com.google.common.collect.Tables; import java.util.Map; /** @@ -35,29 +39,41 @@ 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 = Tables.synchronizedTable(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); } } } @@ -70,19 +86,25 @@ public Config getConfig(String namespace) { @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/K8sConfigMapConfigRepository.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/K8sConfigMapConfigRepository.java index 5b5f9124..67643e61 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/K8sConfigMapConfigRepository.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/internals/K8sConfigMapConfigRepository.java @@ -44,6 +44,7 @@ public class K8sConfigMapConfigRepository extends AbstractConfigRepository implements RepositoryChangeListener { private static final Logger logger = DeferredLoggerFactory.getLogger(K8sConfigMapConfigRepository.class); + private final String appId; private final String namespace; private String configMapName; private String configMapKey; @@ -55,8 +56,8 @@ public class K8sConfigMapConfigRepository extends AbstractConfigRepository private volatile ConfigSourceType sourceType = ConfigSourceType.CONFIGMAP; private static final Gson GSON = new Gson(); - - public K8sConfigMapConfigRepository(String namespace, ConfigRepository upstream) { + public K8sConfigMapConfigRepository(String appId, String namespace, ConfigRepository upstream) { + this.appId = appId; this.namespace = namespace; configUtil = ApolloInjector.getInstance(ConfigUtil.class); kubernetesManager = ApolloInjector.getInstance(KubernetesManager.class); @@ -218,6 +219,11 @@ private synchronized void updateConfigMapProperties(Properties newProperties, Co persistConfigMap(configMapProperties); } + @Override + public void onRepositoryChange(String namespace, Properties newProperties) { + this.onRepositoryChange(appId, namespace, newProperties); + } + /** * Update the memory * @@ -225,14 +231,14 @@ private synchronized void updateConfigMapProperties(Properties newProperties, Co * @param newProperties the properties after change */ @Override - public void onRepositoryChange(String namespace, Properties newProperties) { + public void onRepositoryChange(String appId, String namespace, Properties newProperties) { if (newProperties == null || newProperties.equals(configMapProperties)) { return; } Properties newFileProperties = propertiesFactory.getPropertiesInstance(); newFileProperties.putAll(newProperties); updateConfigMapProperties(newFileProperties, upstream.getSourceType()); - this.fireRepositoryChange(namespace, newProperties); + this.fireRepositoryChange(appId, namespace, newProperties); } void persistConfigMap(Properties properties) { 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 52786384..29d8b7ca 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 @@ -50,6 +50,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; @@ -63,11 +64,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); @@ -84,7 +86,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); @@ -129,13 +131,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 @@ -151,7 +158,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) { @@ -192,13 +199,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()) { @@ -230,11 +237,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; @@ -288,10 +295,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 ccc75576..4f52575b 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 @@ -40,11 +40,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; @@ -54,11 +57,7 @@ import java.net.SocketTimeoutException; 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; @@ -78,9 +77,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 ConcurrentMap 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(); @@ -96,12 +95,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(); @@ -111,25 +109,27 @@ 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.computeIfAbsent( + appId, k -> Multimaps.synchronizedSetMultimap(HashMultimap.create())); + boolean result = repositoryMultimap.put(namespace, remoteConfigRepository); + m_notifications.put(appId, namespace, INIT_NOTIFICATION_ID); + if (m_longPollStarted.get(appId) == null) { + startLongPolling(appId); } - return added; + 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 @@ -146,7 +146,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); @@ -177,7 +177,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); @@ -195,10 +195,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 @@ -215,11 +215,11 @@ private void doLongPollingRefresh(String appId, String cluster, String dataCente transaction.setStatus(ex); long sleepTimeInSecond = m_longPollFailSchedulePolicyInSecond.fail(); if (ex.getCause() instanceof SocketTimeoutException) { - Tracer.logEvent(APOLLO_CLIENT_NAMESPACE_TIMEOUT, assembleNamespaces()); + Tracer.logEvent(APOLLO_CLIENT_NAMESPACE_TIMEOUT, assembleNamespaces(appId)); } 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) { @@ -231,20 +231,24 @@ 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; } + Multimap namespaceRepositories = m_longPollNamespaces.get(appId); + if (namespaceRepositories == null) { + return; + } for (ApolloConfigNotification notification : notifications) { String namespaceName = notification.getNamespaceName(); //create a new list to avoid ConcurrentModificationException List toBeNotified = - Lists.newArrayList(m_longPollNamespaces.get(namespaceName)); + Lists.newArrayList(namespaceRepositories.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()))); + toBeNotified.addAll(namespaceRepositories.get( + String.format("%s.%s", namespaceName, ConfigFileFormat.Properties.getValue()))); for (RemoteConfigRepository remoteConfigRepository : toBeNotified) { try { remoteConfigRepository.onLongPollNotified(lastServiceDto, remoteMessages); @@ -255,20 +259,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()); } } } @@ -294,8 +298,12 @@ private void updateRemoteNotifications(List deltaNotif } } - private String assembleNamespaces() { - return STRING_JOINER.join(m_longPollNamespaces.keySet()); + private String assembleNamespaces(String appId) { + Multimap namespaceRepositories = m_longPollNamespaces.get(appId); + if (namespaceRepositories == null) { + return ""; + } + return STRING_JOINER.join(namespaceRepositories.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 879f243c..e779c80b 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 @@ -74,6 +74,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; protected final static ScheduledExecutorService m_executorService; private final AtomicReference m_longPollServiceDto; @@ -91,9 +92,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); @@ -159,7 +162,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) { @@ -190,10 +193,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 @@ -337,7 +340,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 2d333988..6a627aeb 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 @@ -17,6 +17,7 @@ package com.ctrip.framework.apollo.internals; import static com.ctrip.framework.apollo.monitor.internal.ApolloClientMonitorConstant.*; +import com.ctrip.framework.apollo.build.ApolloInjector; import com.ctrip.framework.apollo.enums.ConfigSourceType; import java.util.Collections; import java.util.List; @@ -24,6 +25,7 @@ import java.util.Properties; import java.util.Set; +import com.ctrip.framework.apollo.util.ConfigUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,6 +40,7 @@ */ 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; @@ -50,6 +53,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(); @@ -94,13 +112,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 @@ -112,7 +135,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 05f87569..1930c716 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 @@ -37,8 +37,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..69fa829f 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; } @@ -82,7 +88,8 @@ public String getNamespace() { @Override public String toString() { final StringBuilder sb = new StringBuilder("ConfigChange{"); - sb.append("namespace='").append(namespace).append('\''); + sb.append("appid='").append(appId).append('\''); + sb.append(", namespace='").append(namespace).append('\''); sb.append(", propertyName='").append(propertyName).append('\''); sb.append(", oldValue='").append(oldValue).append('\''); sb.append(", newValue='").append(newValue).append('\''); 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 d74b6c63..e202fba8 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 @@ -65,6 +65,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; @@ -74,66 +79,72 @@ 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(namespace, configRepository); + return this.createRepositoryConfig(appId, namespace, configRepository); } - protected Config createRepositoryConfig(String namespace, ConfigRepository configRepository) { - return new DefaultConfig(namespace, configRepository); + @Override + public ConfigFile createConfigFile(String namespace, ConfigFileFormat configFileFormat) { + return this.createConfigFile(m_configUtil.getAppId(), namespace, configFileFormat); + } + + 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.isPropertyKubernetesCacheEnabled()) { - return createConfigMapConfigRepository(namespace); + return createConfigMapConfigRepository(appId, namespace); } else 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)); } /** @@ -141,16 +152,15 @@ LocalFileConfigRepository createLocalConfigRepository(String namespace) { * @param namespace the namespace of the repository * @return the newly created repository for the given namespace */ - private ConfigRepository createConfigMapConfigRepository(String namespace) { - return new K8sConfigMapConfigRepository(namespace, createLocalConfigRepository(namespace)); + private ConfigRepository createConfigMapConfigRepository(String appId, String namespace) { + return new K8sConfigMapConfigRepository(appId, namespace, createLocalConfigRepository(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 appId, String namespace, ConfigFileFormat format) { String actualNamespaceName = trimNamespaceFormat(namespace, format); PropertiesCompatibleConfigFile configFile = (PropertiesCompatibleConfigFile) ConfigService .getConfigFile(actualNamespaceName, format); 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..a574defe 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,10 +16,11 @@ */ package com.ctrip.framework.apollo.spi; -import java.util.Map; - import com.ctrip.framework.apollo.build.ApolloInjector; -import com.google.common.collect.Maps; +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; /** * @author Jason Song(song_s@ctrip.com) @@ -27,23 +28,31 @@ public class DefaultConfigFactoryManager implements ConfigFactoryManager { private ConfigRegistry m_registry; - private Map m_factories = Maps.newConcurrentMap(); + private Table m_factories = Tables.synchronizedTable(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 +68,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..e5d8685b 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); @@ -129,6 +131,7 @@ private void processApolloConfigChangeListener(final Object bean, final Method m method); ReflectionUtils.makeAccessible(method); + String appId = StringUtils.defaultIfBlank(annotation.appId(), configUtil.getAppId()); String[] namespaces = annotation.value(); String[] annotatedInterestedKeys = annotation.interestedKeys(); String[] annotatedInterestedKeyPrefixes = annotation.interestedKeyPrefixes(); @@ -143,7 +146,7 @@ private void processApolloConfigChangeListener(final Object bean, final Method m Set resolvedNamespaces = processResolveNamespaceValue(namespaces); for (String namespace : resolvedNamespaces) { - Config config = ConfigService.getConfig(namespace); + Config config = ConfigService.getConfig(appId, namespace); if (interestedKeys == null && interestedKeyPrefixes == null) { config.addChangeListener(configChangeListener); 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/ApolloConfigChangeListener.java b/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloConfigChangeListener.java index d5015f5b..6d2248b2 100644 --- a/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloConfigChangeListener.java +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloConfigChangeListener.java @@ -59,6 +59,13 @@ @Target(ElementType.METHOD) @Documented public @interface ApolloConfigChangeListener { + + /** + * Apollo appId for the config, if not specified then default to application + * @return + */ + 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..781c149d 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,13 @@ * @return */ int order() default Ordered.LOWEST_PRECEDENCE; + + /** + * Additional appId and namespace configurations. Will not participate in bootstrap + * e.g. + * @EnableApolloConfig(value = {"someNamespace", "anotherNamespace"}, + * multipleConfigs = {@MultipleConfig(appId = "anotherAppId", namespaces = {"yetAnotherNamespace"}, secert="${xxxx.secret}")}) + * @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..e4572f9a --- /dev/null +++ b/apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/MultipleConfig.java @@ -0,0 +1,59 @@ +/* + * 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 org.springframework.core.Ordered; + +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 ""; + + /** + * multiple config order sort. + * @return + */ + int order() default Ordered.LOWEST_PRECEDENCE; +} 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..543aa423 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,17 +20,20 @@ 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; import com.ctrip.framework.apollo.util.ConfigUtil; import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; import java.util.Collection; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; @@ -41,7 +44,10 @@ import org.springframework.context.EnvironmentAware; import org.springframework.core.Ordered; import org.springframework.core.PriorityOrdered; -import org.springframework.core.env.*; +import org.springframework.core.env.CompositePropertySource; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.Environment; +import org.springframework.core.env.StandardEnvironment; /** * Apollo Property Sources processor for Spring Annotation Based Application.

@@ -55,7 +61,7 @@ */ public class PropertySourcesProcessor implements BeanFactoryPostProcessor, EnvironmentAware, ApplicationEventPublisherAware, PriorityOrdered { - private static final Multimap NAMESPACE_NAMES = LinkedHashMultimap.create(); + private static final Map> APP_NAMESPACE_NAMES = Maps.newHashMap(); private static final Set AUTO_UPDATE_INITIALIZED_BEAN_FACTORIES = Sets.newConcurrentHashSet(); private final ConfigPropertySourceFactory configPropertySourceFactory = SpringInjector @@ -65,7 +71,16 @@ 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 multimap = APP_NAMESPACE_NAMES.get(order); + if (multimap == null) { + multimap = LinkedHashMultimap.create(); + APP_NAMESPACE_NAMES.put(order, multimap); + } + return multimap.putAll(appId, namespaces); } @Override @@ -88,20 +103,27 @@ 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); - - composite.addPropertySource(configPropertySourceFactory.getConfigPropertySource(namespace, config)); + 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( + 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 +175,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..b17a1520 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,7 +16,9 @@ */ 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.core.utils.StringUtils; import com.ctrip.framework.apollo.spring.annotation.ApolloAnnotationProcessor; import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig; import com.ctrip.framework.apollo.spring.annotation.SpringValueProcessor; @@ -24,9 +26,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 +36,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 +53,26 @@ 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); + + // put main appId + PropertySourcesProcessor.addNamespaces(configUtil.getAppId(), Lists.newArrayList(this.resolveNamespaces(namespaces)), order); + + // put multiple appId into + AnnotationAttributes[] multipleConfigs = attributes.getAnnotationArray("multipleConfigs"); + if (multipleConfigs != null) { + for (AnnotationAttributes multipleConfig : multipleConfigs) { + String appId = multipleConfig.getString("appId"); + String[] multipleNamespaces = this.resolveNamespaces(multipleConfig.getStringArray("namespaces")); + String secret = resolveSecret(multipleConfig.getString("secret")); + int multipleOrder = multipleConfig.getNumber("order"); + + // put multiple secret into system property + if (!StringUtils.isBlank(secret)) { + System.setProperty("apollo.accesskey." + appId + ".secret", secret); + } + PropertySourcesProcessor.addNamespaces(appId, Lists.newArrayList(multipleNamespaces), multipleOrder); + } + } Map propertySourcesPlaceholderPropertyValues = new HashMap<>(); // to make sure the default PropertySourcesPlaceholderConfigurer's priority is higher than PropertyPlaceholderConfigurer @@ -77,6 +101,16 @@ private String[] resolveNamespaces(String[] namespaces) { return resolvedNamespaces; } + private String resolveSecret(String secret){ + if (this.environment == null) { + if (secret != null && secret.contains("${")) { + 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("${")) { @@ -97,4 +131,4 @@ public int getOrder() { public void setEnvironment(Environment environment) { this.environment = environment; } -} \ No newline at end of file +} 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 e322491c..457f3f32 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 @@ -320,6 +320,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); @@ -625,4 +636,8 @@ private boolean getPropertyBoolean(String propertyName, String envName, boolean } return defaultVal; } -} \ No newline at end of file + + 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..04fa4d31 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 @@ -28,6 +28,7 @@ import java.io.IOException; import java.net.ServerSocket; import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Map; import java.util.Properties; import java.util.concurrent.TimeUnit; @@ -36,7 +37,6 @@ import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.utils.ClassLoaderUtil; import com.ctrip.framework.apollo.util.ConfigUtil; -import com.google.gson.Gson; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.slf4j.Logger; @@ -119,9 +119,10 @@ public void setUp() throws Exception { System.setProperty(ConfigConsts.APOLLO_META_KEY, metaServiceUrl); ReflectionTestUtils.invokeMethod(MetaDomainConsts.class, "reset"); - MockInjector.setInstance(ConfigUtil.class, new MockConfigUtil()); + MockConfigUtil mockConfigUtil = new MockConfigUtil(); + MockInjector.setInstance(ConfigUtil.class, mockConfigUtil); + configDir = new File(mockConfigUtil.getDefaultLocalCacheDir(someAppId)+ "/config-cache"); - configDir = new File(ClassLoaderUtil.getClassPath() + "config-cache"); if (configDir.exists()) { configDir.delete(); } @@ -275,6 +276,16 @@ public long getLongPollingInitialDelayInMills() { public boolean isPropertiesOrderEnabled() { return propertiesOrderEnabled; } + + @Override + public String getDefaultLocalCacheDir(String appId) { + String path = ClassLoaderUtil.getClassPath() + "/" + appId; + if(isOSWindows()){ + // because there is an extra / in front of the windows system + path = Paths.get(path.substring(1)).toString(); + } + return path; + } } /** 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..65f0c2f4 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 @@ -59,11 +59,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 +74,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 +86,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 +97,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 +104,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 +118,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 +134,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 +143,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 +160,11 @@ public boolean hasContent() { return true; } + @Override + public String getAppId() { + return m_appId; + } + @Override public String getNamespace() { return m_namespace; @@ -180,12 +194,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/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/K8sConfigMapConfigRepositoryTest.java b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/K8sConfigMapConfigRepositoryTest.java index f0c02071..6a0fe102 100644 --- a/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/K8sConfigMapConfigRepositoryTest.java +++ b/apollo-client/src/test/java/com/ctrip/framework/apollo/internals/K8sConfigMapConfigRepositoryTest.java @@ -78,7 +78,7 @@ public void setUp() { .metadata(new V1ObjectMeta().name(someAppId).namespace(someNamespace)) .data(data); - k8sConfigMapConfigRepository = new K8sConfigMapConfigRepository(someNamespace, upstreamRepo); + k8sConfigMapConfigRepository = new K8sConfigMapConfigRepository(someAppId, someNamespace, upstreamRepo); } /** @@ -164,7 +164,7 @@ public void testOnRepositoryChange() throws ApiException { Properties newProperties = new Properties(); newProperties.setProperty(defaultKey, defaultValue); // Act - k8sConfigMapConfigRepository.onRepositoryChange(someNamespace, newProperties); + k8sConfigMapConfigRepository.onRepositoryChange(someAppId, someNamespace, newProperties); // Assert verify(kubernetesManager, times(1)).updateConfigMap(anyString(), anyString(), anyMap()); } 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..29ca1f88 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 @@ -80,6 +80,9 @@ public class RemoteConfigLongPollServiceTest { @Before public void setUp() throws Exception { + someAppId = "someAppId"; + someCluster = "someCluster"; + MockInjector.setInstance(HttpClient.class, httpClient); someServerUrl = "http://someServer"; @@ -95,8 +98,7 @@ public void setUp() throws Exception { responseType = (Type) ReflectionTestUtils.getField(remoteConfigLongPollService, "m_responseType"); - someAppId = "someAppId"; - someCluster = "someCluster"; + } @After @@ -133,7 +135,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 +186,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,7 +248,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); remoteConfigLongPollService.stopLongPollingRefresh(); @@ -317,10 +319,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 +390,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 +451,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 +579,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..0c64cf5f 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 @@ -126,6 +126,7 @@ public Properties answer(InvocationOnMock invocation) { someAppId = "someAppId"; someCluster = "someCluster"; + } @After @@ -145,7 +146,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 +172,7 @@ public Properties answer(InvocationOnMock invocation) { } }); - RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someNamespace); + RemoteConfigRepository remoteConfigRepository = new RemoteConfigRepository(someAppId, someNamespace); Properties config = remoteConfigRepository.getConfig(); @@ -208,7 +209,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 +222,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 +235,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 +252,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 +263,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 +286,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 +312,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 +340,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 +417,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..3cd53380 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 @@ -80,7 +80,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 +95,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 +113,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 +132,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,21 +187,26 @@ 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)); } 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..d09a69c4 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 @@ -27,13 +27,13 @@ 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; import java.io.InputStreamReader; -import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import java.nio.charset.StandardCharsets; import java.util.Calendar; import java.util.Date; @@ -52,18 +52,18 @@ import com.ctrip.framework.apollo.core.enums.ConfigFileFormat; import com.ctrip.framework.apollo.internals.ConfigManager; import com.google.common.collect.Maps; -import org.springframework.util.ReflectionUtils.FieldCallback; -import org.springframework.util.ReflectionUtils.FieldFilter; /** * @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; + protected static String someAppId = "someAppId"; + static { try { CONFIG_SERVICE_RESET = ConfigService.class.getDeclaredMethod("reset"); @@ -85,14 +85,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, namespaceName, configRepository); - mockConfig(namespaceName, config); + mockConfig(appId, namespaceName, config); return config; } @@ -113,15 +113,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,50 +161,73 @@ 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 { //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 ReflectionUtils.invokeMethod(PROPERTY_SOURCES_PROCESSOR_RESET, null); + + MockConfigUtil configUtil = new MockConfigUtil(); + configUtil.setAutoUpdateInjectedSpringProperties(true); + MockInjector.setInstance(ConfigUtil.class, configUtil); + DefaultInjector defaultInjector = new DefaultInjector(); ConfigManager defaultConfigManager = defaultInjector.getInstance(ConfigManager.class); MockInjector.setInstance(ConfigManager.class, new MockConfigManager(defaultConfigManager)); MockInjector.setDelegate(defaultInjector); + } protected static void doTearDown() { MockInjector.reset(); CONFIG_REGISTRY.clear(); + CONFIG_FILE_REGISTRY.clear(); } private static class MockConfigManager implements ConfigManager { private final ConfigManager delegate; + private final String defaultAppId = someAppId; + public MockConfigManager(ConfigManager delegate) { this.delegate = delegate; } @Override public Config getConfig(String namespace) { - Config config = CONFIG_REGISTRY.get(namespace); + return getConfig(defaultAppId, 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(defaultAppId, 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 +247,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..a7dd1162 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 @@ -62,6 +62,7 @@ public class BootstrapConfigTest { @DirtiesContext public static class TestWithBootstrapEnabledAndDefaultNamespacesAndConditionalOn extends AbstractSpringIntegrationTest { + private static final String someProperty = "someProperty"; private static final String someValue = "someValue"; @@ -90,7 +91,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 +135,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 +171,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 +213,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 +245,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 +279,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 +312,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 +348,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 +377,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 +401,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,7 +409,7 @@ public static void beforeClass() { Config config = mock(Config.class); - mockConfig(ConfigConsts.NAMESPACE_APPLICATION, config); + mockConfig(someAppId, ConfigConsts.NAMESPACE_APPLICATION, config); } @AfterClass 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..146a3e98 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,6 +29,8 @@ 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.util.ConfigUtil; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.common.util.concurrent.SettableFuture; @@ -106,10 +109,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 +128,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 +138,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 +154,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 +169,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 +178,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 +190,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 +205,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 +259,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 +268,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 +278,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 +335,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 +367,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 +393,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 +432,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 +443,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 +457,18 @@ 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"); + // Because Configutil has been initialized a long time ago, + // setting this system variable does not cause configutil to reload, + // thereby getting the value of this system variable. + // Therefore, we need to re -initialize the Configutil here to get the value of the system variable loaded to the configutil. + MockConfigUtil configUtil = new MockConfigUtil(); + MockInjector.setInstance(ConfigUtil.class, configUtil); getSimpleBean(TestApolloConfigChangeListenerResolveExpressionSimpleConfiguration.class); @@ -483,13 +492,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 +517,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 +538,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 +562,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 +577,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 +606,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 +614,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 +624,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 +638,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 +1092,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..977018ea 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 @@ -70,7 +70,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 +97,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 +125,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 +157,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 +195,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 +225,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 +237,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 +266,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 +279,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 +294,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 +324,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 +336,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 +350,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 +381,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 +393,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 +409,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 +420,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 +433,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 +443,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 +461,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 +490,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 +519,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 +545,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 +573,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 +604,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 +635,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 +666,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 +698,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 +726,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 +755,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 +790,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 +855,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 +890,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 +916,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 +929,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 +943,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 +956,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 +970,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 +983,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..c8cf898e 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 @@ -70,7 +70,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 +78,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 +91,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 +107,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 +123,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 +135,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 +157,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 +176,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 +195,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 +213,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 +231,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 +250,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 +272,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 +293,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 +311,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 +334,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 +356,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 +374,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 +405,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 +424,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 +432,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..97a1f5eb 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 @@ -55,8 +55,8 @@ 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 +69,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 +79,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 +134,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 +143,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 +153,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..d1ac366b 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 @@ -51,7 +51,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 +63,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 +86,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 +98,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 +118,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 +163,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 +176,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 +193,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 +207,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 +228,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 +242,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 +258,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 +269,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 +288,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 +318,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 +329,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 +347,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 +359,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 +377,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 +389,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 +408,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 +420,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 +467,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 +496,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..9b146a44 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 @@ -62,7 +62,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 +70,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 +84,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 +97,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 +113,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..78e5c515 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 @@ -16,12 +16,16 @@ */ package com.ctrip.framework.apollo.spring.config; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import com.ctrip.framework.apollo.Config; import com.ctrip.framework.apollo.ConfigChangeListener; -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.ConfigConsts; @@ -30,15 +34,18 @@ import com.ctrip.framework.apollo.spring.events.ApolloConfigChangeEvent; import com.ctrip.framework.apollo.util.ConfigUtil; import com.google.common.collect.Lists; +import java.util.Properties; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.context.ApplicationEventPublisher; -import org.springframework.core.env.*; - -import java.util.Properties; +import org.springframework.core.env.CompositePropertySource; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MutablePropertySources; +import org.springframework.core.env.PropertiesPropertySource; +import org.springframework.core.env.StandardEnvironment; public class PropertySourcesProcessorTest extends AbstractSpringIntegrationTest { @@ -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 e9f8ea1e..c8e0d5e4 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 @@ -225,7 +225,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 @@ -238,11 +238,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..6e9d354a 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", null); + } + 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);