Pārlūkot izejas kodu

refactor according to code review comments

Jason Song 8 gadi atpakaļ
vecāks
revīzija
d47d0f83c6
50 mainītis faili ar 346 papildinājumiem un 218 dzēšanām
  1. 1 1
      apollo-adminservice/pom.xml
  2. 1 1
      apollo-assembly/pom.xml
  3. 1 1
      apollo-biz/pom.xml
  4. 2 2
      apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AppNamespaceService.java
  5. 1 1
      apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/NamespaceService.java
  6. 1 1
      apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/repository/AppNamespaceRepositoryTest.java
  7. 1 1
      apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/service/AdminServiceTest.java
  8. 1 1
      apollo-buildtools/pom.xml
  9. 9 1
      apollo-client/README.md
  10. 1 1
      apollo-client/pom.xml
  11. 11 8
      apollo-client/src/main/java/com/ctrip/framework/apollo/ConfigService.java
  12. 14 0
      apollo-client/src/main/java/com/ctrip/framework/apollo/exceptions/ApolloConfigException.java
  13. 32 9
      apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfig.java
  14. 2 2
      apollo-client/src/main/java/com/ctrip/framework/apollo/internals/ConfigRepository.java
  15. 4 6
      apollo-client/src/main/java/com/ctrip/framework/apollo/internals/ConfigServiceLocator.java
  16. 1 1
      apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultConfigManager.java
  17. 57 23
      apollo-client/src/main/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepository.java
  18. 57 44
      apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RemoteConfigRepository.java
  19. 3 42
      apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigFactory.java
  20. 2 2
      apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryManager.java
  21. 1 1
      apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigRegistry.java
  22. 62 17
      apollo-client/src/main/java/com/ctrip/framework/apollo/util/ConfigUtil.java
  23. 5 4
      apollo-client/src/main/java/com/ctrip/framework/apollo/util/http/HttpUtil.java
  24. 1 1
      apollo-client/src/test/java/com/ctrip/framework/apollo/ConfigServiceTest.java
  25. 1 1
      apollo-client/src/test/java/com/ctrip/framework/apollo/integration/ConfigIntegrationTest.java
  26. 1 1
      apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigManagerTest.java
  27. 11 7
      apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigTest.java
  28. 16 10
      apollo-client/src/test/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepositoryTest.java
  29. 2 1
      apollo-client/src/test/java/com/ctrip/framework/apollo/internals/RemoteConfigRepositoryTest.java
  30. 10 6
      apollo-client/src/test/java/com/ctrip/framework/apollo/internals/SimpleConfigTest.java
  31. 2 2
      apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryManagerTest.java
  32. 1 1
      apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryTest.java
  33. 1 1
      apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigRegistryTest.java
  34. 1 1
      apollo-common/pom.xml
  35. 1 1
      apollo-configservice/pom.xml
  36. 1 1
      apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/controller/ConfigController.java
  37. 2 2
      apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/controller/NotificationController.java
  38. 1 1
      apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/controller/ConfigControllerTest.java
  39. 1 1
      apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/controller/NotificationControllerTest.java
  40. 1 1
      apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/integration/ConfigControllerIntegrationTest.java
  41. 1 1
      apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/integration/NotificationControllerIntegrationTest.java
  42. 1 1
      apollo-core/pom.xml
  43. 1 1
      apollo-core/src/main/java/com/ctrip/framework/apollo/core/ConfigConsts.java
  44. 1 1
      apollo-core/src/main/java/com/ctrip/framework/apollo/core/MetaDomainConsts.java
  45. 1 0
      apollo-core/src/main/java/com/ctrip/framework/apollo/core/enums/EnvUtils.java
  46. 1 1
      apollo-demo/pom.xml
  47. 12 0
      apollo-demo/src/main/java/ApolloConfigDemo.java
  48. 1 1
      apollo-portal/pom.xml
  49. 2 2
      apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/ConfigServiceTest.java
  50. 1 1
      pom.xml

+ 1 - 1
apollo-adminservice/pom.xml

@@ -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>

+ 1 - 1
apollo-assembly/pom.xml

@@ -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>

+ 1 - 1
apollo-biz/pom.xml

@@ -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>

+ 2 - 2
apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AppNamespaceService.java

@@ -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){

+ 1 - 1
apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/NamespaceService.java

@@ -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);

+ 1 - 1
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/repository/AppNamespaceRepositoryTest.java

@@ -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());
   }
 

