Commit d47d0f83 authored by Jason Song's avatar Jason Song

refactor according to code review comments

parent 51d510ad
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ctrip.framework.apollo</groupId> <groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId> <artifactId>apollo</artifactId>
<version>0.0.1</version> <version>0.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ctrip.framework.apollo</groupId> <groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId> <artifactId>apollo</artifactId>
<version>0.0.1</version> <version>0.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<parent> <parent>
<artifactId>apollo</artifactId> <artifactId>apollo</artifactId>
<groupId>com.ctrip.framework.apollo</groupId> <groupId>com.ctrip.framework.apollo</groupId>
<version>0.0.1</version> <version>0.0.2-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>apollo-biz</artifactId> <artifactId>apollo-biz</artifactId>
......
...@@ -49,7 +49,7 @@ public class AppNamespaceService { ...@@ -49,7 +49,7 @@ public class AppNamespaceService {
} }
AppNamespace appNs = new AppNamespace(); AppNamespace appNs = new AppNamespace();
appNs.setAppId(appId); appNs.setAppId(appId);
appNs.setName(ConfigConsts.NAMESPACE_DEFAULT); appNs.setName(ConfigConsts.NAMESPACE_APPLICATION);
appNs.setComment("default app namespace"); appNs.setComment("default app namespace");
appNs.setDataChangeCreatedBy(createBy); appNs.setDataChangeCreatedBy(createBy);
appNs.setDataChangeLastModifiedBy(createBy); appNs.setDataChangeLastModifiedBy(createBy);
...@@ -74,7 +74,7 @@ public class AppNamespaceService { ...@@ -74,7 +74,7 @@ public class AppNamespaceService {
} }
public List<AppNamespace> findPublicAppNamespaces(){ public List<AppNamespace> findPublicAppNamespaces(){
return appNamespaceRepository.findByNameNot(ConfigConsts.NAMESPACE_DEFAULT); return appNamespaceRepository.findByNameNot(ConfigConsts.NAMESPACE_APPLICATION);
} }
public AppNamespace update(AppNamespace appNamespace){ public AppNamespace update(AppNamespace appNamespace){
......
...@@ -91,7 +91,7 @@ public class NamespaceService { ...@@ -91,7 +91,7 @@ public class NamespaceService {
Namespace ns = new Namespace(); Namespace ns = new Namespace();
ns.setAppId(appId); ns.setAppId(appId);
ns.setClusterName(ConfigConsts.CLUSTER_NAME_DEFAULT); ns.setClusterName(ConfigConsts.CLUSTER_NAME_DEFAULT);
ns.setNamespaceName(ConfigConsts.NAMESPACE_DEFAULT); ns.setNamespaceName(ConfigConsts.NAMESPACE_APPLICATION);
ns.setDataChangeCreatedBy(createBy); ns.setDataChangeCreatedBy(createBy);
ns.setDataChangeLastModifiedBy(createBy); ns.setDataChangeLastModifiedBy(createBy);
namespaceRepository.save(ns); namespaceRepository.save(ns);
......
...@@ -26,7 +26,7 @@ public class AppNamespaceRepositoryTest { ...@@ -26,7 +26,7 @@ public class AppNamespaceRepositoryTest {
@Test @Test
public void testFindAllPublicAppNamespaces(){ public void testFindAllPublicAppNamespaces(){
List<AppNamespace> appNamespaceList = repository.findByNameNot(ConfigConsts.NAMESPACE_DEFAULT); List<AppNamespace> appNamespaceList = repository.findByNameNot(ConfigConsts.NAMESPACE_APPLICATION);
Assert.assertEquals(4, appNamespaceList.size()); Assert.assertEquals(4, appNamespaceList.size());
} }
......
...@@ -64,7 +64,7 @@ public class AdminServiceTest { ...@@ -64,7 +64,7 @@ public class AdminServiceTest {
List<Namespace> namespaces = namespaceService.findNamespaces(appId, clusters.get(0).getName()); List<Namespace> namespaces = namespaceService.findNamespaces(appId, clusters.get(0).getName());
Assert.assertEquals(1, namespaces.size()); Assert.assertEquals(1, namespaces.size());
Assert.assertEquals(ConfigConsts.NAMESPACE_DEFAULT, namespaces.get(0).getNamespaceName()); Assert.assertEquals(ConfigConsts.NAMESPACE_APPLICATION, namespaces.get(0).getNamespaceName());
List<Audit> audits = auditService.findByOwner(owner); List<Audit> audits = auditService.findByOwner(owner);
Assert.assertEquals(4, audits.size()); Assert.assertEquals(4, audits.size());
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ctrip.framework.apollo</groupId> <groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId> <artifactId>apollo</artifactId>
<version>0.0.1</version> <version>0.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
...@@ -37,6 +37,14 @@ Environment could be configured in 3 ways: ...@@ -37,6 +37,14 @@ Environment could be configured in 3 ways:
* And specify the environment in the file as `env=YOUR-ENVIRONMENT` * And specify the environment in the file as `env=YOUR-ENVIRONMENT`
* Please note the key should be lower case * Please note the key should be lower case
Currently, `env` allows the following values (case-insensitive):
* DEV
* FWS
* FAT
* UAT
* PRO
### I.II Optional Setup ### I.II Optional Setup
#### Cluster #### Cluster
...@@ -76,7 +84,7 @@ If you need this functionality, you could specify the cluster as follows: ...@@ -76,7 +84,7 @@ If you need this functionality, you could specify the cluster as follows:
<dependency> <dependency>
<groupId>com.ctrip.framework.apollo</groupId> <groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId> <artifactId>apollo-client</artifactId>
<version>0.0.1</version> <version>0.0.2-SNAPSHOT</version>
</dependency> </dependency>
## III. Client Usage ## III. Client Usage
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ctrip.framework.apollo</groupId> <groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId> <artifactId>apollo</artifactId>
<version>0.0.1</version> <version>0.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
package com.ctrip.framework.apollo; package com.ctrip.framework.apollo;
import com.ctrip.framework.apollo.core.ConfigConsts; import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.exceptions.ApolloConfigException;
import com.ctrip.framework.apollo.internals.ConfigManager; import com.ctrip.framework.apollo.internals.ConfigManager;
import com.ctrip.framework.apollo.spi.ConfigFactory; import com.ctrip.framework.apollo.spi.ConfigFactory;
import com.ctrip.framework.apollo.spi.ConfigRegistry; import com.ctrip.framework.apollo.spi.ConfigRegistry;
...@@ -28,7 +29,7 @@ public class ConfigService { ...@@ -28,7 +29,7 @@ public class ConfigService {
* @return config instance * @return config instance
*/ */
public static Config getAppConfig() { public static Config getAppConfig() {
return getConfig(ConfigConsts.NAMESPACE_DEFAULT); return getConfig(ConfigConsts.NAMESPACE_APPLICATION);
} }
/** /**
...@@ -37,7 +38,7 @@ public class ConfigService { ...@@ -37,7 +38,7 @@ public class ConfigService {
* @return config instance * @return config instance
*/ */
public static Config getConfig(String namespace) { public static Config getConfig(String namespace) {
Cat.logEvent("Apollo.Client.Version", Apollo.VERSION);
return getManager().getConfig(namespace); return getManager().getConfig(namespace);
} }
...@@ -45,8 +46,9 @@ public class ConfigService { ...@@ -45,8 +46,9 @@ public class ConfigService {
try { try {
return s_instance.m_container.lookup(ConfigManager.class); return s_instance.m_container.lookup(ConfigManager.class);
} catch (ComponentLookupException ex) { } catch (ComponentLookupException ex) {
Cat.logError(ex); ApolloConfigException exception = new ApolloConfigException("Unable to load ConfigManager!", ex);
throw new IllegalStateException("Unable to load ConfigManager!", ex); Cat.logError(exception);
throw exception;
} }
} }
...@@ -54,13 +56,14 @@ public class ConfigService { ...@@ -54,13 +56,14 @@ public class ConfigService {
try { try {
return s_instance.m_container.lookup(ConfigRegistry.class); return s_instance.m_container.lookup(ConfigRegistry.class);
} catch (ComponentLookupException ex) { } catch (ComponentLookupException ex) {
Cat.logError(ex); ApolloConfigException exception = new ApolloConfigException("Unable to load ConfigRegistry!", ex);
throw new IllegalStateException("Unable to load ConfigRegistry!", ex); Cat.logError(exception);
throw exception;
} }
} }
static void setConfig(Config config) { static void setConfig(Config config) {
setConfig(ConfigConsts.NAMESPACE_DEFAULT, config); setConfig(ConfigConsts.NAMESPACE_APPLICATION, config);
} }
/** /**
...@@ -78,7 +81,7 @@ public class ConfigService { ...@@ -78,7 +81,7 @@ public class ConfigService {
} }
static void setConfigFactory(ConfigFactory factory) { static void setConfigFactory(ConfigFactory factory) {
setConfigFactory(ConfigConsts.NAMESPACE_DEFAULT, factory); setConfigFactory(ConfigConsts.NAMESPACE_APPLICATION, factory);
} }
/** /**
......
package com.ctrip.framework.apollo.exceptions;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class ApolloConfigException extends RuntimeException {
public ApolloConfigException(String message) {
super(message);
}
public ApolloConfigException(String message, Throwable cause) {
super(message, cause);
}
}
...@@ -6,10 +6,13 @@ import com.google.common.collect.Sets; ...@@ -6,10 +6,13 @@ import com.google.common.collect.Sets;
import com.ctrip.framework.apollo.Config; import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigChangeListener; import com.ctrip.framework.apollo.ConfigChangeListener;
import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory;
import com.ctrip.framework.apollo.enums.PropertyChangeType; import com.ctrip.framework.apollo.enums.PropertyChangeType;
import com.ctrip.framework.apollo.model.ConfigChange; import com.ctrip.framework.apollo.model.ConfigChange;
import com.ctrip.framework.apollo.model.ConfigChangeEvent; import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.dianping.cat.Cat; import com.dianping.cat.Cat;
import com.dianping.cat.message.Message;
import com.dianping.cat.message.Transaction;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -17,14 +20,23 @@ import org.slf4j.LoggerFactory; ...@@ -17,14 +20,23 @@ import org.slf4j.LoggerFactory;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/** /**
* @author Jason Song(song_s@ctrip.com) * @author Jason Song(song_s@ctrip.com)
*/ */
public abstract class AbstractConfig implements Config { public abstract class AbstractConfig implements Config {
private static final Logger logger = LoggerFactory.getLogger(AbstractConfig.class); private static final Logger logger = LoggerFactory.getLogger(AbstractConfig.class);
private static ExecutorService m_executorService;
private List<ConfigChangeListener> m_listeners = Lists.newCopyOnWriteArrayList(); private List<ConfigChangeListener> m_listeners = Lists.newCopyOnWriteArrayList();
static {
m_executorService = Executors.newCachedThreadPool(ApolloThreadFactory
.create("Config", true));
}
@Override @Override
public void addChangeListener(ConfigChangeListener listener) { public void addChangeListener(ConfigChangeListener listener) {
if (!m_listeners.contains(listener)) { if (!m_listeners.contains(listener)) {
...@@ -80,19 +92,30 @@ public abstract class AbstractConfig implements Config { ...@@ -80,19 +92,30 @@ public abstract class AbstractConfig implements Config {
return value == null ? defaultValue : value.split(delimiter); return value == null ? defaultValue : value.split(delimiter);
} }
protected void fireConfigChange(ConfigChangeEvent changeEvent) { protected void fireConfigChange(final ConfigChangeEvent changeEvent) {
for (ConfigChangeListener listener : m_listeners) { for (final ConfigChangeListener listener : m_listeners) {
try { m_executorService.submit(new Runnable() {
listener.onChange(changeEvent); @Override
} catch (Throwable ex) { public void run() {
Cat.logError(ex); String listenerName = listener.getClass().getName();
logger.error("Failed to invoke config change listener {}", listener.getClass(), ex); Transaction transaction = Cat.newTransaction("Apollo.ConfigChangeListener", listenerName);
} try {
listener.onChange(changeEvent);
transaction.setStatus(Message.SUCCESS);
} catch (Throwable ex) {
transaction.setStatus(ex);
Cat.logError(ex);
logger.error("Failed to invoke config change listener {}", listenerName, ex);
} finally {
transaction.complete();
}
}
});
} }
} }
List<ConfigChange> calcPropertyChanges(String namespace, Properties previous, List<ConfigChange> calcPropertyChanges(String namespace, Properties previous,
Properties current) { Properties current) {
if (previous == null) { if (previous == null) {
previous = new Properties(); previous = new Properties();
} }
......
...@@ -14,9 +14,9 @@ public interface ConfigRepository { ...@@ -14,9 +14,9 @@ public interface ConfigRepository {
/** /**
* Set the fallback repo for this repository. * Set the fallback repo for this repository.
* @param fallbackConfigRepository the fallback repo * @param upstreamConfigRepository the fallback repo
*/ */
public void setFallback(ConfigRepository fallbackConfigRepository); public void setUpstreamRepository(ConfigRepository upstreamConfigRepository);
/** /**
* Add change listener. * Add change listener.
......
...@@ -10,6 +10,7 @@ import com.google.gson.reflect.TypeToken; ...@@ -10,6 +10,7 @@ import com.google.gson.reflect.TypeToken;
import com.ctrip.framework.apollo.core.dto.ServiceDTO; import com.ctrip.framework.apollo.core.dto.ServiceDTO;
import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory; import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory;
import com.ctrip.framework.apollo.exceptions.ApolloConfigException;
import com.ctrip.framework.apollo.util.ConfigUtil; import com.ctrip.framework.apollo.util.ConfigUtil;
import com.ctrip.framework.apollo.util.http.HttpRequest; import com.ctrip.framework.apollo.util.http.HttpRequest;
import com.ctrip.framework.apollo.util.http.HttpResponse; import com.ctrip.framework.apollo.util.http.HttpResponse;
...@@ -92,11 +93,8 @@ public class ConfigServiceLocator implements Initializable { ...@@ -92,11 +93,8 @@ public class ConfigServiceLocator implements Initializable {
@Override @Override
public void run() { public void run() {
logger.debug("refresh config services"); logger.debug("refresh config services");
Transaction transaction = Cat.newTransaction("Apollo.MetaService", "periodicRefresh"); Cat.logEvent("Apollo.MetaService", "periodicRefresh");
boolean syncResult = tryUpdateConfigServices(); tryUpdateConfigServices();
String status = syncResult ? Message.SUCCESS : "-1";
transaction.setStatus(status);
transaction.complete();
} }
}, m_configUtil.getRefreshInterval(), m_configUtil.getRefreshInterval(), }, m_configUtil.getRefreshInterval(), m_configUtil.getRefreshInterval(),
m_configUtil.getRefreshTimeUnit()); m_configUtil.getRefreshTimeUnit());
...@@ -138,7 +136,7 @@ public class ConfigServiceLocator implements Initializable { ...@@ -138,7 +136,7 @@ public class ConfigServiceLocator implements Initializable {
} }
} }
throw new RuntimeException( throw new ApolloConfigException(
String.format("Get config services failed from %s", url), exception); String.format("Get config services failed from %s", url), exception);
} }
......
...@@ -14,7 +14,7 @@ import java.util.Map; ...@@ -14,7 +14,7 @@ import java.util.Map;
/** /**
* @author Jason Song(song_s@ctrip.com) * @author Jason Song(song_s@ctrip.com)
*/ */
@Named(type = ConfigManager.class, value = "default") @Named(type = ConfigManager.class)
public class DefaultConfigManager implements ConfigManager { public class DefaultConfigManager implements ConfigManager {
@Inject @Inject
private ConfigFactoryManager m_factoryManager; private ConfigFactoryManager m_factoryManager;
......
...@@ -4,6 +4,8 @@ import com.google.common.base.Joiner; ...@@ -4,6 +4,8 @@ import com.google.common.base.Joiner;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.ctrip.framework.apollo.core.ConfigConsts; import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.core.utils.ClassLoaderUtil;
import com.ctrip.framework.apollo.exceptions.ApolloConfigException;
import com.ctrip.framework.apollo.util.ConfigUtil; import com.ctrip.framework.apollo.util.ConfigUtil;
import com.ctrip.framework.apollo.util.ExceptionUtil; import com.ctrip.framework.apollo.util.ExceptionUtil;
import com.dianping.cat.Cat; import com.dianping.cat.Cat;
...@@ -22,6 +24,7 @@ import java.io.FileOutputStream; ...@@ -22,6 +24,7 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.file.Files;
import java.util.Properties; import java.util.Properties;
/** /**
...@@ -30,12 +33,13 @@ import java.util.Properties; ...@@ -30,12 +33,13 @@ import java.util.Properties;
public class LocalFileConfigRepository extends AbstractConfigRepository public class LocalFileConfigRepository extends AbstractConfigRepository
implements RepositoryChangeListener { implements RepositoryChangeListener {
private static final Logger logger = LoggerFactory.getLogger(LocalFileConfigRepository.class); private static final Logger logger = LoggerFactory.getLogger(LocalFileConfigRepository.class);
private static final String CONFIG_DIR = "/config-cache";
private final PlexusContainer m_container; private final PlexusContainer m_container;
private final String m_namespace; private final String m_namespace;
private final File m_baseDir; private File m_baseDir;
private final ConfigUtil m_configUtil; private final ConfigUtil m_configUtil;
private volatile Properties m_fileProperties; private volatile Properties m_fileProperties;
private volatile ConfigRepository m_fallback; private volatile ConfigRepository m_upstream;
/** /**
* Constructor. * Constructor.
...@@ -43,16 +47,21 @@ public class LocalFileConfigRepository extends AbstractConfigRepository ...@@ -43,16 +47,21 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
* @param baseDir the base dir for this local file config repository * @param baseDir the base dir for this local file config repository
* @param namespace the namespace * @param namespace the namespace
*/ */
public LocalFileConfigRepository(File baseDir, String namespace) { public LocalFileConfigRepository(String namespace) {
m_baseDir = baseDir;
m_namespace = namespace; m_namespace = namespace;
m_container = ContainerLoader.getDefaultContainer(); m_container = ContainerLoader.getDefaultContainer();
try { try {
m_configUtil = m_container.lookup(ConfigUtil.class); m_configUtil = m_container.lookup(ConfigUtil.class);
} catch (ComponentLookupException ex) { } catch (ComponentLookupException ex) {
Cat.logError(ex); Cat.logError(ex);
throw new IllegalStateException("Unable to load component!", ex); throw new ApolloConfigException("Unable to load component!", ex);
} }
this.initialize(new File(ClassLoaderUtil.getClassPath() + CONFIG_DIR));
}
void initialize(File baseDir) {
m_baseDir = baseDir;
this.checkLocalConfigCacheDir(m_baseDir);
this.trySync(); this.trySync();
} }
...@@ -67,14 +76,14 @@ public class LocalFileConfigRepository extends AbstractConfigRepository ...@@ -67,14 +76,14 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
} }
@Override @Override
public void setFallback(ConfigRepository fallbackConfigRepository) { public void setUpstreamRepository(ConfigRepository upstreamConfigRepository) {
//clear previous listener //clear previous listener
if (m_fallback != null) { if (m_upstream != null) {
m_fallback.removeChangeListener(this); m_upstream.removeChangeListener(this);
} }
m_fallback = fallbackConfigRepository; m_upstream = upstreamConfigRepository;
trySyncFromFallback(); trySyncFromUpstream();
fallbackConfigRepository.addChangeListener(this); upstreamConfigRepository.addChangeListener(this);
} }
@Override @Override
...@@ -90,7 +99,7 @@ public class LocalFileConfigRepository extends AbstractConfigRepository ...@@ -90,7 +99,7 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
@Override @Override
protected void sync() { protected void sync() {
Transaction transaction = Cat.newTransaction("Apollo.ConfigService", "queryLocalConfigFile"); Transaction transaction = Cat.newTransaction("Apollo.ConfigService", "syncLocalConfig");
Throwable exception = null; Throwable exception = null;
try { try {
transaction.addData("Basedir", m_baseDir.getAbsolutePath()); transaction.addData("Basedir", m_baseDir.getAbsolutePath());
...@@ -106,25 +115,25 @@ public class LocalFileConfigRepository extends AbstractConfigRepository ...@@ -106,25 +115,25 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
} }
//sync with fallback immediately //sync with fallback immediately
trySyncFromFallback(); trySyncFromUpstream();
if (m_fileProperties == null) { if (m_fileProperties == null) {
throw new RuntimeException( throw new ApolloConfigException(
"Load config from local config failed!", exception); "Load config from local config failed!", exception);
} }
} }
private void trySyncFromFallback() { private void trySyncFromUpstream() {
if (m_fallback == null) { if (m_upstream == null) {
return; return;
} }
try { try {
Properties properties = m_fallback.getConfig(); Properties properties = m_upstream.getConfig();
updateFileProperties(properties); updateFileProperties(properties);
} catch (Throwable ex) { } catch (Throwable ex) {
Cat.logError(ex); Cat.logError(ex);
logger logger
.warn("Sync config from fallback repository {} failed, reason: {}", m_fallback.getClass(), .warn("Sync config from upstream repository {} failed, reason: {}", m_upstream.getClass(),
ExceptionUtil.getDetailMessage(ex)); ExceptionUtil.getDetailMessage(ex));
} }
} }
...@@ -153,7 +162,7 @@ public class LocalFileConfigRepository extends AbstractConfigRepository ...@@ -153,7 +162,7 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
properties.load(in); properties.load(in);
} catch (IOException ex) { } catch (IOException ex) {
Cat.logError(ex); Cat.logError(ex);
throw new RuntimeException(String throw new ApolloConfigException(String
.format("Loading config from local cache file %s failed", file.getAbsolutePath()), ex); .format("Loading config from local cache file %s failed", file.getAbsolutePath()), ex);
} finally { } finally {
try { try {
...@@ -165,7 +174,7 @@ public class LocalFileConfigRepository extends AbstractConfigRepository ...@@ -165,7 +174,7 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
} }
} }
} else { } else {
throw new RuntimeException( throw new ApolloConfigException(
String.format("Cannot read from local cache file %s", file.getAbsolutePath())); String.format("Cannot read from local cache file %s", file.getAbsolutePath()));
} }
...@@ -187,8 +196,11 @@ public class LocalFileConfigRepository extends AbstractConfigRepository ...@@ -187,8 +196,11 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
m_fileProperties.store(out, "Persisted by DefaultConfig"); m_fileProperties.store(out, "Persisted by DefaultConfig");
transaction.setStatus(Message.SUCCESS); transaction.setStatus(Message.SUCCESS);
} catch (IOException ex) { } catch (IOException ex) {
Cat.logError(ex); ApolloConfigException exception =
transaction.setStatus(ex); new ApolloConfigException(
String.format("Persist local cache file %s failed", file.getAbsolutePath()), ex);
Cat.logError(exception);
transaction.setStatus(exception);
logger.warn("Persist local cache file {} failed, reason: {}.", file.getAbsolutePath(), logger.warn("Persist local cache file {} failed, reason: {}.", file.getAbsolutePath(),
ExceptionUtil.getDetailMessage(ex)); ExceptionUtil.getDetailMessage(ex));
} finally { } finally {
...@@ -203,8 +215,30 @@ public class LocalFileConfigRepository extends AbstractConfigRepository ...@@ -203,8 +215,30 @@ public class LocalFileConfigRepository extends AbstractConfigRepository
} }
} }
File assembleLocalCacheFile(File baseDir, String namespace) { private void checkLocalConfigCacheDir(File baseDir) {
if (baseDir.exists()) {
return;
}
Transaction transaction = Cat.newTransaction("Apollo.ConfigService", "createLocalConfigDir");
transaction.addData("BaseDir", baseDir.getAbsolutePath());
try {
Files.createDirectory(baseDir.toPath());
transaction.setStatus(Message.SUCCESS);
} catch (IOException ex) {
ApolloConfigException exception =
new ApolloConfigException(
String.format("Create local config directory %s failed", baseDir), ex);
Cat.logError(exception);
transaction.setStatus(exception);
logger.warn(
"Unable to create local config cache directory {}, reason: {}. Will not able to cache config file.",
baseDir, ExceptionUtil.getDetailMessage(ex));
} finally {
transaction.complete();
}
}
File assembleLocalCacheFile(File baseDir, String namespace) {
String fileName = String fileName =
String.format("%s.properties", Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR) String.format("%s.properties", Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR)
.join(m_configUtil.getAppId(), m_configUtil.getCluster(), namespace)); .join(m_configUtil.getAppId(), m_configUtil.getCluster(), namespace));
......
...@@ -7,6 +7,7 @@ import com.google.common.collect.Maps; ...@@ -7,6 +7,7 @@ import com.google.common.collect.Maps;
import com.google.common.escape.Escaper; import com.google.common.escape.Escaper;
import com.google.common.net.UrlEscapers; import com.google.common.net.UrlEscapers;
import com.ctrip.framework.apollo.Apollo;
import com.ctrip.framework.apollo.core.ConfigConsts; import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.core.dto.ApolloConfig; import com.ctrip.framework.apollo.core.dto.ApolloConfig;
import com.ctrip.framework.apollo.core.dto.ApolloConfigNotification; import com.ctrip.framework.apollo.core.dto.ApolloConfigNotification;
...@@ -14,6 +15,7 @@ import com.ctrip.framework.apollo.core.dto.ServiceDTO; ...@@ -14,6 +15,7 @@ import com.ctrip.framework.apollo.core.dto.ServiceDTO;
import com.ctrip.framework.apollo.core.schedule.ExponentialSchedulePolicy; import com.ctrip.framework.apollo.core.schedule.ExponentialSchedulePolicy;
import com.ctrip.framework.apollo.core.schedule.SchedulePolicy; import com.ctrip.framework.apollo.core.schedule.SchedulePolicy;
import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory; import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory;
import com.ctrip.framework.apollo.exceptions.ApolloConfigException;
import com.ctrip.framework.apollo.util.ConfigUtil; import com.ctrip.framework.apollo.util.ConfigUtil;
import com.ctrip.framework.apollo.util.ExceptionUtil; import com.ctrip.framework.apollo.util.ExceptionUtil;
import com.ctrip.framework.apollo.util.http.HttpRequest; import com.ctrip.framework.apollo.util.http.HttpRequest;
...@@ -54,13 +56,19 @@ public class RemoteConfigRepository extends AbstractConfigRepository { ...@@ -54,13 +56,19 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
private final ConfigUtil m_configUtil; private final ConfigUtil m_configUtil;
private volatile AtomicReference<ApolloConfig> m_configCache; private volatile AtomicReference<ApolloConfig> m_configCache;
private final String m_namespace; private final String m_namespace;
private final ScheduledExecutorService m_executorService; private final static ScheduledExecutorService m_executorService;
private final ExecutorService m_longPollingService; private final ExecutorService m_longPollingService;
private final AtomicBoolean m_longPollingStopped; private final AtomicBoolean m_longPollingStopped;
private SchedulePolicy m_longPollSchedulePolicy; private SchedulePolicy m_longPollFailSchedulePolicyInSecond;
private SchedulePolicy m_longPollSuccessSchedulePolicyInMS;
private AtomicReference<ServiceDTO> m_longPollServiceDto; private AtomicReference<ServiceDTO> m_longPollServiceDto;
private AtomicReference<ApolloConfigNotification> m_longPollResult; private AtomicReference<ApolloConfigNotification> m_longPollResult;
static {
m_executorService = Executors.newScheduledThreadPool(1,
ApolloThreadFactory.create("RemoteConfigRepository", true));
}
/** /**
* Constructor. * Constructor.
* *
...@@ -76,13 +84,12 @@ public class RemoteConfigRepository extends AbstractConfigRepository { ...@@ -76,13 +84,12 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
m_serviceLocator = m_container.lookup(ConfigServiceLocator.class); m_serviceLocator = m_container.lookup(ConfigServiceLocator.class);
} catch (ComponentLookupException ex) { } catch (ComponentLookupException ex) {
Cat.logError(ex); Cat.logError(ex);
throw new IllegalStateException("Unable to load component!", ex); throw new ApolloConfigException("Unable to load component!", ex);
} }
m_longPollSchedulePolicy = new ExponentialSchedulePolicy(1, 120); m_longPollFailSchedulePolicyInSecond = new ExponentialSchedulePolicy(1, 120); //in second
m_longPollSuccessSchedulePolicyInMS = new ExponentialSchedulePolicy(100, 1000); //in millisecond
m_longPollingStopped = new AtomicBoolean(false); m_longPollingStopped = new AtomicBoolean(false);
m_executorService = Executors.newScheduledThreadPool(1, m_longPollingService = Executors.newSingleThreadExecutor(
ApolloThreadFactory.create("RemoteConfigRepository", true));
m_longPollingService = Executors.newFixedThreadPool(2,
ApolloThreadFactory.create("RemoteConfigRepository-LongPolling", true)); ApolloThreadFactory.create("RemoteConfigRepository-LongPolling", true));
m_longPollServiceDto = new AtomicReference<>(); m_longPollServiceDto = new AtomicReference<>();
m_longPollResult = new AtomicReference<>(); m_longPollResult = new AtomicReference<>();
...@@ -100,8 +107,8 @@ public class RemoteConfigRepository extends AbstractConfigRepository { ...@@ -100,8 +107,8 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
} }
@Override @Override
public void setFallback(ConfigRepository fallbackConfigRepository) { public void setUpstreamRepository(ConfigRepository upstreamConfigRepository) {
//remote config doesn't need fallback //remote config doesn't need upstream
} }
private void schedulePeriodicRefresh() { private void schedulePeriodicRefresh() {
...@@ -111,12 +118,10 @@ public class RemoteConfigRepository extends AbstractConfigRepository { ...@@ -111,12 +118,10 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
new Runnable() { new Runnable() {
@Override @Override
public void run() { public void run() {
Cat.logEvent("Apollo.ConfigService", String.format("periodicRefresh: %s", m_namespace));
logger.debug("refresh config for namespace: {}", m_namespace); logger.debug("refresh config for namespace: {}", m_namespace);
Transaction transaction = Cat.newTransaction("Apollo.ConfigService", "periodicRefresh"); trySync();
boolean syncSuccess = trySync(); Cat.logEvent("Apollo.Client.Version", Apollo.VERSION);
String status = syncSuccess ? Message.SUCCESS : "-1";
transaction.setStatus(status);
transaction.complete();
} }
}, m_configUtil.getRefreshInterval(), m_configUtil.getRefreshInterval(), }, m_configUtil.getRefreshInterval(), m_configUtil.getRefreshInterval(),
m_configUtil.getRefreshTimeUnit()); m_configUtil.getRefreshTimeUnit());
...@@ -124,19 +129,26 @@ public class RemoteConfigRepository extends AbstractConfigRepository { ...@@ -124,19 +129,26 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
@Override @Override
protected synchronized void sync() { protected synchronized void sync() {
ApolloConfig previous = m_configCache.get(); Transaction transaction = Cat.newTransaction("Apollo.ConfigService", "syncRemoteConfig");
ApolloConfig current = loadApolloConfig();
//HTTP 304, nothing changed
if (previous == current) {
return;
}
logger.debug("Remote Config refreshed!"); try {
ApolloConfig previous = m_configCache.get();
m_configCache.set(current); ApolloConfig current = loadApolloConfig();
//reference equals means HTTP 304
if (previous != current) {
logger.debug("Remote Config refreshed!");
m_configCache.set(current);
this.fireRepositoryChange(m_namespace, this.getConfig());
}
this.fireRepositoryChange(m_namespace, this.getConfig()); transaction.setStatus(Message.SUCCESS);
} catch (Throwable ex) {
transaction.setStatus(ex);
throw ex;
} finally {
transaction.complete();
}
} }
private Properties transformApolloConfigToProperties(ApolloConfig apolloConfig) { private Properties transformApolloConfigToProperties(ApolloConfig apolloConfig) {
...@@ -210,7 +222,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository { ...@@ -210,7 +222,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
String message = String.format( String message = String.format(
"Load Apollo Config failed - appId: %s, cluster: %s, namespace: %s, services: %s", "Load Apollo Config failed - appId: %s, cluster: %s, namespace: %s, services: %s",
appId, cluster, m_namespace, configServices); appId, cluster, m_namespace, configServices);
throw new RuntimeException(message, exception); throw new ApolloConfigException(message, exception);
} }
private String assembleQueryConfigUrl(String uri, String appId, String cluster, String namespace, private String assembleQueryConfigUrl(String uri, String appId, String cluster, String namespace,
...@@ -253,17 +265,17 @@ public class RemoteConfigRepository extends AbstractConfigRepository { ...@@ -253,17 +265,17 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
m_longPollingService.submit(new Runnable() { m_longPollingService.submit(new Runnable() {
@Override @Override
public void run() { public void run() {
doLongPollingRefresh(appId, cluster, dataCenter, m_longPollingService); doLongPollingRefresh(appId, cluster, dataCenter);
} }
}); });
} }
private void doLongPollingRefresh(String appId, String cluster, String dataCenter, private void doLongPollingRefresh(String appId, String cluster, String dataCenter) {
ExecutorService longPollingService) {
final Random random = new Random(); final Random random = new Random();
ServiceDTO lastServiceDto = null; ServiceDTO lastServiceDto = null;
Transaction transaction = null;
while (!m_longPollingStopped.get() && !Thread.currentThread().isInterrupted()) { while (!m_longPollingStopped.get() && !Thread.currentThread().isInterrupted()) {
Transaction transaction = Cat.newTransaction("Apollo.ConfigService", "pollNotification");
long sleepTime = 50; //default 50 ms
try { try {
if (lastServiceDto == null) { if (lastServiceDto == null) {
List<ServiceDTO> configServices = getConfigServices(); List<ServiceDTO> configServices = getConfigServices();
...@@ -279,7 +291,6 @@ public class RemoteConfigRepository extends AbstractConfigRepository { ...@@ -279,7 +291,6 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
//longer timeout for read - 1 minute //longer timeout for read - 1 minute
request.setReadTimeout(60000); request.setReadTimeout(60000);
transaction = Cat.newTransaction("Apollo.ConfigService", "pollNotification");
transaction.addData("Url", url); transaction.addData("Url", url);
HttpResponse<ApolloConfigNotification> response = HttpResponse<ApolloConfigNotification> response =
...@@ -292,35 +303,37 @@ public class RemoteConfigRepository extends AbstractConfigRepository { ...@@ -292,35 +303,37 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
m_longPollResult.set(response.getBody()); m_longPollResult.set(response.getBody());
transaction.addData("Result", response.getBody().toString()); transaction.addData("Result", response.getBody().toString());
} }
longPollingService.submit(new Runnable() { m_executorService.submit(new Runnable() {
@Override @Override
public void run() { public void run() {
trySync(); trySync();
} }
}); });
m_longPollSuccessSchedulePolicyInMS.success();
} }
m_longPollSchedulePolicy.success();
if (response.getStatusCode() == 304) {
sleepTime = m_longPollSuccessSchedulePolicyInMS.fail();
}
m_longPollFailSchedulePolicyInSecond.success();
transaction.addData("StatusCode", response.getStatusCode()); transaction.addData("StatusCode", response.getStatusCode());
transaction.setStatus(Message.SUCCESS); transaction.setStatus(Message.SUCCESS);
} catch (Throwable ex) { } catch (Throwable ex) {
lastServiceDto = null; lastServiceDto = null;
Cat.logError(ex); Cat.logError(ex);
if (transaction != null) { transaction.setStatus(ex);
transaction.setStatus(ex); long sleepTimeInSecond = m_longPollFailSchedulePolicyInSecond.fail();
}
long sleepTime = m_longPollSchedulePolicy.fail();
logger.warn( logger.warn(
"Long polling failed, will retry in {} seconds. appId: {}, cluster: {}, namespace: {}, reason: {}", "Long polling failed, will retry in {} seconds. appId: {}, cluster: {}, namespace: {}, reason: {}",
sleepTime, appId, cluster, m_namespace, ExceptionUtil.getDetailMessage(ex)); sleepTimeInSecond, appId, cluster, m_namespace, ExceptionUtil.getDetailMessage(ex));
sleepTime = sleepTimeInSecond * 1000;
} finally {
transaction.complete();
try { try {
TimeUnit.SECONDS.sleep(sleepTime); TimeUnit.MILLISECONDS.sleep(sleepTime);
} catch (InterruptedException ie) { } catch (InterruptedException ie) {
//ignore //ignore
} }
} finally {
if (transaction != null) {
transaction.complete();
}
} }
} }
} }
...@@ -364,7 +377,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository { ...@@ -364,7 +377,7 @@ public class RemoteConfigRepository extends AbstractConfigRepository {
private List<ServiceDTO> getConfigServices() { private List<ServiceDTO> getConfigServices() {
List<ServiceDTO> services = m_serviceLocator.getConfigServices(); List<ServiceDTO> services = m_serviceLocator.getConfigServices();
if (services.size() == 0) { if (services.size() == 0) {
throw new RuntimeException("No available config service"); throw new ApolloConfigException("No available config service");
} }
return services; return services;
......
package com.ctrip.framework.apollo.spi; package com.ctrip.framework.apollo.spi;
import com.ctrip.framework.apollo.Config; import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.core.utils.ClassLoaderUtil;
import com.ctrip.framework.apollo.internals.DefaultConfig; import com.ctrip.framework.apollo.internals.DefaultConfig;
import com.ctrip.framework.apollo.internals.LocalFileConfigRepository; import com.ctrip.framework.apollo.internals.LocalFileConfigRepository;
import com.ctrip.framework.apollo.internals.RemoteConfigRepository; import com.ctrip.framework.apollo.internals.RemoteConfigRepository;
import com.ctrip.framework.apollo.util.ExceptionUtil;
import com.dianping.cat.Cat;
import com.dianping.cat.message.Message;
import com.dianping.cat.message.Transaction;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.unidal.lookup.annotation.Named; import org.unidal.lookup.annotation.Named;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
/** /**
* @author Jason Song(song_s@ctrip.com) * @author Jason Song(song_s@ctrip.com)
*/ */
@Named(type = ConfigFactory.class, value = "default") @Named(type = ConfigFactory.class)
public class DefaultConfigFactory implements ConfigFactory { public class DefaultConfigFactory implements ConfigFactory {
private static final Logger logger = LoggerFactory.getLogger(DefaultConfigFactory.class); private static final Logger logger = LoggerFactory.getLogger(DefaultConfigFactory.class);
private static final String CONFIG_DIR = "/config-cache";
private File m_baseDir;
/**
* Create the config factory.
*/
public DefaultConfigFactory() {
m_baseDir = new File(ClassLoaderUtil.getClassPath() + CONFIG_DIR);
this.checkLocalConfigCacheDir(m_baseDir);
}
private void checkLocalConfigCacheDir(File baseDir) {
if (baseDir.exists()) {
return;
}
Transaction transaction = Cat.newTransaction("Apollo.ConfigService", "createLocalConfigDir");
transaction.addData("BaseDir", baseDir.getAbsolutePath());
try {
Files.createDirectory(baseDir.toPath());
transaction.setStatus(Message.SUCCESS);
} catch (IOException ex) {
Cat.logError(ex);
transaction.setStatus(ex);
logger.warn(
"Unable to create local config cache directory {}, reason: {}. Will not able to cache config file.",
baseDir, ExceptionUtil.getDetailMessage(ex));
} finally {
transaction.complete();
}
}
@Override @Override
public Config create(String namespace) { public Config create(String namespace) {
...@@ -64,8 +25,8 @@ public class DefaultConfigFactory implements ConfigFactory { ...@@ -64,8 +25,8 @@ public class DefaultConfigFactory implements ConfigFactory {
LocalFileConfigRepository createLocalConfigRepository(String namespace) { LocalFileConfigRepository createLocalConfigRepository(String namespace) {
LocalFileConfigRepository localFileConfigRepository = LocalFileConfigRepository localFileConfigRepository =
new LocalFileConfigRepository(m_baseDir, namespace); new LocalFileConfigRepository(namespace);
localFileConfigRepository.setFallback(createRemoteConfigRepository(namespace)); localFileConfigRepository.setUpstreamRepository(createRemoteConfigRepository(namespace));
return localFileConfigRepository; return localFileConfigRepository;
} }
......
...@@ -12,7 +12,7 @@ import java.util.Map; ...@@ -12,7 +12,7 @@ import java.util.Map;
/** /**
* @author Jason Song(song_s@ctrip.com) * @author Jason Song(song_s@ctrip.com)
*/ */
@Named(type = ConfigFactoryManager.class, value = "default") @Named(type = ConfigFactoryManager.class)
public class DefaultConfigFactoryManager extends ContainerHolder implements ConfigFactoryManager { public class DefaultConfigFactoryManager extends ContainerHolder implements ConfigFactoryManager {
@Inject @Inject
private ConfigRegistry m_registry; private ConfigRegistry m_registry;
...@@ -44,7 +44,7 @@ public class DefaultConfigFactoryManager extends ContainerHolder implements Conf ...@@ -44,7 +44,7 @@ public class DefaultConfigFactoryManager extends ContainerHolder implements Conf
// step 4: check default config factory // step 4: check default config factory
if (factory == null) { if (factory == null) {
factory = lookup(ConfigFactory.class, "default"); factory = lookup(ConfigFactory.class);
} }
m_factories.put(namespace, factory); m_factories.put(namespace, factory);
......
...@@ -11,7 +11,7 @@ import java.util.Map; ...@@ -11,7 +11,7 @@ import java.util.Map;
/** /**
* @author Jason Song(song_s@ctrip.com) * @author Jason Song(song_s@ctrip.com)
*/ */
@Named(type = ConfigRegistry.class, value = "default") @Named(type = ConfigRegistry.class)
public class DefaultConfigRegistry implements ConfigRegistry, LogEnabled { public class DefaultConfigRegistry implements ConfigRegistry, LogEnabled {
private Map<String, ConfigFactory> m_instances = Maps.newConcurrentMap(); private Map<String, ConfigFactory> m_instances = Maps.newConcurrentMap();
......
package com.ctrip.framework.apollo.util; package com.ctrip.framework.apollo.util;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.ctrip.framework.apollo.core.ConfigConsts; import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.core.MetaDomainConsts; import com.ctrip.framework.apollo.core.MetaDomainConsts;
...@@ -8,6 +9,8 @@ import com.ctrip.framework.apollo.core.enums.Env; ...@@ -8,6 +9,8 @@ import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.enums.EnvUtils; import com.ctrip.framework.apollo.core.enums.EnvUtils;
import com.ctrip.framework.foundation.Foundation; import com.ctrip.framework.foundation.Foundation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.unidal.lookup.annotation.Named; import org.unidal.lookup.annotation.Named;
import org.unidal.net.Networks; import org.unidal.net.Networks;
...@@ -18,11 +21,19 @@ import java.util.concurrent.TimeUnit; ...@@ -18,11 +21,19 @@ import java.util.concurrent.TimeUnit;
*/ */
@Named(type = ConfigUtil.class) @Named(type = ConfigUtil.class)
public class ConfigUtil { public class ConfigUtil {
//TODO read from config? private static final Logger logger = LoggerFactory.getLogger(ConfigUtil.class);
private static final int refreshInterval = 5; private int refreshInterval = 5;
private static final TimeUnit refreshIntervalTimeUnit = TimeUnit.MINUTES; private TimeUnit refreshIntervalTimeUnit = TimeUnit.MINUTES;
private static final int connectTimeout = 5000; //5 seconds private int connectTimeout = 5000; //5 seconds
private static final int readTimeout = 10000; //10 seconds private int readTimeout = 10000; //10 seconds
private String cluster;
public ConfigUtil() {
initRefreshInterval();
initConnectTimeout();
initReadTimeout();
initCluster();
}
/** /**
* Get the app id for the current application. * Get the app id for the current application.
...@@ -42,29 +53,30 @@ public class ConfigUtil { ...@@ -42,29 +53,30 @@ public class ConfigUtil {
* @return the current data center, null if there is no such info. * @return the current data center, null if there is no such info.
*/ */
public String getDataCenter() { public String getDataCenter() {
String dataCenter = Foundation.server().getDataCenter(); return Foundation.server().getDataCenter();
//TODO use sub env from framework foundation if data center is null
return dataCenter;
} }
/** private void initCluster() {
* Get the cluster name for the current application.
*
* @return the cluster name, or "default" if not specified
*/
public String getCluster() {
//Load data center from system property //Load data center from system property
String cluster = System.getProperty("apollo.cluster"); cluster = System.getProperty("apollo.cluster");
//Use data center as cluster //Use data center as cluster
if (cluster == null) { if (Strings.isNullOrEmpty(cluster)) {
cluster = getDataCenter(); cluster = getDataCenter();
} }
//Use default cluster //Use default cluster
if (cluster == null) { if (Strings.isNullOrEmpty(cluster)) {
cluster = ConfigConsts.CLUSTER_NAME_DEFAULT; cluster = ConfigConsts.CLUSTER_NAME_DEFAULT;
} }
}
/**
* Get the cluster name for the current application.
*
* @return the cluster name, or "default" if not specified
*/
public String getCluster() {
return cluster; return cluster;
} }
...@@ -88,14 +100,47 @@ public class ConfigUtil { ...@@ -88,14 +100,47 @@ public class ConfigUtil {
return MetaDomainConsts.getDomain(getApolloEnv()); return MetaDomainConsts.getDomain(getApolloEnv());
} }
private void initConnectTimeout() {
String customizedConnectTimeout = System.getProperty("apollo.connectTimeout");
if (!Strings.isNullOrEmpty(customizedConnectTimeout)) {
try {
connectTimeout = Integer.parseInt(customizedConnectTimeout);
} catch (Throwable ex) {
logger.error("Config for apollo.connectTimeout is invalid: {}", customizedConnectTimeout);
}
}
}
public int getConnectTimeout() { public int getConnectTimeout() {
return connectTimeout; return connectTimeout;
} }
private void initReadTimeout() {
String customizedReadTimeout = System.getProperty("apollo.readTimeout");
if (!Strings.isNullOrEmpty(customizedReadTimeout)) {
try {
readTimeout = Integer.parseInt(customizedReadTimeout);
} catch (Throwable ex) {
logger.error("Config for apollo.readTimeout is invalid: {}", customizedReadTimeout);
}
}
}
public int getReadTimeout() { public int getReadTimeout() {
return readTimeout; return readTimeout;
} }
private void initRefreshInterval() {
String customizedRefreshInterval = System.getProperty("apollo.refreshInterval");
if (!Strings.isNullOrEmpty(customizedRefreshInterval)) {
try {
refreshInterval = Integer.parseInt(customizedRefreshInterval);
} catch (Throwable ex) {
logger.error("Config for apollo.refreshInterval is invalid: {}", customizedRefreshInterval);
}
}
}
public int getRefreshInterval() { public int getRefreshInterval() {
return refreshInterval; return refreshInterval;
} }
......
...@@ -5,6 +5,7 @@ import com.google.common.base.Function; ...@@ -5,6 +5,7 @@ import com.google.common.base.Function;
import com.google.common.io.BaseEncoding; import com.google.common.io.BaseEncoding;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.ctrip.framework.apollo.exceptions.ApolloConfigException;
import com.ctrip.framework.apollo.util.ConfigUtil; import com.ctrip.framework.apollo.util.ConfigUtil;
import org.unidal.helper.Files; import org.unidal.helper.Files;
...@@ -46,7 +47,7 @@ public class HttpUtil { ...@@ -46,7 +47,7 @@ public class HttpUtil {
* @param httpRequest the request * @param httpRequest the request
* @param responseType the response type * @param responseType the response type
* @return the response * @return the response
* @throws RuntimeException if any error happened or response code is neither 200 nor 304 * @throws ApolloConfigException if any error happened or response code is neither 200 nor 304
*/ */
public <T> HttpResponse<T> doGet(HttpRequest httpRequest, final Class<T> responseType) { public <T> HttpResponse<T> doGet(HttpRequest httpRequest, final Class<T> responseType) {
Function<String, T> convertResponse = new Function<String, T>() { Function<String, T> convertResponse = new Function<String, T>() {
...@@ -65,7 +66,7 @@ public class HttpUtil { ...@@ -65,7 +66,7 @@ public class HttpUtil {
* @param httpRequest the request * @param httpRequest the request
* @param responseType the response type * @param responseType the response type
* @return the response * @return the response
* @throws RuntimeException if any error happened or response code is neither 200 nor 304 * @throws ApolloConfigException if any error happened or response code is neither 200 nor 304
*/ */
public <T> HttpResponse<T> doGet(HttpRequest httpRequest, final Type responseType) { public <T> HttpResponse<T> doGet(HttpRequest httpRequest, final Type responseType) {
Function<String, T> convertResponse = new Function<String, T>() { Function<String, T> convertResponse = new Function<String, T>() {
...@@ -116,7 +117,7 @@ public class HttpUtil { ...@@ -116,7 +117,7 @@ public class HttpUtil {
} }
} catch (Throwable ex) { } catch (Throwable ex) {
throw new RuntimeException("Could not complete get operation", ex); throw new ApolloConfigException("Could not complete get operation", ex);
} finally { } finally {
if (is != null) { if (is != null) {
try { try {
...@@ -126,7 +127,7 @@ public class HttpUtil { ...@@ -126,7 +127,7 @@ public class HttpUtil {
} }
} }
} }
throw new RuntimeException(String.format("Get operation failed for %s, status code - %d", throw new ApolloConfigException(String.format("Get operation failed for %s, status code - %d",
httpRequest.getUrl(), statusCode)); httpRequest.getUrl(), statusCode));
} }
......
...@@ -46,7 +46,7 @@ public class ConfigServiceTest extends ComponentTestCase { ...@@ -46,7 +46,7 @@ public class ConfigServiceTest extends ComponentTestCase {
Config config = ConfigService.getAppConfig(); Config config = ConfigService.getAppConfig();
assertEquals(ConfigConsts.NAMESPACE_DEFAULT + ":" + someKey, assertEquals(ConfigConsts.NAMESPACE_APPLICATION + ":" + someKey,
config.getProperty(someKey, null)); config.getProperty(someKey, null));
} }
......
...@@ -54,7 +54,7 @@ public class ConfigIntegrationTest extends BaseIntegrationTest { ...@@ -54,7 +54,7 @@ public class ConfigIntegrationTest extends BaseIntegrationTest {
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); super.setUp();
defaultNamespace = ConfigConsts.NAMESPACE_DEFAULT; defaultNamespace = ConfigConsts.NAMESPACE_APPLICATION;
someReleaseKey = "1"; someReleaseKey = "1";
configDir = new File(ClassLoaderUtil.getClassPath() + "config-cache"); configDir = new File(ClassLoaderUtil.getClassPath() + "config-cache");
configDir.mkdirs(); configDir.mkdirs();
......
...@@ -22,7 +22,7 @@ public class DefaultConfigManagerTest extends ComponentTestCase { ...@@ -22,7 +22,7 @@ public class DefaultConfigManagerTest extends ComponentTestCase {
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); super.setUp();
defineComponent(ConfigFactoryManager.class, MockConfigManager.class); defineComponent(ConfigFactoryManager.class, MockConfigManager.class);
defaultConfigManager = (DefaultConfigManager) lookup(ConfigManager.class, "default"); defaultConfigManager = (DefaultConfigManager) lookup(ConfigManager.class);
} }
@Test @Test
......
...@@ -3,6 +3,7 @@ package com.ctrip.framework.apollo.internals; ...@@ -3,6 +3,7 @@ package com.ctrip.framework.apollo.internals;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.io.Files; import com.google.common.io.Files;
import com.google.common.util.concurrent.SettableFuture;
import com.ctrip.framework.apollo.ConfigChangeListener; import com.ctrip.framework.apollo.ConfigChangeListener;
import com.ctrip.framework.apollo.core.utils.ClassLoaderUtil; import com.ctrip.framework.apollo.core.utils.ClassLoaderUtil;
...@@ -17,6 +18,7 @@ import org.mockito.ArgumentCaptor; ...@@ -17,6 +18,7 @@ import org.mockito.ArgumentCaptor;
import java.io.File; import java.io.File;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
...@@ -135,7 +137,14 @@ public class DefaultConfigTest { ...@@ -135,7 +137,14 @@ public class DefaultConfigTest {
DefaultConfig defaultConfig = DefaultConfig defaultConfig =
new DefaultConfig(someNamespace, configRepository); new DefaultConfig(someNamespace, configRepository);
ConfigChangeListener someListener = mock(ConfigChangeListener.class); final SettableFuture<ConfigChangeEvent> configChangeFuture = SettableFuture.create();
ConfigChangeListener someListener = new ConfigChangeListener() {
@Override
public void onChange(ConfigChangeEvent changeEvent) {
configChangeFuture.set(changeEvent);
}
};
defaultConfig.addChangeListener(someListener); defaultConfig.addChangeListener(someListener);
Properties newProperties = new Properties(); Properties newProperties = new Properties();
...@@ -146,14 +155,9 @@ public class DefaultConfigTest { ...@@ -146,14 +155,9 @@ public class DefaultConfigTest {
newProperties.putAll(ImmutableMap newProperties.putAll(ImmutableMap
.of(someKey, someKeyNewValue, anotherKey, anotherKeyNewValue, newKey, newValue)); .of(someKey, someKeyNewValue, anotherKey, anotherKeyNewValue, newKey, newValue));
final ArgumentCaptor<ConfigChangeEvent> captor =
ArgumentCaptor.forClass(ConfigChangeEvent.class);
defaultConfig.onRepositoryChange(someNamespace, newProperties); defaultConfig.onRepositoryChange(someNamespace, newProperties);
verify(someListener, times(1)).onChange(captor.capture()); ConfigChangeEvent changeEvent = configChangeFuture.get(500, TimeUnit.MILLISECONDS);
ConfigChangeEvent changeEvent = captor.getValue();
assertEquals(someNamespace, changeEvent.getNamespace()); assertEquals(someNamespace, changeEvent.getNamespace());
assertEquals(4, changeEvent.changedKeys().size()); assertEquals(4, changeEvent.changedKeys().size());
......
...@@ -92,7 +92,8 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase { ...@@ -92,7 +92,8 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase {
someProperties.setProperty(someKey, someValue); someProperties.setProperty(someKey, someValue);
createLocalCachePropertyFile(someProperties); createLocalCachePropertyFile(someProperties);
LocalFileConfigRepository localRepo = new LocalFileConfigRepository(someBaseDir, someNamespace); LocalFileConfigRepository localRepo = new LocalFileConfigRepository(someNamespace);
localRepo.initialize(someBaseDir);
Properties properties = localRepo.getConfig(); Properties properties = localRepo.getConfig();
assertEquals(someValue, properties.getProperty(someKey)); assertEquals(someValue, properties.getProperty(someKey));
...@@ -107,10 +108,11 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase { ...@@ -107,10 +108,11 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase {
Files.write(defaultKey + "=" + someValue, file, Charsets.UTF_8); Files.write(defaultKey + "=" + someValue, file, Charsets.UTF_8);
LocalFileConfigRepository localRepo = new LocalFileConfigRepository(someBaseDir, someNamespace); LocalFileConfigRepository localRepo = new LocalFileConfigRepository(someNamespace);
localRepo.initialize(someBaseDir);
//when fallback is set, it will try to sync from it //when fallback is set, it will try to sync from it
localRepo.setFallback(fallbackRepo); localRepo.setUpstreamRepository(fallbackRepo);
Properties properties = localRepo.getConfig(); Properties properties = localRepo.getConfig();
...@@ -121,9 +123,10 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase { ...@@ -121,9 +123,10 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase {
public void testLoadConfigWithNoLocalFile() throws Exception { public void testLoadConfigWithNoLocalFile() throws Exception {
LocalFileConfigRepository LocalFileConfigRepository
localFileConfigRepository = localFileConfigRepository =
new LocalFileConfigRepository(someBaseDir, someNamespace); new LocalFileConfigRepository(someNamespace);
localFileConfigRepository.initialize(someBaseDir);
localFileConfigRepository.setFallback(fallbackRepo); localFileConfigRepository.setUpstreamRepository(fallbackRepo);
Properties result = localFileConfigRepository.getConfig(); Properties result = localFileConfigRepository.getConfig();
...@@ -135,15 +138,17 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase { ...@@ -135,15 +138,17 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase {
@Test @Test
public void testLoadConfigWithNoLocalFileMultipleTimes() throws Exception { public void testLoadConfigWithNoLocalFileMultipleTimes() throws Exception {
LocalFileConfigRepository localRepo = LocalFileConfigRepository localRepo =
new LocalFileConfigRepository(someBaseDir, someNamespace); new LocalFileConfigRepository(someNamespace);
localRepo.initialize(someBaseDir);
localRepo.setFallback(fallbackRepo); localRepo.setUpstreamRepository(fallbackRepo);
Properties someProperties = localRepo.getConfig(); Properties someProperties = localRepo.getConfig();
LocalFileConfigRepository LocalFileConfigRepository
anotherLocalRepoWithNoFallback = anotherLocalRepoWithNoFallback =
new LocalFileConfigRepository(someBaseDir, someNamespace); new LocalFileConfigRepository(someNamespace);
anotherLocalRepoWithNoFallback.initialize(someBaseDir);
Properties anotherProperties = anotherLocalRepoWithNoFallback.getConfig(); Properties anotherProperties = anotherLocalRepoWithNoFallback.getConfig();
...@@ -158,8 +163,9 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase { ...@@ -158,8 +163,9 @@ public class LocalFileConfigRepositoryTest extends ComponentTestCase {
RepositoryChangeListener someListener = mock(RepositoryChangeListener.class); RepositoryChangeListener someListener = mock(RepositoryChangeListener.class);
LocalFileConfigRepository localFileConfigRepository = LocalFileConfigRepository localFileConfigRepository =
new LocalFileConfigRepository(someBaseDir, someNamespace); new LocalFileConfigRepository(someNamespace);
localFileConfigRepository.setFallback(fallbackRepo); localFileConfigRepository.initialize(someBaseDir);
localFileConfigRepository.setUpstreamRepository(fallbackRepo);
localFileConfigRepository.addChangeListener(someListener); localFileConfigRepository.addChangeListener(someListener);
localFileConfigRepository.getConfig(); localFileConfigRepository.getConfig();
......
...@@ -7,6 +7,7 @@ import com.google.common.util.concurrent.SettableFuture; ...@@ -7,6 +7,7 @@ import com.google.common.util.concurrent.SettableFuture;
import com.ctrip.framework.apollo.core.dto.ApolloConfig; import com.ctrip.framework.apollo.core.dto.ApolloConfig;
import com.ctrip.framework.apollo.core.dto.ApolloConfigNotification; import com.ctrip.framework.apollo.core.dto.ApolloConfigNotification;
import com.ctrip.framework.apollo.core.dto.ServiceDTO; import com.ctrip.framework.apollo.core.dto.ServiceDTO;
import com.ctrip.framework.apollo.exceptions.ApolloConfigException;
import com.ctrip.framework.apollo.util.ConfigUtil; import com.ctrip.framework.apollo.util.ConfigUtil;
import com.ctrip.framework.apollo.util.http.HttpRequest; import com.ctrip.framework.apollo.util.http.HttpRequest;
import com.ctrip.framework.apollo.util.http.HttpResponse; import com.ctrip.framework.apollo.util.http.HttpResponse;
...@@ -85,7 +86,7 @@ public class RemoteConfigRepositoryTest extends ComponentTestCase { ...@@ -85,7 +86,7 @@ public class RemoteConfigRepositoryTest extends ComponentTestCase {
remoteConfigRepository.stopLongPollingRefresh(); remoteConfigRepository.stopLongPollingRefresh();
} }
@Test(expected = RuntimeException.class) @Test(expected = ApolloConfigException.class)
public void testGetRemoteConfigWithServerError() throws Exception { public void testGetRemoteConfigWithServerError() throws Exception {
when(someResponse.getStatusCode()).thenReturn(500); when(someResponse.getStatusCode()).thenReturn(500);
......
package com.ctrip.framework.apollo.internals; package com.ctrip.framework.apollo.internals;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.SettableFuture;
import com.ctrip.framework.apollo.Config; import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigChangeListener; import com.ctrip.framework.apollo.ConfigChangeListener;
...@@ -16,6 +17,7 @@ import org.mockito.Mock; ...@@ -16,6 +17,7 @@ import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.runners.MockitoJUnitRunner;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
...@@ -79,18 +81,20 @@ public class SimpleConfigTest { ...@@ -79,18 +81,20 @@ public class SimpleConfigTest {
when(configRepository.getConfig()).thenReturn(someProperties); when(configRepository.getConfig()).thenReturn(someProperties);
ConfigChangeListener someListener = mock(ConfigChangeListener.class); final SettableFuture<ConfigChangeEvent> configChangeFuture = SettableFuture.create();
ConfigChangeListener someListener = new ConfigChangeListener() {
@Override
public void onChange(ConfigChangeEvent changeEvent) {
configChangeFuture.set(changeEvent);
}
};
SimpleConfig config = new SimpleConfig(someNamespace, configRepository); SimpleConfig config = new SimpleConfig(someNamespace, configRepository);
config.addChangeListener(someListener); config.addChangeListener(someListener);
config.onRepositoryChange(someNamespace, anotherProperties); config.onRepositoryChange(someNamespace, anotherProperties);
ArgumentCaptor<ConfigChangeEvent> captor = ArgumentCaptor.forClass(ConfigChangeEvent.class); ConfigChangeEvent changeEvent = configChangeFuture.get(500, TimeUnit.MILLISECONDS);
verify(someListener, times(1)).onChange(captor.capture());
ConfigChangeEvent changeEvent = captor.getValue();
assertEquals(someNamespace, changeEvent.getNamespace()); assertEquals(someNamespace, changeEvent.getNamespace());
assertEquals(3, changeEvent.changedKeys().size()); assertEquals(3, changeEvent.changedKeys().size());
......
...@@ -22,7 +22,7 @@ public class DefaultConfigFactoryManagerTest extends ComponentTestCase { ...@@ -22,7 +22,7 @@ public class DefaultConfigFactoryManagerTest extends ComponentTestCase {
super.setUp(); super.setUp();
defineComponent(ConfigRegistry.class, MockConfigRegistry.class); defineComponent(ConfigRegistry.class, MockConfigRegistry.class);
defaultConfigFactoryManager = defaultConfigFactoryManager =
(DefaultConfigFactoryManager) lookup(ConfigFactoryManager.class, "default"); (DefaultConfigFactoryManager) lookup(ConfigFactoryManager.class);
} }
@Test @Test
...@@ -60,7 +60,7 @@ public class DefaultConfigFactoryManagerTest extends ComponentTestCase { ...@@ -60,7 +60,7 @@ public class DefaultConfigFactoryManagerTest extends ComponentTestCase {
@Test @Test
public void testGetFactoryFromDefault() throws Exception { public void testGetFactoryFromDefault() throws Exception {
String someNamespace = "someName"; String someNamespace = "someName";
defineComponent(ConfigFactory.class, "default", AnotherConfigFactory.class); defineComponent(ConfigFactory.class, AnotherConfigFactory.class);
ConfigFactory result = defaultConfigFactoryManager.getFactory(someNamespace); ConfigFactory result = defaultConfigFactoryManager.getFactory(someNamespace);
......
...@@ -28,7 +28,7 @@ public class DefaultConfigFactoryTest extends ComponentTestCase { ...@@ -28,7 +28,7 @@ public class DefaultConfigFactoryTest extends ComponentTestCase {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); super.setUp();
defaultConfigFactory = spy((DefaultConfigFactory) lookup(ConfigFactory.class, "default")); defaultConfigFactory = spy((DefaultConfigFactory) lookup(ConfigFactory.class));
} }
@Test @Test
......
...@@ -19,7 +19,7 @@ public class DefaultConfigRegistryTest extends ComponentTestCase { ...@@ -19,7 +19,7 @@ public class DefaultConfigRegistryTest extends ComponentTestCase {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); super.setUp();
defaultConfigRegistry = (DefaultConfigRegistry) lookup(ConfigRegistry.class, "default"); defaultConfigRegistry = (DefaultConfigRegistry) lookup(ConfigRegistry.class);
} }
@Test @Test
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ctrip.framework.apollo</groupId> <groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId> <artifactId>apollo</artifactId>
<version>0.0.1</version> <version>0.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ctrip.framework.apollo</groupId> <groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId> <artifactId>apollo</artifactId>
<version>0.0.1</version> <version>0.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
...@@ -67,7 +67,7 @@ public class ConfigController { ...@@ -67,7 +67,7 @@ public class ConfigController {
} }
//if namespace is not 'application', should check if it's a public configuration //if namespace is not 'application', should check if it's a public configuration
if (!Objects.equals(ConfigConsts.NAMESPACE_DEFAULT, namespace)) { if (!Objects.equals(ConfigConsts.NAMESPACE_APPLICATION, namespace)) {
Release publicRelease = this.findPublicConfig(appId, clusterName, namespace, dataCenter); Release publicRelease = this.findPublicConfig(appId, clusterName, namespace, dataCenter);
if (!Objects.isNull(publicRelease)) { if (!Objects.isNull(publicRelease)) {
releases.add(publicRelease); releases.add(publicRelease);
......
...@@ -64,14 +64,14 @@ public class NotificationController implements ReleaseMessageListener { ...@@ -64,14 +64,14 @@ public class NotificationController implements ReleaseMessageListener {
public DeferredResult<ResponseEntity<ApolloConfigNotification>> pollNotification( public DeferredResult<ResponseEntity<ApolloConfigNotification>> pollNotification(
@RequestParam(value = "appId") String appId, @RequestParam(value = "appId") String appId,
@RequestParam(value = "cluster") String cluster, @RequestParam(value = "cluster") String cluster,
@RequestParam(value = "namespace", defaultValue = ConfigConsts.NAMESPACE_DEFAULT) String namespace, @RequestParam(value = "namespace", defaultValue = ConfigConsts.NAMESPACE_APPLICATION) String namespace,
@RequestParam(value = "dataCenter", required = false) String dataCenter, @RequestParam(value = "dataCenter", required = false) String dataCenter,
@RequestParam(value = "notificationId", defaultValue = "-1") long notificationId, @RequestParam(value = "notificationId", defaultValue = "-1") long notificationId,
@RequestParam(value = "ip", required = false) String clientIp) { @RequestParam(value = "ip", required = false) String clientIp) {
Set<String> watchedKeys = assembleWatchKeys(appId, cluster, namespace, dataCenter); Set<String> watchedKeys = assembleWatchKeys(appId, cluster, namespace, dataCenter);
//Listen on more namespaces, since it's not the default namespace //Listen on more namespaces, since it's not the default namespace
if (!Objects.equals(ConfigConsts.NAMESPACE_DEFAULT, namespace)) { if (!Objects.equals(ConfigConsts.NAMESPACE_APPLICATION, namespace)) {
watchedKeys.addAll(this.findPublicConfigWatchKey(appId, cluster, namespace, dataCenter)); watchedKeys.addAll(this.findPublicConfigWatchKey(appId, cluster, namespace, dataCenter));
} }
......
...@@ -64,7 +64,7 @@ public class ConfigControllerTest { ...@@ -64,7 +64,7 @@ public class ConfigControllerTest {
someAppId = "1"; someAppId = "1";
someClusterName = "someClusterName"; someClusterName = "someClusterName";
defaultClusterName = ConfigConsts.CLUSTER_NAME_DEFAULT; defaultClusterName = ConfigConsts.CLUSTER_NAME_DEFAULT;
defaultNamespaceName = ConfigConsts.NAMESPACE_DEFAULT; defaultNamespaceName = ConfigConsts.NAMESPACE_APPLICATION;
somePublicNamespaceName = "somePublicNamespace"; somePublicNamespaceName = "somePublicNamespace";
someDataCenter = "someDC"; someDataCenter = "someDC";
someClientIp = "someClientIp"; someClientIp = "someClientIp";
......
...@@ -64,7 +64,7 @@ public class NotificationControllerTest { ...@@ -64,7 +64,7 @@ public class NotificationControllerTest {
someAppId = "someAppId"; someAppId = "someAppId";
someCluster = "someCluster"; someCluster = "someCluster";
defaultCluster = ConfigConsts.CLUSTER_NAME_DEFAULT; defaultCluster = ConfigConsts.CLUSTER_NAME_DEFAULT;
defaultNamespace = ConfigConsts.NAMESPACE_DEFAULT; defaultNamespace = ConfigConsts.NAMESPACE_APPLICATION;
somePublicNamespace = "somePublicNamespace"; somePublicNamespace = "somePublicNamespace";
someDataCenter = "someDC"; someDataCenter = "someDC";
someNotificationId = 1; someNotificationId = 1;
......
...@@ -39,7 +39,7 @@ public class ConfigControllerIntegrationTest extends AbstractBaseIntegrationTest ...@@ -39,7 +39,7 @@ public class ConfigControllerIntegrationTest extends AbstractBaseIntegrationTest
public void testQueryConfigWithDefaultClusterAndDefaultNamespaceOK() throws Exception { public void testQueryConfigWithDefaultClusterAndDefaultNamespaceOK() throws Exception {
ResponseEntity<ApolloConfig> response = restTemplate ResponseEntity<ApolloConfig> response = restTemplate
.getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}", ApolloConfig.class, .getForEntity("{baseurl}/configs/{appId}/{clusterName}/{namespace}", ApolloConfig.class,
getHostUrl(), someAppId, ConfigConsts.CLUSTER_NAME_DEFAULT, ConfigConsts.NAMESPACE_DEFAULT); getHostUrl(), someAppId, ConfigConsts.CLUSTER_NAME_DEFAULT, ConfigConsts.NAMESPACE_APPLICATION);
ApolloConfig result = response.getBody(); ApolloConfig result = response.getBody();
assertEquals(HttpStatus.OK, response.getStatusCode()); assertEquals(HttpStatus.OK, response.getStatusCode());
......
...@@ -41,7 +41,7 @@ public class NotificationControllerIntegrationTest extends AbstractBaseIntegrati ...@@ -41,7 +41,7 @@ public class NotificationControllerIntegrationTest extends AbstractBaseIntegrati
public void setUp() throws Exception { public void setUp() throws Exception {
someAppId = "someAppId"; someAppId = "someAppId";
someCluster = ConfigConsts.CLUSTER_NAME_DEFAULT; someCluster = ConfigConsts.CLUSTER_NAME_DEFAULT;
defaultNamespace = ConfigConsts.NAMESPACE_DEFAULT; defaultNamespace = ConfigConsts.NAMESPACE_APPLICATION;
somePublicNamespace = "somePublicNamespace"; somePublicNamespace = "somePublicNamespace";
executorService = Executors.newSingleThreadExecutor(); executorService = Executors.newSingleThreadExecutor();
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ctrip.framework.apollo</groupId> <groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId> <artifactId>apollo</artifactId>
<version>0.0.1</version> <version>0.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
package com.ctrip.framework.apollo.core; package com.ctrip.framework.apollo.core;
public interface ConfigConsts { public interface ConfigConsts {
String NAMESPACE_DEFAULT = "application"; String NAMESPACE_APPLICATION = "application";
String CLUSTER_NAME_DEFAULT = "default"; String CLUSTER_NAME_DEFAULT = "default";
String CLUSTER_NAMESPACE_SEPARATOR = "+"; String CLUSTER_NAMESPACE_SEPARATOR = "+";
} }
...@@ -17,7 +17,7 @@ public class MetaDomainConsts { ...@@ -17,7 +17,7 @@ public class MetaDomainConsts {
private static Map<Env, Object> domains = new HashMap<>(); private static Map<Env, Object> domains = new HashMap<>();
public static final String DEFAULT_META_URL = "http://localhost:8080"; public static final String DEFAULT_META_URL = "http://config.local";
static { static {
Properties prop = new Properties(); Properties prop = new Properties();
......
...@@ -17,6 +17,7 @@ public final class EnvUtils { ...@@ -17,6 +17,7 @@ public final class EnvUtils {
case "UAT": case "UAT":
return Env.UAT; return Env.UAT;
case "PRO": case "PRO":
case "PROD": //just in case
return Env.PRO; return Env.PRO;
case "DEV": case "DEV":
return Env.DEV; return Env.DEV;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<parent> <parent>
<artifactId>apollo</artifactId> <artifactId>apollo</artifactId>
<groupId>com.ctrip.framework.apollo</groupId> <groupId>com.ctrip.framework.apollo</groupId>
<version>0.0.1</version> <version>0.0.2-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>apollo-demo</artifactId> <artifactId>apollo-demo</artifactId>
......
...@@ -21,6 +21,18 @@ public class ApolloConfigDemo implements ConfigChangeListener { ...@@ -21,6 +21,18 @@ public class ApolloConfigDemo implements ConfigChangeListener {
public ApolloConfigDemo() { public ApolloConfigDemo() {
config = ConfigService.getAppConfig(); config = ConfigService.getAppConfig();
config.addChangeListener(this); config.addChangeListener(this);
config.addChangeListener(new ConfigChangeListener() {
@Override
public void onChange(ConfigChangeEvent changeEvent) {
logger.info("Changes2 for namespace {}", changeEvent.getNamespace());
for (String key : changeEvent.changedKeys()) {
ConfigChange change = changeEvent.getChange(key);
logger.info("Change2 - key: {}, oldValue: {}, newValue: {}, changeType: {}",
change.getPropertyName(), change.getOldValue(), change.getNewValue(),
change.getChangeType());
}
}
});
} }
private String getConfig(String key) { private String getConfig(String key) {
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ctrip.framework.apollo</groupId> <groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId> <artifactId>apollo</artifactId>
<version>0.0.1</version> <version>0.0.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
...@@ -88,7 +88,7 @@ public class ConfigServiceTest { ...@@ -88,7 +88,7 @@ public class ConfigServiceTest {
List<ItemDTO> sourceItems = Arrays.asList(sourceItem1); List<ItemDTO> sourceItems = Arrays.asList(sourceItem1);
String appId = "6666", env = "LOCAL", clusterName = ConfigConsts.CLUSTER_NAME_DEFAULT, String appId = "6666", env = "LOCAL", clusterName = ConfigConsts.CLUSTER_NAME_DEFAULT,
namespaceName = ConfigConsts.NAMESPACE_DEFAULT; namespaceName = ConfigConsts.NAMESPACE_APPLICATION;
List<NamespaceIdentifer> namespaceIdentifers = generateNamespaceIdentifer(appId, env, clusterName, namespaceName); List<NamespaceIdentifer> namespaceIdentifers = generateNamespaceIdentifer(appId, env, clusterName, namespaceName);
NamespaceDTO namespaceDTO = generateNamespaceDTO(appId, clusterName, namespaceName); NamespaceDTO namespaceDTO = generateNamespaceDTO(appId, clusterName, namespaceName);
...@@ -125,7 +125,7 @@ public class ConfigServiceTest { ...@@ -125,7 +125,7 @@ public class ConfigServiceTest {
List<ItemDTO> targetItems = Arrays.asList(targetItem1, targetItem2, targetItem3); List<ItemDTO> targetItems = Arrays.asList(targetItem1, targetItem2, targetItem3);
String appId = "6666", env = "LOCAL", clusterName = ConfigConsts.CLUSTER_NAME_DEFAULT, String appId = "6666", env = "LOCAL", clusterName = ConfigConsts.CLUSTER_NAME_DEFAULT,
namespaceName = ConfigConsts.NAMESPACE_DEFAULT; namespaceName = ConfigConsts.NAMESPACE_APPLICATION;
List<NamespaceIdentifer> namespaceIdentifers = generateNamespaceIdentifer(appId, env, clusterName, namespaceName); List<NamespaceIdentifer> namespaceIdentifers = generateNamespaceIdentifer(appId, env, clusterName, namespaceName);
NamespaceDTO namespaceDTO = generateNamespaceDTO(appId, clusterName, namespaceName); NamespaceDTO namespaceDTO = generateNamespaceDTO(appId, clusterName, namespaceName);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.ctrip.framework.apollo</groupId> <groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo</artifactId> <artifactId>apollo</artifactId>
<version>0.0.1</version> <version>0.0.2-SNAPSHOT</version>
<name>Apollo</name> <name>Apollo</name>
<packaging>pom</packaging> <packaging>pom</packaging>
<description>Ctrip Configuration Center</description> <description>Ctrip Configuration Center</description>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment