mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
Merge pull request #1167 from yuhuangbin/nacos-loaddata
[Bugfix] Resolve the type erase caused by loading Nacos data
This commit is contained in:
commit
23c3dd69ab
@ -17,7 +17,6 @@
|
|||||||
package com.alibaba.cloud.nacos.client;
|
package com.alibaba.cloud.nacos.client;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
@ -111,17 +110,7 @@ public class NacosPropertySourceBuilder {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private Map<String, Object> propertiesToMap(Properties properties) {
|
private Map<String, Object> propertiesToMap(Properties properties) {
|
||||||
Map<String, Object> result = new HashMap<>(16);
|
Map<String, Object> result = new HashMap<>(16);
|
||||||
Enumeration<String> keys = (Enumeration<String>) properties.propertyNames();
|
properties.forEach((k, v) -> result.put(String.valueOf(k), v));
|
||||||
while (keys.hasMoreElements()) {
|
|
||||||
String key = keys.nextElement();
|
|
||||||
String value = properties.getProperty(key);
|
|
||||||
if (value != null) {
|
|
||||||
result.put(key, value.trim());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result.put(key, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,12 +111,12 @@ public abstract class AbstractNacosDataParser {
|
|||||||
/**
|
/**
|
||||||
* Generate key-value pairs from the map.
|
* Generate key-value pairs from the map.
|
||||||
*/
|
*/
|
||||||
protected Properties generateProperties(Map<String, String> map) {
|
protected Properties generateProperties(Map<String, Object> map) {
|
||||||
if (null == map || map.isEmpty()) {
|
if (null == map || map.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||||
String key = entry.getKey();
|
String key = entry.getKey();
|
||||||
if (StringUtils.isEmpty(key)) {
|
if (StringUtils.isEmpty(key)) {
|
||||||
continue;
|
continue;
|
||||||
@ -130,12 +130,12 @@ public abstract class AbstractNacosDataParser {
|
|||||||
/**
|
/**
|
||||||
* Reload the key ending in `value` if need.
|
* Reload the key ending in `value` if need.
|
||||||
*/
|
*/
|
||||||
protected Map<String, String> reloadMap(Map<String, String> map) {
|
protected Map<String, Object> reloadMap(Map<String, Object> map) {
|
||||||
if (map == null || map.isEmpty()) {
|
if (map == null || map.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Map<String, String> result = new HashMap<>(map);
|
Map<String, Object> result = new HashMap<>(map);
|
||||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||||
String key = entry.getKey();
|
String key = entry.getKey();
|
||||||
if (key.contains(DOT)) {
|
if (key.contains(DOT)) {
|
||||||
int idx = key.lastIndexOf(DOT);
|
int idx = key.lastIndexOf(DOT);
|
||||||
|
@ -17,18 +17,22 @@
|
|||||||
package com.alibaba.cloud.nacos.parser;
|
package com.alibaba.cloud.nacos.parser;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author zkz
|
* @author zkz
|
||||||
|
* @author yuhuangbin
|
||||||
*/
|
*/
|
||||||
public class NacosDataJsonParser extends AbstractNacosDataParser {
|
public class NacosDataJsonParser extends AbstractNacosDataParser {
|
||||||
|
|
||||||
@ -41,7 +45,7 @@ public class NacosDataJsonParser extends AbstractNacosDataParser {
|
|||||||
if (StringUtils.isEmpty(data)) {
|
if (StringUtils.isEmpty(data)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Map<String, String> map = parseJSON2Map(data);
|
Map<String, Object> map = parseJSON2Map(data);
|
||||||
return this.generateProperties(this.reloadMap(map));
|
return this.generateProperties(this.reloadMap(map));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,44 +55,48 @@ public class NacosDataJsonParser extends AbstractNacosDataParser {
|
|||||||
* @return the map convert by json string
|
* @return the map convert by json string
|
||||||
* @throws IOException thrown if there is a problem parsing config.
|
* @throws IOException thrown if there is a problem parsing config.
|
||||||
*/
|
*/
|
||||||
public static Map<String, String> parseJSON2Map(String json) throws IOException {
|
public static Map<String, Object> parseJSON2Map(String json) throws IOException {
|
||||||
Map<String, String> map = new HashMap<>(32);
|
Map<String, Object> result = new HashMap<>(32);
|
||||||
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
JsonNode jsonNode = mapper.readTree(json);
|
Map<String, Object> nacosDataMap = mapper.readValue(json, Map.class);
|
||||||
if (null == jsonNode) {
|
|
||||||
return map;
|
if (CollectionUtils.isEmpty(nacosDataMap)) {
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
parseJsonNode(map, jsonNode, "");
|
parseNacosDataMap(result, nacosDataMap, "");
|
||||||
return map;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void parseJsonNode(Map<String, String> jsonMap, JsonNode jsonNode,
|
private static void parseNacosDataMap(Map<String, Object> result,
|
||||||
String parentKey) {
|
Map<String, Object> dataMap, String parentKey) {
|
||||||
Iterator<String> fieldNames = jsonNode.fieldNames();
|
Set<Map.Entry<String, Object>> entries = dataMap.entrySet();
|
||||||
while (fieldNames.hasNext()) {
|
for (Iterator<Map.Entry<String, Object>> iterator = entries.iterator(); iterator
|
||||||
String name = fieldNames.next();
|
.hasNext();) {
|
||||||
String fullKey = StringUtils.isEmpty(parentKey) ? name
|
Map.Entry<String, Object> entry = iterator.next();
|
||||||
: parentKey + DOT + name;
|
String key = entry.getKey();
|
||||||
JsonNode resultValue = jsonNode.findValue(name);
|
Object value = entry.getValue();
|
||||||
if (null == resultValue) {
|
|
||||||
|
String fullKey = StringUtils.isEmpty(parentKey) ? key : key.startsWith("[")
|
||||||
|
? parentKey.concat(key) : parentKey.concat(DOT).concat(key);
|
||||||
|
|
||||||
|
if (value instanceof Map) {
|
||||||
|
Map<String, Object> map = (Map<String, Object>) value;
|
||||||
|
parseNacosDataMap(result, map, fullKey);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (resultValue.isArray()) {
|
else if (value instanceof Collection) {
|
||||||
Iterator<JsonNode> iterator = resultValue.elements();
|
int count = 0;
|
||||||
while (iterator != null && iterator.hasNext()) {
|
Collection<Object> collection = (Collection<Object>) value;
|
||||||
JsonNode next = iterator.next();
|
for (Object object : collection) {
|
||||||
if (null == next) {
|
parseNacosDataMap(result,
|
||||||
continue;
|
Collections.singletonMap("[" + (count++) + "]", object),
|
||||||
}
|
fullKey);
|
||||||
parseJsonNode(jsonMap, next, fullKey);
|
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (resultValue.isObject()) {
|
|
||||||
parseJsonNode(jsonMap, resultValue, fullKey);
|
result.put(fullKey, value);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
jsonMap.put(fullKey, resultValue.asText());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,13 +50,13 @@ public class NacosDataXmlParser extends AbstractNacosDataParser {
|
|||||||
if (StringUtils.isEmpty(data)) {
|
if (StringUtils.isEmpty(data)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Map<String, String> map = parseXml2Map(data);
|
Map<String, Object> map = parseXml2Map(data);
|
||||||
return this.generateProperties(this.reloadMap(map));
|
return this.generateProperties(this.reloadMap(map));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, String> parseXml2Map(String xml) throws IOException {
|
private Map<String, Object> parseXml2Map(String xml) throws IOException {
|
||||||
xml = xml.replaceAll("\\r", "").replaceAll("\\n", "").replaceAll("\\t", "");
|
xml = xml.replaceAll("\\r", "").replaceAll("\\n", "").replaceAll("\\t", "");
|
||||||
Map<String, String> map = new HashMap<>(32);
|
Map<String, Object> map = new HashMap<>(32);
|
||||||
try {
|
try {
|
||||||
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance()
|
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance()
|
||||||
.newDocumentBuilder();
|
.newDocumentBuilder();
|
||||||
@ -73,7 +73,7 @@ public class NacosDataXmlParser extends AbstractNacosDataParser {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseNodeList(NodeList nodeList, Map<String, String> map,
|
private void parseNodeList(NodeList nodeList, Map<String, Object> map,
|
||||||
String parentKey) {
|
String parentKey) {
|
||||||
if (nodeList == null || nodeList.getLength() < 1) {
|
if (nodeList == null || nodeList.getLength() < 1) {
|
||||||
return;
|
return;
|
||||||
@ -104,7 +104,7 @@ public class NacosDataXmlParser extends AbstractNacosDataParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseNodeAttr(NamedNodeMap nodeMap, Map<String, String> map,
|
private void parseNodeAttr(NamedNodeMap nodeMap, Map<String, Object> map,
|
||||||
String parentKey) {
|
String parentKey) {
|
||||||
if (null == nodeMap || nodeMap.getLength() < 1) {
|
if (null == nodeMap || nodeMap.getLength() < 1) {
|
||||||
return;
|
return;
|
||||||
|
@ -39,6 +39,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
|||||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@ -51,8 +52,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
|
|||||||
@PowerMockIgnore("javax.management.*")
|
@PowerMockIgnore("javax.management.*")
|
||||||
@PowerMockRunnerDelegate(SpringRunner.class)
|
@PowerMockRunnerDelegate(SpringRunner.class)
|
||||||
@PrepareForTest({ NacosConfigService.class })
|
@PrepareForTest({ NacosConfigService.class })
|
||||||
@SpringBootTest(classes = NacosConfigurationXmlJsonTest.TestConfig.class,
|
@SpringBootTest(classes = NacosConfigurationXmlJsonTest.TestConfig.class, properties = {
|
||||||
properties = { "spring.application.name=xmlApp", "spring.profiles.active=dev",
|
"spring.application.name=xmlApp", "spring.profiles.active=dev",
|
||||||
"spring.cloud.nacos.config.server-addr=127.0.0.1:8848",
|
"spring.cloud.nacos.config.server-addr=127.0.0.1:8848",
|
||||||
"spring.cloud.nacos.config.namespace=test-namespace",
|
"spring.cloud.nacos.config.namespace=test-namespace",
|
||||||
"spring.cloud.nacos.config.encode=utf-8",
|
"spring.cloud.nacos.config.encode=utf-8",
|
||||||
@ -65,10 +66,9 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
|
|||||||
"spring.cloud.nacos.config.ext-config[0].data-id=ext-json-test.json",
|
"spring.cloud.nacos.config.ext-config[0].data-id=ext-json-test.json",
|
||||||
"spring.cloud.nacos.config.ext-config[1].data-id=ext-common02.properties",
|
"spring.cloud.nacos.config.ext-config[1].data-id=ext-common02.properties",
|
||||||
"spring.cloud.nacos.config.ext-config[1].group=GLOBAL_GROUP",
|
"spring.cloud.nacos.config.ext-config[1].group=GLOBAL_GROUP",
|
||||||
"spring.cloud.nacos.config.shared-dataids=shared-data1.properties",
|
"spring.cloud.nacos.config.shared-dataids=shared-data1.properties,shared-data.json",
|
||||||
"spring.cloud.nacos.config.accessKey=test-accessKey",
|
"spring.cloud.nacos.config.accessKey=test-accessKey",
|
||||||
"spring.cloud.nacos.config.secretKey=test-secretKey" },
|
"spring.cloud.nacos.config.secretKey=test-secretKey" }, webEnvironment = NONE)
|
||||||
webEnvironment = NONE)
|
|
||||||
public class NacosConfigurationXmlJsonTest {
|
public class NacosConfigurationXmlJsonTest {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -136,6 +136,22 @@ public class NacosConfigurationXmlJsonTest {
|
|||||||
return "shared-name=shared-value-1";
|
return "shared-name=shared-value-1";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ("shared-data.json".equals(args[0])
|
||||||
|
&& "DEFAULT_GROUP".equals(args[1])) {
|
||||||
|
return "{\n" + " \"test\" : {\n"
|
||||||
|
+ " \"name\" : \"test\",\n"
|
||||||
|
+ " \"list\" : [\n" + " {\n"
|
||||||
|
+ " \"name\" :\"listname1\",\n"
|
||||||
|
+ " \"age\":1\n" + " },\n"
|
||||||
|
+ " {\n"
|
||||||
|
+ " \"name\" :\"listname2\",\n"
|
||||||
|
+ " \"age\":2\n" + " }\n"
|
||||||
|
+ " ],\n" + " \"metadata\" : {\n"
|
||||||
|
+ " \"intKey\" : 123,\n"
|
||||||
|
+ " \"booleanKey\" : true\n" + " }\n"
|
||||||
|
+ " }\n" + "}";
|
||||||
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -156,6 +172,9 @@ public class NacosConfigurationXmlJsonTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private NacosRefreshHistory refreshHistory;
|
private NacosRefreshHistory refreshHistory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Environment environment;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void contextLoads() throws Exception {
|
public void contextLoads() throws Exception {
|
||||||
|
|
||||||
@ -176,6 +195,27 @@ public class NacosConfigurationXmlJsonTest {
|
|||||||
|
|
||||||
checkoutEndpoint();
|
checkoutEndpoint();
|
||||||
|
|
||||||
|
checkJsonParser();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkJsonParser() {
|
||||||
|
assertThat(environment.getProperty("test.name", String.class)).isEqualTo("test");
|
||||||
|
|
||||||
|
assertThat(environment.getProperty("test.list[0].name", String.class))
|
||||||
|
.isEqualTo("listname1");
|
||||||
|
assertThat(environment.getProperty("test.list[0].age", Integer.class))
|
||||||
|
.isEqualTo(1);
|
||||||
|
|
||||||
|
assertThat(environment.getProperty("test.list[1].name", String.class))
|
||||||
|
.isEqualTo("listname2");
|
||||||
|
assertThat(environment.getProperty("test.list[1].age", Integer.class))
|
||||||
|
.isEqualTo(2);
|
||||||
|
|
||||||
|
assertThat(
|
||||||
|
(Integer) environment.getProperty("test.metadata.intKey", Object.class))
|
||||||
|
.isEqualTo(123);
|
||||||
|
assertThat((Boolean) environment.getProperty("test.metadata.booleanKey",
|
||||||
|
Object.class)).isEqualTo(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkoutNacosConfigServerAddr() {
|
private void checkoutNacosConfigServerAddr() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user