mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
Merge pull request #1179 from yuhuangbin/nacos-loaddata-orderly
[optimize] Nacos config load data orderly
This commit is contained in:
commit
dbba024538
@ -17,9 +17,8 @@
|
||||
package com.alibaba.cloud.nacos.client;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.alibaba.cloud.nacos.NacosPropertySourceRepository;
|
||||
import com.alibaba.cloud.nacos.parser.NacosDataParserHandler;
|
||||
@ -39,7 +38,7 @@ public class NacosPropertySourceBuilder {
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(NacosPropertySourceBuilder.class);
|
||||
|
||||
private static final Properties EMPTY_PROPERTIES = new Properties();
|
||||
private static final Map<String, Object> EMPTY_MAP = new LinkedHashMap();
|
||||
|
||||
private ConfigService configService;
|
||||
|
||||
@ -72,14 +71,15 @@ public class NacosPropertySourceBuilder {
|
||||
*/
|
||||
NacosPropertySource build(String dataId, String group, String fileExtension,
|
||||
boolean isRefreshable) {
|
||||
Properties p = loadNacosData(dataId, group, fileExtension);
|
||||
Map<String, Object> p = loadNacosData(dataId, group, fileExtension);
|
||||
NacosPropertySource nacosPropertySource = new NacosPropertySource(group, dataId,
|
||||
propertiesToMap(p), new Date(), isRefreshable);
|
||||
p, new Date(), isRefreshable);
|
||||
NacosPropertySourceRepository.collectNacosPropertySource(nacosPropertySource);
|
||||
return nacosPropertySource;
|
||||
}
|
||||
|
||||
private Properties loadNacosData(String dataId, String group, String fileExtension) {
|
||||
private Map<String, Object> loadNacosData(String dataId, String group,
|
||||
String fileExtension) {
|
||||
String data = null;
|
||||
try {
|
||||
data = configService.getConfig(dataId, group, timeout);
|
||||
@ -87,16 +87,16 @@ public class NacosPropertySourceBuilder {
|
||||
log.warn(
|
||||
"Ignore the empty nacos configuration and get it based on dataId[{}] & group[{}]",
|
||||
dataId, group);
|
||||
return EMPTY_PROPERTIES;
|
||||
return EMPTY_MAP;
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(String.format(
|
||||
"Loading nacos data, dataId: '%s', group: '%s', data: %s", dataId,
|
||||
group, data));
|
||||
}
|
||||
Properties properties = NacosDataParserHandler.getInstance()
|
||||
Map<String, Object> dataMap = NacosDataParserHandler.getInstance()
|
||||
.parseNacosData(data, fileExtension);
|
||||
return properties == null ? EMPTY_PROPERTIES : properties;
|
||||
return dataMap == null ? EMPTY_MAP : dataMap;
|
||||
}
|
||||
catch (NacosException e) {
|
||||
log.error("get data from Nacos error,dataId:{}, ", dataId, e);
|
||||
@ -104,14 +104,7 @@ public class NacosPropertySourceBuilder {
|
||||
catch (Exception e) {
|
||||
log.error("parse data from Nacos error,dataId:{},data:{},", dataId, data, e);
|
||||
}
|
||||
return EMPTY_PROPERTIES;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> propertiesToMap(Properties properties) {
|
||||
Map<String, Object> result = new HashMap<>(16);
|
||||
properties.forEach((k, v) -> result.put(String.valueOf(k), v));
|
||||
return result;
|
||||
return EMPTY_MAP;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,9 +17,12 @@
|
||||
package com.alibaba.cloud.nacos.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@ -32,6 +35,8 @@ public abstract class AbstractNacosDataParser {
|
||||
|
||||
protected static final String VALUE = "value";
|
||||
|
||||
protected static final String EMPTY_STRING = "";
|
||||
|
||||
private String extension;
|
||||
|
||||
private AbstractNacosDataParser nextParser;
|
||||
@ -66,7 +71,7 @@ public abstract class AbstractNacosDataParser {
|
||||
* @return result of Properties
|
||||
* @throws IOException thrown if there is a problem parsing config.
|
||||
*/
|
||||
public final Properties parseNacosData(String data, String extension)
|
||||
public final Map<String, Object> parseNacosData(String data, String extension)
|
||||
throws IOException {
|
||||
if (extension == null || extension.length() < 1) {
|
||||
throw new IllegalStateException("The file extension cannot be empty");
|
||||
@ -86,7 +91,7 @@ public abstract class AbstractNacosDataParser {
|
||||
* @return result of Properties
|
||||
* @throws IOException thrown if there is a problem parsing config.
|
||||
*/
|
||||
protected abstract Properties doParse(String data) throws IOException;
|
||||
protected abstract Map<String, Object> doParse(String data) throws IOException;
|
||||
|
||||
protected AbstractNacosDataParser setNextParser(AbstractNacosDataParser nextParser) {
|
||||
this.nextParser = nextParser;
|
||||
@ -108,23 +113,36 @@ public abstract class AbstractNacosDataParser {
|
||||
|| this.extension.contains(extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate key-value pairs from the map.
|
||||
*/
|
||||
protected Properties generateProperties(Map<String, Object> map) {
|
||||
if (null == map || map.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Properties properties = new Properties();
|
||||
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
protected void flattenedMap(Map<String, Object> result, Map<String, Object> dataMap,
|
||||
String parentKey) {
|
||||
Set<Map.Entry<String, Object>> entries = dataMap.entrySet();
|
||||
for (Iterator<Map.Entry<String, Object>> iterator = entries.iterator(); iterator
|
||||
.hasNext();) {
|
||||
Map.Entry<String, Object> entry = iterator.next();
|
||||
String key = entry.getKey();
|
||||
if (StringUtils.isEmpty(key)) {
|
||||
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<String, Object> map = (Map<String, Object>) value;
|
||||
flattenedMap(result, map, fullKey);
|
||||
continue;
|
||||
}
|
||||
key = key.startsWith(DOT) ? key.replaceFirst("\\.", "") : key;
|
||||
properties.put(key, entry.getValue());
|
||||
else if (value instanceof Collection) {
|
||||
int count = 0;
|
||||
Collection<Object> collection = (Collection<Object>) value;
|
||||
for (Object object : collection) {
|
||||
flattenedMap(result,
|
||||
Collections.singletonMap("[" + (count++) + "]", object),
|
||||
fullKey);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
result.put(fullKey, value);
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,7 +152,7 @@ public abstract class AbstractNacosDataParser {
|
||||
if (map == null || map.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Map<String, Object> result = new HashMap<>(map);
|
||||
Map<String, Object> result = new LinkedHashMap<>(map);
|
||||
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (key.contains(DOT)) {
|
||||
|
@ -17,13 +17,8 @@
|
||||
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.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
@ -41,12 +36,12 @@ public class NacosDataJsonParser extends AbstractNacosDataParser {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Properties doParse(String data) throws IOException {
|
||||
protected Map<String, Object> doParse(String data) throws IOException {
|
||||
if (StringUtils.isEmpty(data)) {
|
||||
return null;
|
||||
}
|
||||
Map<String, Object> map = parseJSON2Map(data);
|
||||
return this.generateProperties(this.reloadMap(map));
|
||||
return this.reloadMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,49 +50,17 @@ 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<String, Object> parseJSON2Map(String json) throws IOException {
|
||||
Map<String, Object> result = new HashMap<>(32);
|
||||
private Map<String, Object> parseJSON2Map(String json) throws IOException {
|
||||
Map<String, Object> result = new LinkedHashMap<>(32);
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
Map<String, Object> nacosDataMap = mapper.readValue(json, Map.class);
|
||||
Map<String, Object> nacosDataMap = mapper.readValue(json, LinkedHashMap.class);
|
||||
|
||||
if (CollectionUtils.isEmpty(nacosDataMap)) {
|
||||
return result;
|
||||
}
|
||||
parseNacosDataMap(result, nacosDataMap, "");
|
||||
flattenedMap(result, nacosDataMap, EMPTY_STRING);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void parseNacosDataMap(Map<String, Object> result,
|
||||
Map<String, Object> dataMap, String parentKey) {
|
||||
Set<Map.Entry<String, Object>> entries = dataMap.entrySet();
|
||||
for (Iterator<Map.Entry<String, Object>> iterator = entries.iterator(); iterator
|
||||
.hasNext();) {
|
||||
Map.Entry<String, Object> 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<String, Object> map = (Map<String, Object>) value;
|
||||
parseNacosDataMap(result, map, fullKey);
|
||||
continue;
|
||||
}
|
||||
else if (value instanceof Collection) {
|
||||
int count = 0;
|
||||
Collection<Object> collection = (Collection<Object>) value;
|
||||
for (Object object : collection) {
|
||||
parseNacosDataMap(result,
|
||||
Collections.singletonMap("[" + (count++) + "]", object),
|
||||
fullKey);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
result.put(fullKey, value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
package com.alibaba.cloud.nacos.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author zkz
|
||||
@ -34,10 +34,11 @@ public final class NacosDataParserHandler {
|
||||
* Parsing nacos configuration content.
|
||||
* @param data config from Nacos
|
||||
* @param extension file extension. json or xml or yml or yaml or properties
|
||||
* @return result of properties
|
||||
* @return result of LinkedHashMap
|
||||
* @throws IOException thrown if there is a problem parsing config.
|
||||
*/
|
||||
public Properties parseNacosData(String data, String extension) throws IOException {
|
||||
public Map<String, Object> parseNacosData(String data, String extension)
|
||||
throws IOException {
|
||||
if (null == parser) {
|
||||
parser = this.createParser();
|
||||
}
|
||||
|
@ -16,24 +16,49 @@
|
||||
|
||||
package com.alibaba.cloud.nacos.parser;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.Properties;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author zkz
|
||||
*/
|
||||
public class NacosDataPropertiesParser extends AbstractNacosDataParser {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(NacosDataPropertiesParser.class);
|
||||
|
||||
public NacosDataPropertiesParser() {
|
||||
super("properties");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Properties doParse(String data) throws IOException {
|
||||
Properties properties = new Properties();
|
||||
properties.load(new StringReader(data));
|
||||
return properties;
|
||||
protected Map<String, Object> doParse(String data) throws IOException {
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new StringReader(data))) {
|
||||
for (String line = reader.readLine(); line != null; line = reader
|
||||
.readLine()) {
|
||||
String dataLine = line.trim();
|
||||
if (StringUtils.isEmpty(dataLine) || dataLine.startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
int index = dataLine.indexOf("=");
|
||||
if (index == -1) {
|
||||
log.warn("the config data is invalid {}", dataLine);
|
||||
continue;
|
||||
}
|
||||
result.put(dataLine.substring(0, index), dataLine.substring(index + 1));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,9 +18,8 @@ package com.alibaba.cloud.nacos.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
@ -46,17 +45,17 @@ public class NacosDataXmlParser extends AbstractNacosDataParser {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Properties doParse(String data) throws IOException {
|
||||
protected Map<String, Object> doParse(String data) throws IOException {
|
||||
if (StringUtils.isEmpty(data)) {
|
||||
return null;
|
||||
}
|
||||
Map<String, Object> map = parseXml2Map(data);
|
||||
return this.generateProperties(this.reloadMap(map));
|
||||
return this.reloadMap(map);
|
||||
}
|
||||
|
||||
private Map<String, Object> parseXml2Map(String xml) throws IOException {
|
||||
xml = xml.replaceAll("\\r", "").replaceAll("\\n", "").replaceAll("\\t", "");
|
||||
Map<String, Object> map = new HashMap<>(32);
|
||||
Map<String, Object> map = new LinkedHashMap<>(32);
|
||||
try {
|
||||
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance()
|
||||
.newDocumentBuilder();
|
||||
|
@ -16,9 +16,10 @@
|
||||
|
||||
package com.alibaba.cloud.nacos.parser;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
|
||||
import org.springframework.beans.factory.config.YamlMapFactoryBean;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
|
||||
/**
|
||||
@ -31,10 +32,13 @@ public class NacosDataYamlParser extends AbstractNacosDataParser {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Properties doParse(String data) {
|
||||
YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
|
||||
protected Map<String, Object> doParse(String data) {
|
||||
YamlMapFactoryBean yamlFactory = new YamlMapFactoryBean();
|
||||
yamlFactory.setResources(new ByteArrayResource(data.getBytes()));
|
||||
return yamlFactory.getObject();
|
||||
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
flattenedMap(result, yamlFactory.getObject(), EMPTY_STRING);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user