From 0b50a47a02244ac3a0dc8db650169866a3a81c45 Mon Sep 17 00:00:00 2001 From: yuhuangbin Date: Fri, 10 Jan 2020 20:11:26 +0800 Subject: [PATCH 1/2] enhance load config data from Nacos --- .../nacos/NacosConfigAutoConfiguration.java | 3 +- .../client/NacosPropertySourceBuilder.java | 13 +--- .../nacos/parser/AbstractNacosDataParser.java | 10 +-- .../nacos/parser/NacosDataJsonParser.java | 70 +++++++++++-------- .../nacos/parser/NacosDataXmlParser.java | 10 +-- 5 files changed, 52 insertions(+), 54 deletions(-) diff --git a/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/NacosConfigAutoConfiguration.java b/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/NacosConfigAutoConfiguration.java index e851faef..60075c9c 100644 --- a/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/NacosConfigAutoConfiguration.java +++ b/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/NacosConfigAutoConfiguration.java @@ -64,7 +64,8 @@ public class NacosConfigAutoConfiguration { public NacosContextRefresher nacosContextRefresher( NacosConfigManager nacosConfigManager, NacosRefreshHistory nacosRefreshHistory) { - // Consider that it is not necessary to be compatible with the previous configuration + // Consider that it is not necessary to be compatible with the previous + // configuration // and use the new configuration if necessary. return new NacosContextRefresher(nacosConfigManager, nacosRefreshHistory); } diff --git a/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/client/NacosPropertySourceBuilder.java b/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/client/NacosPropertySourceBuilder.java index 3f650b5e..767a72c1 100644 --- a/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/client/NacosPropertySourceBuilder.java +++ b/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/client/NacosPropertySourceBuilder.java @@ -17,7 +17,6 @@ package com.alibaba.cloud.nacos.client; import java.util.Date; -import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Properties; @@ -111,17 +110,7 @@ public class NacosPropertySourceBuilder { @SuppressWarnings("unchecked") private Map propertiesToMap(Properties properties) { Map result = new HashMap<>(16); - Enumeration keys = (Enumeration) properties.propertyNames(); - 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); - } - } + properties.forEach((k, v) -> result.put(String.valueOf(k), v)); return result; } diff --git a/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/AbstractNacosDataParser.java b/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/AbstractNacosDataParser.java index 38896118..4109b049 100644 --- a/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/AbstractNacosDataParser.java +++ b/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/AbstractNacosDataParser.java @@ -111,12 +111,12 @@ public abstract class AbstractNacosDataParser { /** * Generate key-value pairs from the map. */ - protected Properties generateProperties(Map map) { + protected Properties generateProperties(Map map) { if (null == map || map.isEmpty()) { return null; } Properties properties = new Properties(); - for (Map.Entry entry : map.entrySet()) { + for (Map.Entry entry : map.entrySet()) { String key = entry.getKey(); if (StringUtils.isEmpty(key)) { continue; @@ -130,12 +130,12 @@ public abstract class AbstractNacosDataParser { /** * Reload the key ending in `value` if need. */ - protected Map reloadMap(Map map) { + protected Map reloadMap(Map map) { if (map == null || map.isEmpty()) { return null; } - Map result = new HashMap<>(map); - for (Map.Entry entry : map.entrySet()) { + Map result = new HashMap<>(map); + for (Map.Entry entry : map.entrySet()) { String key = entry.getKey(); if (key.contains(DOT)) { int idx = key.lastIndexOf(DOT); diff --git a/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/NacosDataJsonParser.java b/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/NacosDataJsonParser.java index 437661a3..7b22192d 100644 --- a/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/NacosDataJsonParser.java +++ b/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/NacosDataJsonParser.java @@ -17,18 +17,22 @@ package com.alibaba.cloud.nacos.parser; import java.io.IOException; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Properties; +import java.util.Set; -import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; /** * @author zkz + * @author yuhuangbin */ public class NacosDataJsonParser extends AbstractNacosDataParser { @@ -41,7 +45,7 @@ public class NacosDataJsonParser extends AbstractNacosDataParser { if (StringUtils.isEmpty(data)) { return null; } - Map map = parseJSON2Map(data); + Map map = parseJSON2Map(data); return this.generateProperties(this.reloadMap(map)); } @@ -51,44 +55,48 @@ public class NacosDataJsonParser extends AbstractNacosDataParser { * @return the map convert by json string * @throws IOException thrown if there is a problem parsing config. */ - public static Map parseJSON2Map(String json) throws IOException { - Map map = new HashMap<>(32); + public static Map parseJSON2Map(String json) throws IOException { + Map result = new HashMap<>(32); + ObjectMapper mapper = new ObjectMapper(); - JsonNode jsonNode = mapper.readTree(json); - if (null == jsonNode) { - return map; + Map nacosDataMap = mapper.readValue(json, Map.class); + + if (CollectionUtils.isEmpty(nacosDataMap)) { + return result; } - parseJsonNode(map, jsonNode, ""); - return map; + parseNacosDataMap(result, nacosDataMap, ""); + return result; } - private static void parseJsonNode(Map jsonMap, JsonNode jsonNode, - String parentKey) { - Iterator fieldNames = jsonNode.fieldNames(); - while (fieldNames.hasNext()) { - String name = fieldNames.next(); - String fullKey = StringUtils.isEmpty(parentKey) ? name - : parentKey + DOT + name; - JsonNode resultValue = jsonNode.findValue(name); - if (null == resultValue) { + private static void parseNacosDataMap(Map result, + Map dataMap, String parentKey) { + Set> entries = dataMap.entrySet(); + for (Iterator> iterator = entries.iterator(); iterator + .hasNext();) { + Map.Entry entry = iterator.next(); + String key = entry.getKey(); + Object value = entry.getValue(); + + String fullKey = StringUtils.isEmpty(parentKey) ? key : key.startsWith("[") + ? parentKey.concat(key) : parentKey.concat(DOT).concat(key); + + if (value instanceof Map) { + Map map = (Map) value; + parseNacosDataMap(result, map, fullKey); continue; } - if (resultValue.isArray()) { - Iterator iterator = resultValue.elements(); - while (iterator != null && iterator.hasNext()) { - JsonNode next = iterator.next(); - if (null == next) { - continue; - } - parseJsonNode(jsonMap, next, fullKey); + else if (value instanceof Collection) { + int count = 0; + Collection collection = (Collection) value; + for (Object object : collection) { + parseNacosDataMap(result, + Collections.singletonMap("[" + (count++) + "]", object), + fullKey); } continue; } - if (resultValue.isObject()) { - parseJsonNode(jsonMap, resultValue, fullKey); - continue; - } - jsonMap.put(fullKey, resultValue.asText()); + + result.put(fullKey, value); } } diff --git a/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/NacosDataXmlParser.java b/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/NacosDataXmlParser.java index 8a43ad9c..7a9c45d6 100644 --- a/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/NacosDataXmlParser.java +++ b/spring-cloud-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/NacosDataXmlParser.java @@ -50,13 +50,13 @@ public class NacosDataXmlParser extends AbstractNacosDataParser { if (StringUtils.isEmpty(data)) { return null; } - Map map = parseXml2Map(data); + Map map = parseXml2Map(data); return this.generateProperties(this.reloadMap(map)); } - private Map parseXml2Map(String xml) throws IOException { + private Map parseXml2Map(String xml) throws IOException { xml = xml.replaceAll("\\r", "").replaceAll("\\n", "").replaceAll("\\t", ""); - Map map = new HashMap<>(32); + Map map = new HashMap<>(32); try { DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance() .newDocumentBuilder(); @@ -73,7 +73,7 @@ public class NacosDataXmlParser extends AbstractNacosDataParser { return map; } - private void parseNodeList(NodeList nodeList, Map map, + private void parseNodeList(NodeList nodeList, Map map, String parentKey) { if (nodeList == null || nodeList.getLength() < 1) { return; @@ -104,7 +104,7 @@ public class NacosDataXmlParser extends AbstractNacosDataParser { } } - private void parseNodeAttr(NamedNodeMap nodeMap, Map map, + private void parseNodeAttr(NamedNodeMap nodeMap, Map map, String parentKey) { if (null == nodeMap || nodeMap.getLength() < 1) { return; From f7455bcf88d4c9e8731ae1f9fc62b484ea7627e4 Mon Sep 17 00:00:00 2001 From: yuhuangbin Date: Mon, 13 Jan 2020 10:44:15 +0800 Subject: [PATCH 2/2] add Json parser test cast --- .../nacos/NacosConfigurationXmlJsonTest.java | 76 ++++++++++++++----- 1 file changed, 58 insertions(+), 18 deletions(-) diff --git a/spring-cloud-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigurationXmlJsonTest.java b/spring-cloud-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigurationXmlJsonTest.java index da1380c2..b06cfd86 100644 --- a/spring-cloud-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigurationXmlJsonTest.java +++ b/spring-cloud-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigurationXmlJsonTest.java @@ -39,6 +39,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; import org.springframework.test.context.junit4.SpringRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -51,24 +52,23 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @PowerMockIgnore("javax.management.*") @PowerMockRunnerDelegate(SpringRunner.class) @PrepareForTest({ NacosConfigService.class }) -@SpringBootTest(classes = NacosConfigurationXmlJsonTest.TestConfig.class, - properties = { "spring.application.name=xmlApp", "spring.profiles.active=dev", - "spring.cloud.nacos.config.server-addr=127.0.0.1:8848", - "spring.cloud.nacos.config.namespace=test-namespace", - "spring.cloud.nacos.config.encode=utf-8", - "spring.cloud.nacos.config.timeout=1000", - "spring.cloud.nacos.config.group=test-group", - "spring.cloud.nacos.config.name=test-name", - "spring.cloud.nacos.config.cluster-name=test-cluster", - "spring.cloud.nacos.config.file-extension=xml", - "spring.cloud.nacos.config.contextPath=test-contextpath", - "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].group=GLOBAL_GROUP", - "spring.cloud.nacos.config.shared-dataids=shared-data1.properties", - "spring.cloud.nacos.config.accessKey=test-accessKey", - "spring.cloud.nacos.config.secretKey=test-secretKey" }, - webEnvironment = NONE) +@SpringBootTest(classes = NacosConfigurationXmlJsonTest.TestConfig.class, properties = { + "spring.application.name=xmlApp", "spring.profiles.active=dev", + "spring.cloud.nacos.config.server-addr=127.0.0.1:8848", + "spring.cloud.nacos.config.namespace=test-namespace", + "spring.cloud.nacos.config.encode=utf-8", + "spring.cloud.nacos.config.timeout=1000", + "spring.cloud.nacos.config.group=test-group", + "spring.cloud.nacos.config.name=test-name", + "spring.cloud.nacos.config.cluster-name=test-cluster", + "spring.cloud.nacos.config.file-extension=xml", + "spring.cloud.nacos.config.contextPath=test-contextpath", + "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].group=GLOBAL_GROUP", + "spring.cloud.nacos.config.shared-dataids=shared-data1.properties,shared-data.json", + "spring.cloud.nacos.config.accessKey=test-accessKey", + "spring.cloud.nacos.config.secretKey=test-secretKey" }, webEnvironment = NONE) public class NacosConfigurationXmlJsonTest { static { @@ -136,6 +136,22 @@ public class NacosConfigurationXmlJsonTest { 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 ""; } }); @@ -156,6 +172,9 @@ public class NacosConfigurationXmlJsonTest { @Autowired private NacosRefreshHistory refreshHistory; + @Autowired + private Environment environment; + @Test public void contextLoads() throws Exception { @@ -176,6 +195,27 @@ public class NacosConfigurationXmlJsonTest { 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() {