diff --git a/apollo-adminservice/pom.xml b/apollo-adminservice/pom.xml
index cd89c245d3272e4cbab2373f2fdaba5d0eb2e25a..4d47c7ccd348b574477a0a8ea7ce2b50cc88c0c9 100644
--- a/apollo-adminservice/pom.xml
+++ b/apollo-adminservice/pom.xml
@@ -4,7 +4,7 @@
com.ctrip.framework.apollo
apollo
- 0.0.6
+ 0.0.7-SNAPSHOT
../pom.xml
4.0.0
diff --git a/apollo-assembly/pom.xml b/apollo-assembly/pom.xml
index ff5af3603497ae7c78f2c4557f4869ea114b0fe1..07c2dd1d68dbaaf6b3a53517965a220863101dbb 100644
--- a/apollo-assembly/pom.xml
+++ b/apollo-assembly/pom.xml
@@ -4,7 +4,7 @@
com.ctrip.framework.apollo
apollo
- 0.0.6
+ 0.0.7-SNAPSHOT
../pom.xml
4.0.0
diff --git a/apollo-biz/pom.xml b/apollo-biz/pom.xml
index cc7e8bc9714cb3045b169d683d407776182a39c3..2a716c2634e1a7e2468da84f361a82b5ea468849 100644
--- a/apollo-biz/pom.xml
+++ b/apollo-biz/pom.xml
@@ -4,7 +4,7 @@
apollo
com.ctrip.framework.apollo
- 0.0.6
+ 0.0.7-SNAPSHOT
4.0.0
apollo-biz
diff --git a/apollo-buildtools/pom.xml b/apollo-buildtools/pom.xml
index 4caf191bd46e8fbdc4456f75a30662e80c1ae6f5..3977717a56e9769d3917f97af96c50d1918045a9 100644
--- a/apollo-buildtools/pom.xml
+++ b/apollo-buildtools/pom.xml
@@ -4,7 +4,7 @@
com.ctrip.framework.apollo
apollo
- 0.0.6
+ 0.0.7-SNAPSHOT
../pom.xml
4.0.0
diff --git a/apollo-client/pom.xml b/apollo-client/pom.xml
index 278e4c10d10b469f3ff7a44f9accb67a1dad974f..d3da41f061a8d6976fa0a4d9cb7d35c6fd472353 100644
--- a/apollo-client/pom.xml
+++ b/apollo-client/pom.xml
@@ -4,7 +4,7 @@
com.ctrip.framework.apollo
apollo
- 0.0.6
+ 0.0.7-SNAPSHOT
../pom.xml
4.0.0
diff --git a/apollo-common/pom.xml b/apollo-common/pom.xml
index a4f81fa596df812f088ad61da925a299c7c4975f..7c7ac462281c5808d6569ad6c6c4e5afe7dd3a4f 100644
--- a/apollo-common/pom.xml
+++ b/apollo-common/pom.xml
@@ -4,7 +4,7 @@
com.ctrip.framework.apollo
apollo
- 0.0.6
+ 0.0.7-SNAPSHOT
../pom.xml
4.0.0
diff --git a/apollo-configservice/pom.xml b/apollo-configservice/pom.xml
index 28d38a6f11a4b8d6e491127ece1d6717d5cfd07d..57aaaacf2abfcbbd9044aae1a26984a36522641a 100644
--- a/apollo-configservice/pom.xml
+++ b/apollo-configservice/pom.xml
@@ -4,7 +4,7 @@
com.ctrip.framework.apollo
apollo
- 0.0.6
+ 0.0.7-SNAPSHOT
../pom.xml
4.0.0
diff --git a/apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/controller/ConfigFileController.java b/apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/controller/ConfigFileController.java
index 3ab6c48d1c5b1943fe8902413213c71606f12e53..6577d4f28e082ae18faaf916bf5804a2f8c4dfe9 100644
--- a/apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/controller/ConfigFileController.java
+++ b/apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/controller/ConfigFileController.java
@@ -11,6 +11,7 @@ import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
+import com.google.gson.Gson;
import com.ctrip.framework.apollo.biz.entity.ReleaseMessage;
import com.ctrip.framework.apollo.biz.message.ReleaseMessageListener;
@@ -19,11 +20,9 @@ import com.ctrip.framework.apollo.configservice.util.NamespaceUtil;
import com.ctrip.framework.apollo.configservice.util.WatchKeysUtil;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.core.dto.ApolloConfig;
-import com.ctrip.framework.apollo.core.dto.ApolloConfigNotification;
import com.ctrip.framework.apollo.core.utils.PropertiesUtil;
import com.dianping.cat.Cat;
-import org.hibernate.cache.spi.CacheKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -35,12 +34,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.context.request.async.DeferredResult;
import java.io.IOException;
-import java.io.StringWriter;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
import java.util.Properties;
import java.util.Set;
@@ -53,18 +49,20 @@ import javax.servlet.http.HttpServletResponse;
*/
@RestController
@RequestMapping("/configfiles")
-public class ConfigFileController implements ReleaseMessageListener{
+public class ConfigFileController implements ReleaseMessageListener {
private static final Logger logger = LoggerFactory.getLogger(ConfigFileController.class);
private static final Joiner STRING_JOINER = Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR);
private static final long MAX_CACHE_SIZE = 50 * 1024 * 1024; // 50MB
- private static final long EXPIRE_AFTER_WRITE = 10;
- private final HttpHeaders responseHeaders;
+ private static final long EXPIRE_AFTER_WRITE = 30;
+ private final HttpHeaders propertiesResponseHeaders;
+ private final HttpHeaders jsonResponseHeaders;
private final ResponseEntity NOT_FOUND_RESPONSE;
private Cache localCache;
private final Multimap
watchedKeys2CacheKey = Multimaps.synchronizedSetMultimap(HashMultimap.create());
private final Multimap
cacheKey2WatchedKeys = Multimaps.synchronizedSetMultimap(HashMultimap.create());
+ private static final Gson gson = new Gson();
@Autowired
private ConfigController configController;
@@ -103,23 +101,60 @@ public class ConfigFileController implements ReleaseMessageListener{
}
})
.build();
- responseHeaders = new HttpHeaders();
- responseHeaders.add("Content-Type", "text/plain;charset=UTF-8");
+ propertiesResponseHeaders = new HttpHeaders();
+ propertiesResponseHeaders.add("Content-Type", "text/plain;charset=UTF-8");
+ jsonResponseHeaders = new HttpHeaders();
+ jsonResponseHeaders.add("Content-Type", "application/json;charset=UTF-8");
NOT_FOUND_RESPONSE = new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
@RequestMapping(value = "/{appId}/{clusterName}/{namespace:.+}", method = RequestMethod.GET)
- public ResponseEntity queryConfigAsFile(@PathVariable String appId,
+ public ResponseEntity queryConfigAsProperties(@PathVariable String appId,
+ @PathVariable String clusterName,
+ @PathVariable String namespace,
+ @RequestParam(value = "dataCenter", required = false) String dataCenter,
+ @RequestParam(value = "ip", required = false) String clientIp,
+ HttpServletResponse response)
+ throws IOException {
+
+ String result =
+ queryConfig(ConfigFileOutputFormat.PROPERTIES, appId, clusterName, namespace, dataCenter,
+ clientIp, response);
+
+ if (result == null) {
+ return NOT_FOUND_RESPONSE;
+ }
+
+ return new ResponseEntity<>(result, propertiesResponseHeaders, HttpStatus.OK);
+ }
+
+ @RequestMapping(value = "/json/{appId}/{clusterName}/{namespace:.+}", method = RequestMethod.GET)
+ public ResponseEntity queryConfigAsJson(@PathVariable String appId,
@PathVariable String clusterName,
@PathVariable String namespace,
@RequestParam(value = "dataCenter", required = false) String dataCenter,
@RequestParam(value = "ip", required = false) String clientIp,
HttpServletResponse response) throws IOException {
+
+ String result =
+ queryConfig(ConfigFileOutputFormat.JSON, appId, clusterName, namespace, dataCenter,
+ clientIp, response);
+
+ if (result == null) {
+ return NOT_FOUND_RESPONSE;
+ }
+
+ return new ResponseEntity<>(result, jsonResponseHeaders, HttpStatus.OK);
+ }
+
+ String queryConfig(ConfigFileOutputFormat outputFormat, String appId, String clusterName,
+ String namespace, String dataCenter, String clientIp,
+ HttpServletResponse response) throws IOException {
//strip out .properties suffix
namespace = namespaceUtil.filterNamespaceName(namespace);
//TODO add clientIp as key parts?
- String cacheKey = assembleCacheKey(appId, clusterName, namespace, dataCenter);
+ String cacheKey = assembleCacheKey(outputFormat, appId, clusterName, namespace, dataCenter);
String result = localCache.getIfPresent(cacheKey);
@@ -131,11 +166,19 @@ public class ConfigFileController implements ReleaseMessageListener{
response);
if (apolloConfig == null || apolloConfig.getConfigurations() == null) {
- return NOT_FOUND_RESPONSE;
+ return null;
+ }
+
+ switch (outputFormat) {
+ case PROPERTIES:
+ Properties properties = new Properties();
+ properties.putAll(apolloConfig.getConfigurations());
+ result = PropertiesUtil.toString(properties);
+ break;
+ case JSON:
+ result = gson.toJson(apolloConfig.getConfigurations());
+ break;
}
- Properties properties = new Properties();
- properties.putAll(apolloConfig.getConfigurations());
- result = PropertiesUtil.toString(properties);
localCache.put(cacheKey, result);
logger.debug("adding cache for key: {}", cacheKey);
@@ -153,13 +196,14 @@ public class ConfigFileController implements ReleaseMessageListener{
Cat.logEvent("ConfigFile-Cache-Hit", cacheKey);
}
- return new ResponseEntity<>(result, responseHeaders,
- HttpStatus.OK);
+ return result;
}
- String assembleCacheKey(String appId, String clusterName, String namespace,
- String dataCenter) {
- List keyParts = Lists.newArrayList(appId, clusterName, namespace);
+ String assembleCacheKey(ConfigFileOutputFormat outputFormat, String appId, String clusterName,
+ String namespace,
+ String dataCenter) {
+ List keyParts =
+ Lists.newArrayList(outputFormat.getValue(), appId, clusterName, namespace);
if (!Strings.isNullOrEmpty(dataCenter)) {
keyParts.add(dataCenter);
}
@@ -187,4 +231,18 @@ public class ConfigFileController implements ReleaseMessageListener{
localCache.invalidate(cacheKey);
}
}
+
+ enum ConfigFileOutputFormat {
+ PROPERTIES("properties"), JSON("json");
+
+ private String value;
+
+ ConfigFileOutputFormat(String value) {
+ this.value = value;
+ }
+
+ public String getValue() {
+ return value;
+ }
+ }
}
diff --git a/apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/controller/ConfigFileControllerTest.java b/apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/controller/ConfigFileControllerTest.java
index 08d1f190ef6f6e4de890e78cfb3ce46e7f44a50a..3387632d82a353489417cc21455f4956155baa37 100644
--- a/apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/controller/ConfigFileControllerTest.java
+++ b/apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/controller/ConfigFileControllerTest.java
@@ -5,6 +5,8 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
+import com.google.common.reflect.TypeToken;
+import com.google.gson.Gson;
import com.ctrip.framework.apollo.biz.entity.ReleaseMessage;
import com.ctrip.framework.apollo.biz.message.Topics;
@@ -21,7 +23,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.util.ReflectionTestUtils;
-import java.util.List;
+import java.lang.reflect.Type;
import java.util.Map;
import java.util.Set;
@@ -81,7 +83,7 @@ public class ConfigFileControllerTest {
}
@Test
- public void testQueryConfigAsFile() throws Exception {
+ public void testQueryConfigAsProperties() throws Exception {
String someKey = "someKey";
String someValue = "someValue";
String anotherKey = "anotherKey";
@@ -93,7 +95,7 @@ public class ConfigFileControllerTest {
String cacheKey =
configFileController
- .assembleCacheKey(someAppId, someClusterName, someNamespace, someDataCenter);
+ .assembleCacheKey(ConfigFileController.ConfigFileOutputFormat.PROPERTIES, someAppId, someClusterName, someNamespace, someDataCenter);
Map configurations =
ImmutableMap.of(someKey, someValue, anotherKey, anotherValue);
@@ -108,7 +110,7 @@ public class ConfigFileControllerTest {
ResponseEntity response =
configFileController
- .queryConfigAsFile(someAppId, someClusterName, someNamespace, someDataCenter,
+ .queryConfigAsProperties(someAppId, someClusterName, someNamespace, someDataCenter,
someClientIp, someResponse);
assertEquals(2, watchedKeys2CacheKey.size());
@@ -124,7 +126,7 @@ public class ConfigFileControllerTest {
ResponseEntity anotherResponse =
configFileController
- .queryConfigAsFile(someAppId, someClusterName, someNamespace, someDataCenter,
+ .queryConfigAsProperties(someAppId, someClusterName, someNamespace, someDataCenter,
someClientIp, someResponse);
assertEquals(response, anotherResponse);
@@ -134,6 +136,36 @@ public class ConfigFileControllerTest {
someResponse);
}
+ @Test
+ public void testQueryConfigAsJson() throws Exception {
+ String someKey = "someKey";
+ String someValue = "someValue";
+ Gson gson = new Gson();
+ Type responseType = new TypeToken