提交 d47d0f83 编写于 作者: J Jason Song

refactor according to code review comments

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