diff --git a/apollo-biz/src/main/java/com/ctrip/apollo/biz/service/ConfigService.java b/apollo-biz/src/main/java/com/ctrip/apollo/biz/service/ConfigService.java
index ea283865855d7121cb252cfb3965d8766ef6e312..da373f6758b8b0d4d0627a72091db0435d2bce51 100644
--- a/apollo-biz/src/main/java/com/ctrip/apollo/biz/service/ConfigService.java
+++ b/apollo-biz/src/main/java/com/ctrip/apollo/biz/service/ConfigService.java
@@ -1,5 +1,6 @@
package com.ctrip.apollo.biz.service;
+import com.ctrip.apollo.biz.entity.Version;
import com.ctrip.apollo.core.model.ApolloConfig;
/**
@@ -15,4 +16,20 @@ public interface ConfigService {
* @return
*/
ApolloConfig loadConfig(long appId, String clusterName, String versionName);
+
+ /**
+ * Load Version by appId and versionName from database
+ * @param appId
+ * @param versionName
+ * @return
+ */
+ Version loadVersionByAppIdAndVersionName(long appId, String versionName);
+
+ /**
+ * Load Config by version and clusterName from database
+ * @param version
+ * @param clusterName
+ * @return
+ */
+ ApolloConfig loadConfigByVersionAndClusterName(Version version, String clusterName);
}
diff --git a/apollo-biz/src/main/java/com/ctrip/apollo/biz/service/impl/ConfigServiceImpl.java b/apollo-biz/src/main/java/com/ctrip/apollo/biz/service/impl/ConfigServiceImpl.java
index 5a20af9128da703cd3d1a72c5ec47be4e097ed10..a747b5c8717181acf66c4cd08089d90b47d73088 100644
--- a/apollo-biz/src/main/java/com/ctrip/apollo/biz/service/impl/ConfigServiceImpl.java
+++ b/apollo-biz/src/main/java/com/ctrip/apollo/biz/service/impl/ConfigServiceImpl.java
@@ -32,10 +32,21 @@ public class ConfigServiceImpl implements ConfigService {
@Override
public ApolloConfig loadConfig(long appId, String clusterName, String versionName) {
- Version version = versionRepository.findByAppIdAndName(appId, versionName);
+ Version version = loadVersionByAppIdAndVersionName(appId, versionName);
if (version == null) {
return null;
}
+
+ return loadConfigByVersionAndClusterName(version, clusterName);
+ }
+
+ @Override
+ public Version loadVersionByAppIdAndVersionName(long appId, String versionName) {
+ return versionRepository.findByAppIdAndName(appId, versionName);
+ }
+
+ @Override
+ public ApolloConfig loadConfigByVersionAndClusterName(Version version, String clusterName) {
ReleaseSnapShot releaseSnapShot =
releaseSnapShotRepository.findByReleaseIdAndClusterName(version.getReleaseId(), clusterName);
if (releaseSnapShot == null) {
diff --git a/apollo-biz/src/main/resources/import.sql b/apollo-biz/src/main/resources/import.sql
index dd4b29badbc8e0fc93a601cc49c57bb353e64b03..14d70fc3648c8a6a407507d36681d223ef17e3a1 100644
--- a/apollo-biz/src/main/resources/import.sql
+++ b/apollo-biz/src/main/resources/import.sql
@@ -4,5 +4,5 @@ INSERT INTO Cluster (AppId, IsDeleted, Name) VALUES (101, 0, 'default');
INSERT INTO Version (AppId, IsDeleted, Name, ReleaseId) VALUES (101, 0, '1.0', 1);
INSERT INTO Version (AppId, IsDeleted, Name, ReleaseId) VALUES (102, 0, '1.0', 2);
-INSERT INTO RELEASESNAPSHOT (ClusterName, IsDeleted, ReleaseId, Configurations) VALUES ('default', 0, 1, '{"apollo.foo":"bar"}');
-INSERT INTO RELEASESNAPSHOT (ClusterName, IsDeleted, ReleaseId, Configurations) VALUES ('default', 0, 2, '{"apollo.bar":"foo"}');
+INSERT INTO RELEASESNAPSHOT (ClusterName, IsDeleted, ReleaseId, Configurations) VALUES ('default', 0, 1, '{"apollo.foo":"bar", "apollo.bar":"foo"}');
+INSERT INTO RELEASESNAPSHOT (ClusterName, IsDeleted, ReleaseId, Configurations) VALUES ('default', 0, 2, '{"demo.foo":"demo1", "demo.bar":"demo2"}');
diff --git a/apollo-biz/src/test/java/com/ctrip/apollo/biz/service/impl/ConfigServiceImplTest.java b/apollo-biz/src/test/java/com/ctrip/apollo/biz/service/impl/ConfigServiceImplTest.java
index f01ea31e446066545503e8a6f171b184f07b3193..281b7f8eb0ad0455668a047dcdfeb58d7a5dd488 100644
--- a/apollo-biz/src/test/java/com/ctrip/apollo/biz/service/impl/ConfigServiceImplTest.java
+++ b/apollo-biz/src/test/java/com/ctrip/apollo/biz/service/impl/ConfigServiceImplTest.java
@@ -19,6 +19,7 @@ import java.io.IOException;
import java.util.Map;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.*;
@@ -66,7 +67,38 @@ public class ConfigServiceImplTest {
assertEquals(someVersionName, result.getVersion());
assertEquals(someReleaseId, result.getReleaseId());
assertEquals(someMap, result.getConfigurations());
+ }
+
+ @Test
+ public void testLoadConfigWithVersionNotFound() throws Exception {
+ long someAppId = 1;
+ String someClusterName = "someClusterName";
+ String someVersionName = "someVersionName";
+
+ when(versionRepository.findByAppIdAndName(someAppId, someVersionName)).thenReturn(null);
+
+ ApolloConfig result = configService.loadConfig(someAppId, someClusterName, someVersionName);
+
+ assertNull(result);
+ verify(versionRepository, times(1)).findByAppIdAndName(someAppId, someVersionName);
+ }
+
+ @Test
+ public void testLoadConfigWithConfigNotFound() throws Exception {
+ long someAppId = 1;
+ String someClusterName = "someClusterName";
+ String someVersionName = "someVersionName";
+ long someReleaseId = 1;
+ Version someVersion = assembleVersion(someAppId, someVersionName, someReleaseId);
+
+ when(versionRepository.findByAppIdAndName(someAppId, someVersionName)).thenReturn(someVersion);
+ when(releaseSnapShotRepository.findByReleaseIdAndClusterName(someReleaseId, someClusterName)).thenReturn(null);
+
+ ApolloConfig result = configService.loadConfig(someAppId, someClusterName, someVersionName);
+ assertNull(result);
+ verify(versionRepository, times(1)).findByAppIdAndName(someAppId, someVersionName);
+ verify(releaseSnapShotRepository, times(1)).findByReleaseIdAndClusterName(someReleaseId, someClusterName);
}
private Version assembleVersion(long appId, String versionName, long releaseId) {
diff --git a/apollo-client/pom.xml b/apollo-client/pom.xml
index 86d3b43e86eafd731b4e23e01ca581157f03cf6c..5a2f3c4f3ea3216f3739e95b9a4e1eed4d30fc42 100644
--- a/apollo-client/pom.xml
+++ b/apollo-client/pom.xml
@@ -29,6 +29,10 @@
org.springframework
spring-web
+
+ org.springframework.cloud
+ spring-cloud-context
+
com.google.guava
diff --git a/apollo-client/src/main/java/com/ctrip/apollo/client/ApolloConfigManager.java b/apollo-client/src/main/java/com/ctrip/apollo/client/ApolloConfigManager.java
index 20ed7e555927fbd783cfc3e6205d2971ed76bc66..3d7338fa7085017fb6aaa0e48902727ca897b19d 100644
--- a/apollo-client/src/main/java/com/ctrip/apollo/client/ApolloConfigManager.java
+++ b/apollo-client/src/main/java/com/ctrip/apollo/client/ApolloConfigManager.java
@@ -4,19 +4,23 @@ import com.ctrip.apollo.client.loader.ConfigLoader;
import com.ctrip.apollo.client.loader.ConfigLoaderFactory;
import com.ctrip.apollo.client.util.ConfigUtil;
import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
+import org.springframework.cloud.context.scope.refresh.RefreshScope;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.MutablePropertySources;
/**
- * Client side config
+ * Client side config manager
*
* @author Jason Song(song_s@ctrip.com)
*/
@@ -48,9 +52,27 @@ public class ApolloConfigManager implements BeanDefinitionRegistryPostProcessor,
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
+ registerDependentBeans(registry);
preparePropertySource();
}
+ /**
+ * Register beans needed for Apollo Config Client
+ *
+ * - RefreshScope: used to refresh beans when configurations changes
+ *
+ *
+ * - PropertySourcesPlaceholderConfigurer: used to support placeholder configuration injection
+ *
+ * @param registry
+ */
+ private void registerDependentBeans(BeanDefinitionRegistry registry) {
+ BeanDefinition refreshScope = BeanDefinitionBuilder.genericBeanDefinition(RefreshScope.class).getBeanDefinition();
+ registry.registerBeanDefinition("refreshScope", refreshScope);
+ BeanDefinition propertySourcesPlaceholderConfigurer = BeanDefinitionBuilder.genericBeanDefinition(PropertySourcesPlaceholderConfigurer.class).getBeanDefinition();
+ registry.registerBeanDefinition("propertySourcesPlaceholderConfigurer", propertySourcesPlaceholderConfigurer);
+ }
+
/**
* This is executed after postProcessBeanDefinitionRegistry
*/
@@ -58,11 +80,20 @@ public class ApolloConfigManager implements BeanDefinitionRegistryPostProcessor,
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
+ /**
+ * Make sure this bean is called before other beans
+ * @return
+ */
@Override
public int getOrder() {
- return Ordered.HIGHEST_PRECEDENCE + 1;
+ return Ordered.HIGHEST_PRECEDENCE;
}
+ /**
+ * Prepare property sources
+ * First try to load from remote
+ * If loading from remote failed, then fall back to local cached properties
+ */
void preparePropertySource() {
MutablePropertySources currentPropertySources = applicationContext.getEnvironment().getPropertySources();
if (currentPropertySources.contains(APOLLO_PROPERTY_SOURCE_NAME)) {
diff --git a/apollo-client/src/main/java/com/ctrip/apollo/client/loader/ConfigLoaderFactory.java b/apollo-client/src/main/java/com/ctrip/apollo/client/loader/ConfigLoaderFactory.java
index ee5ecf6dd5e2b02ccd977a20eaf12a67f16909df..54de60121e47d9829ace01fad2861d62571034d7 100644
--- a/apollo-client/src/main/java/com/ctrip/apollo/client/loader/ConfigLoaderFactory.java
+++ b/apollo-client/src/main/java/com/ctrip/apollo/client/loader/ConfigLoaderFactory.java
@@ -1,6 +1,5 @@
package com.ctrip.apollo.client.loader;
-import com.ctrip.apollo.client.loader.impl.MockConfigLoader;
import com.ctrip.apollo.client.loader.impl.RemoteConfigLoader;
/**
@@ -16,10 +15,6 @@ public class ConfigLoaderFactory {
return configLoaderFactory;
}
- public ConfigLoader getMockConfigLoader() {
- return new MockConfigLoader();
- }
-
public ConfigLoader getRemoteConfigLoader() {
return new RemoteConfigLoader();
}
diff --git a/apollo-client/src/main/java/com/ctrip/apollo/client/loader/impl/MockConfigLoader.java b/apollo-client/src/main/java/com/ctrip/apollo/client/loader/impl/MockConfigLoader.java
deleted file mode 100644
index c76631ee4fb0c323426c5da4e39e91fa4851550b..0000000000000000000000000000000000000000
--- a/apollo-client/src/main/java/com/ctrip/apollo/client/loader/impl/MockConfigLoader.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.ctrip.apollo.client.loader.impl;
-
-import com.ctrip.apollo.client.loader.ConfigLoader;
-import com.google.common.collect.Maps;
-import org.springframework.core.env.CompositePropertySource;
-import org.springframework.core.env.MapPropertySource;
-
-import java.util.Map;
-
-/**
- * Mock config
- * @author Jason Song(song_s@ctrip.com)
- */
-public class MockConfigLoader implements ConfigLoader {
- private static final String PROPERTY_SOURCE_NAME = "ApolloMockConfigProperties";
-
- @Override
- public CompositePropertySource loadPropertySource() {
- CompositePropertySource composite = new CompositePropertySource(PROPERTY_SOURCE_NAME);
- composite.addPropertySource(mock());
- return composite;
- }
-
- private MapPropertySource mock() {
- Map source = Maps.newHashMap();
- source.put("apollo.foo" ,"bar");
- MapPropertySource propertySource = new MapPropertySource("mock source", source);
-
- return propertySource;
- }
-}
diff --git a/apollo-client/src/test/java/com/ctrip/apollo/client/ApolloConfigManagerTest.java b/apollo-client/src/test/java/com/ctrip/apollo/client/ApolloConfigManagerTest.java
index 79365d1609106eab04632e9171a5acf613c6fdae..7911b921f4d0b62ebc07afec12a815ba7d1c8eb3 100644
--- a/apollo-client/src/test/java/com/ctrip/apollo/client/ApolloConfigManagerTest.java
+++ b/apollo-client/src/test/java/com/ctrip/apollo/client/ApolloConfigManagerTest.java
@@ -7,6 +7,8 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.CompositePropertySource;
@@ -32,10 +34,12 @@ public class ApolloConfigManagerTest {
private ConfigurableEnvironment env;
@Mock
private MutablePropertySources mutablePropertySources;
+ @Mock
+ private BeanDefinitionRegistry beanDefinitionRegistry;
@Before
public void setUp() {
- apolloConfigManager = new ApolloConfigManager();
+ apolloConfigManager = spy(new ApolloConfigManager());
when(applicationContext.getEnvironment()).thenReturn(env);
when(env.getPropertySources()).thenReturn(mutablePropertySources);
@@ -68,4 +72,13 @@ public class ApolloConfigManagerTest {
assertTrue(insertedPropertySource.getPropertySources().contains(somePropertySource));
}
+ @Test
+ public void testPostProcessBeanDefinitionRegistry() {
+ doNothing().when(apolloConfigManager).preparePropertySource();
+
+ apolloConfigManager.postProcessBeanDefinitionRegistry(beanDefinitionRegistry);
+
+ verify(beanDefinitionRegistry, times(2)).registerBeanDefinition(anyString(), any(BeanDefinition.class));
+ }
+
}
diff --git a/apollo-configserver/src/main/java/com/ctrip/apollo/server/config/WebConfig.java b/apollo-configserver/src/main/java/com/ctrip/apollo/configserver/config/WebConfig.java
similarity index 97%
rename from apollo-configserver/src/main/java/com/ctrip/apollo/server/config/WebConfig.java
rename to apollo-configserver/src/main/java/com/ctrip/apollo/configserver/config/WebConfig.java
index 69a176cb92cb146b767e48c9b9b83bc64ffcd685..744c937a41771120f054289dcf6e3237deeb20f3 100644
--- a/apollo-configserver/src/main/java/com/ctrip/apollo/server/config/WebConfig.java
+++ b/apollo-configserver/src/main/java/com/ctrip/apollo/configserver/config/WebConfig.java
@@ -1,4 +1,4 @@
-package com.ctrip.apollo.server.config;
+package com.ctrip.apollo.configserver.config;
import org.h2.server.web.WebServlet;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
diff --git a/apollo-configserver/src/main/java/com/ctrip/apollo/configserver/controller/ConfigController.java b/apollo-configserver/src/main/java/com/ctrip/apollo/configserver/controller/ConfigController.java
new file mode 100644
index 0000000000000000000000000000000000000000..769f402fd4e2995f9a5385b07d7d87a91bc3da67
--- /dev/null
+++ b/apollo-configserver/src/main/java/com/ctrip/apollo/configserver/controller/ConfigController.java
@@ -0,0 +1,52 @@
+package com.ctrip.apollo.configserver.controller;
+
+import com.ctrip.apollo.biz.entity.Version;
+import com.ctrip.apollo.biz.service.ConfigService;
+import com.ctrip.apollo.core.model.ApolloConfig;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * @author Jason Song(song_s@ctrip.com)
+ */
+@RestController
+public class ConfigController {
+ @Resource(name = "configService")
+ private ConfigService configService;
+
+ @RequestMapping(value = "/{appId}/{clusterName}/{versionName:.*}")
+ public ApolloConfig queryConfig(@PathVariable long appId,
+ @PathVariable String clusterName,
+ @PathVariable String versionName,
+ @RequestParam(value = "releaseId", defaultValue = "-1") long clientSideReleaseId,
+ HttpServletResponse response) throws IOException {
+ Version version = configService.loadVersionByAppIdAndVersionName(appId, versionName);
+ if (version == null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND,
+ String.format("Could not load version with appId: %d, versionName: %s", appId, versionName));
+ return null;
+ }
+ if (version.getReleaseId() == clientSideReleaseId) {
+ //Client side configuration is the same with server side, return 304
+ response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+ return null;
+ }
+
+ ApolloConfig apolloConfig =
+ configService.loadConfigByVersionAndClusterName(version, clusterName);
+
+ if (apolloConfig == null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND,
+ String.format("Could not load config with releaseId: %d, clusterName: %s", version.getReleaseId(), clusterName));
+ return null;
+ }
+
+ return apolloConfig;
+ }
+}
diff --git a/apollo-configserver/src/main/java/com/ctrip/apollo/server/controller/ConfigController.java b/apollo-configserver/src/main/java/com/ctrip/apollo/server/controller/ConfigController.java
deleted file mode 100644
index 984fa3f6376166f0acc987982fa2c0ca65d31cde..0000000000000000000000000000000000000000
--- a/apollo-configserver/src/main/java/com/ctrip/apollo/server/controller/ConfigController.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.ctrip.apollo.server.controller;
-
-import com.ctrip.apollo.biz.service.ConfigService;
-import com.ctrip.apollo.core.model.ApolloConfig;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import javax.annotation.Resource;
-
-/**
- * @author Jason Song(song_s@ctrip.com)
- */
-@RestController
-public class ConfigController {
- @Resource(name = "configService")
- private ConfigService configService;
-
- @RequestMapping(value = "/{appId}/{clusterName}/{version:.*}")
- public ApolloConfig queryConfig(@PathVariable long appId,
- @PathVariable String clusterName,
- @PathVariable String version) {
- return configService.loadConfig(appId, clusterName, version);
- }
-}
diff --git a/apollo-configserver/src/test/java/com/ctrip/apollo/configserver/AllTests.java b/apollo-configserver/src/test/java/com/ctrip/apollo/configserver/AllTests.java
index 7239a6c31f33619dc30434045d716346c143a7c9..f5f5929e89bd335f3eb6e3cd3deb0fc9505e8506 100644
--- a/apollo-configserver/src/test/java/com/ctrip/apollo/configserver/AllTests.java
+++ b/apollo-configserver/src/test/java/com/ctrip/apollo/configserver/AllTests.java
@@ -1,12 +1,13 @@
package com.ctrip.apollo.configserver;
+import com.ctrip.apollo.configserver.controller.ConfigControllerTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({
-
+ConfigControllerTest.class
})
public class AllTests {
diff --git a/apollo-configserver/src/test/java/com/ctrip/apollo/configserver/controller/ConfigControllerTest.java b/apollo-configserver/src/test/java/com/ctrip/apollo/configserver/controller/ConfigControllerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..89601f7bfd9ccbbaf4c66647dd70182a38e6f9c0
--- /dev/null
+++ b/apollo-configserver/src/test/java/com/ctrip/apollo/configserver/controller/ConfigControllerTest.java
@@ -0,0 +1,111 @@
+package com.ctrip.apollo.configserver.controller;
+
+import com.ctrip.apollo.biz.entity.Version;
+import com.ctrip.apollo.biz.service.ConfigService;
+import com.ctrip.apollo.core.model.ApolloConfig;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import javax.servlet.http.HttpServletResponse;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.*;
+
+/**
+ * @author Jason Song(song_s@ctrip.com)
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class ConfigControllerTest {
+ private ConfigController configController;
+ @Mock
+ private ConfigService configService;
+
+ @Before
+ public void setUp() throws Exception {
+ configController = new ConfigController();
+ ReflectionTestUtils.setField(configController, "configService", configService);
+ }
+
+ @Test
+ public void testQueryConfig() throws Exception {
+ ApolloConfig someApolloConfig = mock(ApolloConfig.class);
+ long someAppId = 1;
+ String someClusterName = "someClusterName";
+ String someVersionName = "someVersion";
+ long someClientSideReleaseId = 1;
+ long someServerSideNewReleaseId = 2;
+ HttpServletResponse someResponse = mock(HttpServletResponse.class);
+ Version someVersion = mock(Version.class);
+
+ when(configService.loadVersionByAppIdAndVersionName(someAppId, someVersionName)).thenReturn(someVersion);
+ when(someVersion.getReleaseId()).thenReturn(someServerSideNewReleaseId);
+ when(configService.loadConfigByVersionAndClusterName(someVersion, someClusterName)).thenReturn(someApolloConfig);
+
+ ApolloConfig result = configController.queryConfig(someAppId, someClusterName, someVersionName, someClientSideReleaseId, someResponse);
+
+ assertEquals(someApolloConfig, result);
+ verify(configService, times(1)).loadVersionByAppIdAndVersionName(someAppId, someVersionName);
+ verify(configService, times(1)).loadConfigByVersionAndClusterName(someVersion, someClusterName);
+ }
+
+ @Test
+ public void testQueryConfigWithVersionNotFound() throws Exception {
+ long someAppId = 1;
+ String someClusterName = "someClusterName";
+ String someVersionName = "someVersion";
+ long someClientSideReleaseId = 1;
+ HttpServletResponse someResponse = mock(HttpServletResponse.class);
+
+ when(configService.loadVersionByAppIdAndVersionName(someAppId, someVersionName)).thenReturn(null);
+
+ ApolloConfig result = configController.queryConfig(someAppId, someClusterName, someVersionName, someClientSideReleaseId, someResponse);
+
+ assertNull(result);
+ verify(someResponse, times(1)).sendError(eq(HttpServletResponse.SC_NOT_FOUND), anyString());
+ }
+
+ @Test
+ public void testQueryConfigWithApolloConfigNotFound() throws Exception {
+ long someAppId = 1;
+ String someClusterName = "someClusterName";
+ String someVersionName = "someVersion";
+ long someClientSideReleaseId = 1;
+ long someServerSideNewReleaseId = 2;
+ HttpServletResponse someResponse = mock(HttpServletResponse.class);
+ Version someVersion = mock(Version.class);
+
+ when(configService.loadVersionByAppIdAndVersionName(someAppId, someVersionName)).thenReturn(someVersion);
+ when(someVersion.getReleaseId()).thenReturn(someServerSideNewReleaseId);
+ when(configService.loadConfigByVersionAndClusterName(someVersion, someClusterName)).thenReturn(null);
+
+ ApolloConfig result = configController.queryConfig(someAppId, someClusterName, someVersionName, someClientSideReleaseId, someResponse);
+
+ assertNull(result);
+ verify(someResponse, times(1)).sendError(eq(HttpServletResponse.SC_NOT_FOUND), anyString());
+ }
+
+ @Test
+ public void testQueryConfigWithApolloConfigNotModified() throws Exception {
+ long someAppId = 1;
+ String someClusterName = "someClusterName";
+ String someVersionName = "someVersion";
+ long someClientSideReleaseId = 1;
+ long someServerSideReleaseId = someClientSideReleaseId;
+ HttpServletResponse someResponse = mock(HttpServletResponse.class);
+ Version someVersion = mock(Version.class);
+
+ when(configService.loadVersionByAppIdAndVersionName(someAppId, someVersionName)).thenReturn(someVersion);
+ when(someVersion.getReleaseId()).thenReturn(someServerSideReleaseId);
+
+ ApolloConfig result = configController.queryConfig(someAppId, someClusterName, someVersionName, someClientSideReleaseId, someResponse);
+
+ assertNull(result);
+ verify(someResponse, times(1)).setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+ verify(configService, never()).loadConfigByVersionAndClusterName(any(Version.class), anyString());
+ }
+}
diff --git a/apollo-configserver/src/test/java/com/ctrip/apollo/server/AllTests.java b/apollo-configserver/src/test/java/com/ctrip/apollo/server/AllTests.java
deleted file mode 100644
index 65c318c5485a5e15922d3447e639c5775431ea4f..0000000000000000000000000000000000000000
--- a/apollo-configserver/src/test/java/com/ctrip/apollo/server/AllTests.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.ctrip.apollo.server;
-
-import com.ctrip.apollo.server.controller.ConfigControllerTest;
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-import org.junit.runners.Suite.SuiteClasses;
-
-@RunWith(Suite.class)
-@SuiteClasses({
-ConfigControllerTest.class
-})
-public class AllTests {
-
-}
diff --git a/apollo-configserver/src/test/java/com/ctrip/apollo/server/controller/ConfigControllerTest.java b/apollo-configserver/src/test/java/com/ctrip/apollo/server/controller/ConfigControllerTest.java
deleted file mode 100644
index e2655da0a356781a531ffcbbedef6652519cca9d..0000000000000000000000000000000000000000
--- a/apollo-configserver/src/test/java/com/ctrip/apollo/server/controller/ConfigControllerTest.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.ctrip.apollo.server.controller;
-
-import com.ctrip.apollo.biz.service.ConfigService;
-import com.ctrip.apollo.core.model.ApolloConfig;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.springframework.test.util.ReflectionTestUtils;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.*;
-
-/**
- * @author Jason Song(song_s@ctrip.com)
- */
-@RunWith(MockitoJUnitRunner.class)
-public class ConfigControllerTest {
- private ConfigController configController;
- @Mock
- private ConfigService configService;
-
- @Before
- public void setUp() throws Exception {
- configController = new ConfigController();
- ReflectionTestUtils.setField(configController, "configService", configService);
- }
-
- @Test
- public void testQueryConfig() throws Exception {
- ApolloConfig someApolloConfig = mock(ApolloConfig.class);
- long someAppId = 1;
- String someClusterName = "someClusterName";
- String someVersion = "someVersion";
-
- when(configService.loadConfig(someAppId, someClusterName, someVersion)).thenReturn(someApolloConfig);
-
- ApolloConfig result = configController.queryConfig(someAppId, someClusterName, someVersion);
-
- assertEquals(someApolloConfig, result);
- verify(configService, times(1)).loadConfig(someAppId, someClusterName, someVersion);
-
- }
-}
diff --git a/apollo-demo/src/main/java/com/ctrip/apollo/demo/AppConfig.java b/apollo-demo/src/main/java/com/ctrip/apollo/demo/AppConfig.java
index 15b098fc99a5492445bb16aaf7efcd90e6df09a2..0aaa5924b009167041d1e056ca94ebe8cde05ae1 100644
--- a/apollo-demo/src/main/java/com/ctrip/apollo/demo/AppConfig.java
+++ b/apollo-demo/src/main/java/com/ctrip/apollo/demo/AppConfig.java
@@ -4,7 +4,6 @@ import com.ctrip.apollo.client.ApolloConfigManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
-import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
/**
* @author Jason Song(song_s@ctrip.com)
@@ -17,8 +16,13 @@ public class AppConfig {
return new ApolloConfigManager();
}
- @Bean
- public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
- return new PropertySourcesPlaceholderConfigurer();
- }
+// @Bean
+// public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
+// return new PropertySourcesPlaceholderConfigurer();
+// }
+//
+// @Bean
+// public static RefreshScope refreshScope() {
+// return new RefreshScope();
+// }
}
diff --git a/apollo-demo/src/main/java/com/ctrip/apollo/demo/controller/DemoController.java b/apollo-demo/src/main/java/com/ctrip/apollo/demo/controller/DemoController.java
index 2e18907f76226f803ae8bd1fb3df0c399ab51687..2bc85e89ac2dd33765c721db53f867ba16510911 100644
--- a/apollo-demo/src/main/java/com/ctrip/apollo/demo/controller/DemoController.java
+++ b/apollo-demo/src/main/java/com/ctrip/apollo/demo/controller/DemoController.java
@@ -1,11 +1,11 @@
package com.ctrip.apollo.demo.controller;
-import com.ctrip.apollo.client.ApolloConfigManager;
import com.ctrip.apollo.client.model.ApolloRegistry;
import com.ctrip.apollo.client.util.ConfigUtil;
import com.ctrip.apollo.demo.model.Config;
+import com.ctrip.apollo.demo.service.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.scope.refresh.RefreshScope;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.PathVariable;
@@ -26,20 +26,32 @@ public class DemoController {
@Autowired
private Environment env;
@Autowired
- private ApolloConfigManager apolloConfigManager;
- //Apollo config client internal impl, not intended to be use by application, only for this test page
+ private DemoService demoService;
+ //Apollo config client internal impl, not intended to be used by application, only for this test page
private ConfigUtil configUtil = ConfigUtil.getInstance();
- @Value("${apollo.foo}")
- private String foo;
+ @Autowired
+ private RefreshScope scope;
@RequestMapping(value = "/config/{configName:.*}", method = RequestMethod.GET)
public Config queryConfig(@PathVariable String configName) {
- return new Config(configName, env.getProperty(configName, "undefined"));
+ String value;
+ if (configName.equals("foo")) {
+ value = demoService.getFoo();
+ } else {
+ value = env.getProperty(configName, "undefined");
+ }
+ return new Config(configName, value);
}
@RequestMapping(value = "/client/registries", method = RequestMethod.GET)
public List loadApolloRegistries() throws IOException {
return configUtil.loadApolloRegistries();
}
+
+ @RequestMapping(value = "/refresh", method = RequestMethod.POST)
+ public String refreshBeans() {
+ this.scope.refreshAll();
+ return "ok";
+ }
}
diff --git a/apollo-demo/src/main/java/com/ctrip/apollo/demo/service/DemoService.java b/apollo-demo/src/main/java/com/ctrip/apollo/demo/service/DemoService.java
new file mode 100644
index 0000000000000000000000000000000000000000..8bc558a26daf3a75b86ccc965703c0971ecd4bc2
--- /dev/null
+++ b/apollo-demo/src/main/java/com/ctrip/apollo/demo/service/DemoService.java
@@ -0,0 +1,23 @@
+package com.ctrip.apollo.demo.service;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Jason Song(song_s@ctrip.com)
+ */
+@Service
+@RefreshScope
+public class DemoService {
+ private String foo;
+
+ @Value("${apollo.foo}")
+ private void setFoo(String foo) {
+ this.foo = foo;
+ }
+
+ public String getFoo() {
+ return foo;
+ }
+}