This commit is contained in:
rushsky518 2019-08-16 17:11:24 +08:00
parent 1877e7d307
commit b29e8c089c
5 changed files with 97 additions and 43 deletions

View File

@ -50,12 +50,7 @@ public enum ConfigType {
/**
* config type is "yaml"
*/
YAML("yaml"),
/**
* config type is "yaml"
*/
YML("yml");
YAML("yaml");
String type;

View File

@ -18,7 +18,7 @@ package com.alibaba.nacos.client.config.impl;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.config.ConfigType;
import com.alibaba.nacos.api.config.listener.AbstractSharedListener;
import com.alibaba.nacos.client.config.listener.impl.ConfigChangeListener;
import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager;
@ -32,6 +32,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import static com.alibaba.nacos.client.config.impl.ConfigChangeEvent.*;
/**
* Listner Management
*
@ -192,14 +194,13 @@ public class CacheData {
String contentTmp = cr.getContent();
listener.receiveConfigInfo(contentTmp);
if (listener instanceof ConfigChangeListener) {
if (dataId.endsWith(ConfigType.YAML.getType()) || dataId.endsWith(ConfigType.YML.getType())
|| dataId.endsWith(ConfigType.PROPERTIES.getType())) {
// compare lastContent and content
ConfigChangeEvent event = new ConfigChangeEvent(dataId, lastContent, content);
((ConfigChangeListener)listener).receiveConfigChange(event);
}
if (listener instanceof AbstractConfigChangeListener &&
(dataId.endsWith(YAML_SUFFIX) || dataId.endsWith(YML_SUFFIX) || dataId.endsWith(PROPERTIES_SUFFIX))) {
// compare lastContent and content
ConfigChangeEvent event = new ConfigChangeEvent(dataId, lastContent, content);
((AbstractConfigChangeListener)listener).receiveConfigChange(event);
}
listenerWrap.lastCallMd5 = md5;
LOGGER.info("[{}] [notify-ok] dataId={}, group={}, md5={}, listener={} ", name, dataId, group, md5,
listener);

View File

@ -15,7 +15,7 @@
*/
package com.alibaba.nacos.client.config.impl;
import com.alibaba.nacos.api.config.ConfigType;
import com.alibaba.nacos.client.utils.StringUtils;
import org.yaml.snakeyaml.Yaml;
import java.io.IOException;
@ -30,7 +30,7 @@ import java.util.*;
public class ConfigChangeEvent {
private Map<String, ConfigChangeItem> result;
public ConfigChangeEvent(String dataId, String oldContent, String content) {
public ConfigChangeEvent(String dataId, String oldContent, String content) throws IOException {
init(dataId, oldContent, content);
}
@ -42,33 +42,41 @@ public class ConfigChangeEvent {
return result.values();
}
private void init(String dataId, String oldContent, String content) {
private void init(String dataId, String oldContent, String content) throws IOException {
result = new HashMap<String, ConfigChangeItem>(32);
if (dataId.endsWith(ConfigType.PROPERTIES.getType())) {
Properties oldProp = new Properties();
Properties newProp = new Properties();
try {
oldProp.load(new StringReader(oldContent));
newProp.load(new StringReader(content));
filterData(oldProp, newProp);
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataId.endsWith(PROPERTIES_SUFFIX)) {
Properties oldProps = new Properties();
Properties newProps = new Properties();
if (dataId.endsWith(ConfigType.YML.getType()) || dataId.endsWith(ConfigType.YAML.getType())) {
Yaml oldYaml = new Yaml();
Yaml newYaml = new Yaml();
Map<String, Object> oldMap = oldYaml.load(oldContent);
Map<String, Object> newMap = newYaml.load(content);
if (!StringUtils.isBlank(oldContent)) {
oldProps.load(new StringReader(oldContent));
}
if (!StringUtils.isBlank(content)) {
newProps.load(new StringReader(content));
}
filterData(oldProps, newProps);
} else if (dataId.endsWith(YML_SUFFIX) || dataId.endsWith(YAML_SUFFIX)) {
Map<String, Object> oldMap = Collections.emptyMap();
Map<String, Object> newMap = Collections.emptyMap();
if (!StringUtils.isBlank(oldContent)) {
oldMap = (new Yaml()).load(oldContent);
oldMap = getFlattenedMap(oldMap);
}
if (!StringUtils.isBlank(content)) {
newMap = (new Yaml()).load(content);
newMap = getFlattenedMap(newMap);
}
filterData(oldMap, newMap);
}
}
private void filterData(Map oldMap, Map newMap) {
for (Iterator<Map.Entry<String, Object>> entryItr = oldMap.entrySet().iterator(); entryItr.hasNext();) {
for (@SuppressWarnings("unchecked") Iterator<Map.Entry<String, Object>> entryItr =
oldMap.entrySet().iterator(); entryItr.hasNext();) {
Map.Entry<String, Object> e = entryItr.next();
ConfigChangeItem cci = null;
if (newMap.containsKey(e.getKey())) {
@ -85,7 +93,8 @@ public class ConfigChangeEvent {
result.put(e.getKey(), cci);
}
for (Iterator<Map.Entry<String, Object>> entryItr = newMap.entrySet().iterator(); entryItr.hasNext();) {
for (@SuppressWarnings("unchecked") Iterator<Map.Entry<String, Object>> entryItr =
newMap.entrySet().iterator(); entryItr.hasNext();) {
Map.Entry<String, Object> e = entryItr.next();
if (!oldMap.containsKey(e.getKey())) {
ConfigChangeItem cci = new ConfigChangeItem(e.getKey(), null, e.getValue().toString());
@ -95,5 +104,48 @@ public class ConfigChangeEvent {
}
}
private final Map<String, Object> getFlattenedMap(Map<String, Object> source) {
Map<String, Object> result = new LinkedHashMap<String, Object>(128);
buildFlattenedMap(result, source, null);
return result;
}
private void buildFlattenedMap(Map<String, Object> result, Map<String, Object> source, String path) {
for (Iterator<Map.Entry<String, Object>> itr = source.entrySet().iterator(); itr.hasNext(); ) {
Map.Entry<String, Object> e = itr.next();
String key = e.getKey();
if (StringUtils.isNotBlank(path)) {
if (e.getKey().startsWith("[")) {
key = path + key;
} else {
key = path + '.' + key;
}
}
if (e.getValue() instanceof String) {
result.put(key, e.getValue());
} else if (e.getValue() instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) e.getValue();
buildFlattenedMap(result, map, key);
} else if (e.getValue() instanceof Collection) {
@SuppressWarnings("unchecked")
Collection<Object> collection = (Collection<Object>) e.getValue();
if (collection.isEmpty()) {
result.put(key, "");
} else {
int count = 0;
for (Object object : collection) {
buildFlattenedMap(result, Collections.singletonMap("[" + (count++) + "]", object), key);
}
}
} else {
result.put(key, (e.getValue() != null ? e.getValue() : ""));
}
}
}
static final String PROPERTIES_SUFFIX = ".properties";
static final String YAML_SUFFIX = ".ymal";
static final String YML_SUFFIX = ".yml";
}

View File

@ -19,12 +19,11 @@ import com.alibaba.nacos.api.config.listener.AbstractListener;
import com.alibaba.nacos.client.config.impl.ConfigChangeEvent;
/**
* ConfigChangeListener
* AbstractConfigChangeListener
*
* @author rushsky518
*/
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
public abstract class ConfigChangeListener extends AbstractListener {
public abstract class AbstractConfigChangeListener extends AbstractListener {
/**
* handle config change
* @param event

View File

@ -15,14 +15,17 @@
*/
package com.alibaba.nacos.example;
import java.util.Properties;
import java.util.*;
import java.util.concurrent.locks.LockSupport;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.client.config.impl.ConfigChangeEvent;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.client.config.listener.impl.ConfigChangeListener;
import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener;
import com.alibaba.nacos.api.exception.NacosException;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.yaml.snakeyaml.Yaml;
/**
* Config service example
@ -33,14 +36,16 @@ public class ConfigExample {
public static void main(String[] args) throws NacosException, InterruptedException {
String serverAddr = "localhost";
String dataId = "redis.properties";
String group = "multi-data-ids";
String dataId = "zhang.yml";
String group = "DEFAULT_GROUP";
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
properties.put("namespace", "");
ConfigService configService = NacosFactory.createConfigService(properties);
String content = configService.getConfig(dataId, group, 5000);
System.out.println(content);
configService.addListener(dataId, group, new ConfigChangeListener() {
configService.addListener(dataId, group, new AbstractConfigChangeListener() {
@Override
public void receiveConfigChange(final ConfigChangeEvent event) {
@ -65,4 +70,6 @@ public class ConfigExample {
// Thread.sleep(300000);
}
}