fix nacos load data

pull/1179/head
yuhuangbin 5 years ago
parent 648944df09
commit 26741dc799

@ -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;
}
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;
}
key = key.startsWith(DOT) ? key.replaceFirst("\\.", "") : key;
properties.put(key, entry.getValue());
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…
Cancel
Save