+ 1 - 1
apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/service/AdminServiceTest.java

@@ -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());

+ 1 - 1
apollo-buildtools/pom.xml

@@ -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>

+ 9 - 1
apollo-client/README.md

@@ -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

+ 1 - 1
apollo-client/pom.xml

@@ -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>

+ 11 - 8
apollo-client/src/main/java/com/ctrip/framework/apollo/ConfigService.java

@@ -1,6 +1,7 @@
 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);
   }
 
   /**

+ 14 - 0
apollo-client/src/main/java/com/ctrip/framework/apollo/exceptions/ApolloConfigException.java

@@ -0,0 +1,14 @@
+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);
+  }
+}

+ 32 - 9
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfig.java

@@ -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();
     }

+ 2 - 2
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/ConfigRepository.java

@@ -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.

+ 4 - 6
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/ConfigServiceLocator.java

@@ -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);
   }
 

+ 1 - 1
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultConfigManager.java

@@ -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;

+ 57 - 23
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepository.java

@@ -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));

+ 57 - 44
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RemoteConfigRepository.java

@@ -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;

+ 3 - 42
apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigFactory.java

@@ -1,59 +1,20 @@
 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;
   }
 

+ 2 - 2
apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryManager.java

@@ -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);

+ 1 - 1
apollo-client/src/main/java/com/ctrip/framework/apollo/spi/DefaultConfigRegistry.java

@@ -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();
 

+ 62 - 17
apollo-client/src/main/java/com/ctrip/framework/apollo/util/ConfigUtil.java

@@ -1,6 +1,7 @@
 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 - 4
apollo-client/src/main/java/com/ctrip/framework/apollo/util/http/HttpUtil.java

@@ -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));
   }
 

+ 1 - 1
apollo-client/src/test/java/com/ctrip/framework/apollo/ConfigServiceTest.java

@@ -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));
   }
 

+ 1 - 1
apollo-client/src/test/java/com/ctrip/framework/apollo/integration/ConfigIntegrationTest.java

@@ -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();

+ 1 - 1
apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigManagerTest.java

@@ -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

+ 11 - 7
apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigTest.java

@@ -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());

+ 16 - 10
apollo-client/src/test/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepositoryTest.java

@@ -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();

+ 2 - 1
apollo-client/src/test/java/com/ctrip/framework/apollo/internals/RemoteConfigRepositoryTest.java

@@ -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);

+ 10 - 6
apollo-client/src/test/java/com/ctrip/framework/apollo/internals/SimpleConfigTest.java

@@ -1,6 +1,7 @@
 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());

+ 2 - 2
apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryManagerTest.java

@@ -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);
 

+ 1 - 1
apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigFactoryTest.java

@@ -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

+ 1 - 1
apollo-client/src/test/java/com/ctrip/framework/apollo/spi/DefaultConfigRegistryTest.java

@@ -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

+ 1 - 1
apollo-common/pom.xml

@@ -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>

+ 1 - 1
apollo-configservice/pom.xml

@@ -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>

+ 1 - 1
apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/controller/ConfigController.java

@@ -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);

+ 2 - 2
apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/controller/NotificationController.java

@@ -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));
     }
 

+ 1 - 1
apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/controller/ConfigControllerTest.java

@@ -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";

+ 1 - 1
apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/controller/NotificationControllerTest.java

@@ -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;

+ 1 - 1
apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/integration/ConfigControllerIntegrationTest.java

@@ -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());

+ 1 - 1
apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/integration/NotificationControllerIntegrationTest.java

@@ -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();
   }

+ 1 - 1
apollo-core/pom.xml

@@ -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>

+ 1 - 1
apollo-core/src/main/java/com/ctrip/framework/apollo/core/ConfigConsts.java

@@ -1,7 +1,7 @@
 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 = "+";
 }

+ 1 - 1
apollo-core/src/main/java/com/ctrip/framework/apollo/core/MetaDomainConsts.java

@@ -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();

+ 1 - 0
apollo-core/src/main/java/com/ctrip/framework/apollo/core/enums/EnvUtils.java

@@ -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;

+ 1 - 1
apollo-demo/pom.xml

@@ -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>

+ 12 - 0
apollo-demo/src/main/java/ApolloConfigDemo.java

@@ -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) {

+ 1 - 1
apollo-portal/pom.xml

@@ -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>

+ 2 - 2
apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/ConfigServiceTest.java

@@ -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);
 

+ 1 - 1
pom.xml

@@ -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>