From 192610b4c9ad941464e170d886c22e829f096980 Mon Sep 17 00:00:00 2001 From: rushsky518 Date: Thu, 1 Aug 2019 15:25:25 +0800 Subject: [PATCH 01/17] #1507 close server from current dir --- distribution/bin/shutdown.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/distribution/bin/shutdown.sh b/distribution/bin/shutdown.sh index cb64555b1..fbf7ad01e 100644 --- a/distribution/bin/shutdown.sh +++ b/distribution/bin/shutdown.sh @@ -13,7 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -pid=`ps ax | grep -i 'nacos.nacos' |grep java | grep -v grep | awk '{print $1}'` +cd `dirname $0`/../target +target_dir=`pwd` + +pid=`ps ax | grep -i 'nacos.nacos' | grep ${target_dir} | grep java | grep -v grep | awk '{print $1}'` if [ -z "$pid" ] ; then echo "No nacosServer running." exit -1; From 1877e7d30745febfa848bfa0b64663dfdcb836c2 Mon Sep 17 00:00:00 2001 From: rushsky518 Date: Thu, 15 Aug 2019 17:37:03 +0800 Subject: [PATCH 02/17] =?UTF-8?q?#1550=20=E6=B5=81=E7=A8=8B=E8=B0=83?= =?UTF-8?q?=E9=80=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alibaba/nacos/api/config/ConfigType.java | 7 +- client/pom.xml | 4 + .../nacos/client/config/impl/CacheData.java | 13 +++ .../client/config/impl/ConfigChangeEvent.java | 99 +++++++++++++++++++ .../client/config/impl/ConfigChangeItem.java | 85 ++++++++++++++++ .../listener/impl/ConfigChangeListener.java | 37 +++++++ .../src/main/resources/application.properties | 6 ++ .../alibaba/nacos/example/ConfigExample.java | 48 +++++---- 8 files changed, 273 insertions(+), 26 deletions(-) create mode 100644 client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java create mode 100644 client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeItem.java create mode 100644 client/src/main/java/com/alibaba/nacos/client/config/listener/impl/ConfigChangeListener.java diff --git a/api/src/main/java/com/alibaba/nacos/api/config/ConfigType.java b/api/src/main/java/com/alibaba/nacos/api/config/ConfigType.java index be063af83..354fcdb9b 100644 --- a/api/src/main/java/com/alibaba/nacos/api/config/ConfigType.java +++ b/api/src/main/java/com/alibaba/nacos/api/config/ConfigType.java @@ -50,7 +50,12 @@ public enum ConfigType { /** * config type is "yaml" */ - YAML("yaml"); + YAML("yaml"), + + /** + * config type is "yaml" + */ + YML("yml"); String type; diff --git a/client/pom.xml b/client/pom.xml index 30b7678cb..6689bde91 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -116,6 +116,10 @@ mockito-core test + + org.yaml + snakeyaml + diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java index fb86c0f6e..12a6c6833 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java @@ -16,7 +16,9 @@ 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.api.config.listener.Listener; import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager; @@ -60,6 +62,7 @@ public class CacheData { } public void setContent(String newContent) { + this.lastContent = this.content; this.content = newContent; this.md5 = getMd5String(content); } @@ -188,6 +191,15 @@ public class CacheData { configFilterChainManager.doFilter(null, cr); 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); + } + } listenerWrap.lastCallMd5 = md5; LOGGER.info("[{}] [notify-ok] dataId={}, group={}, md5={}, listener={} ", name, dataId, group, md5, listener); @@ -279,6 +291,7 @@ public class CacheData { * last modify time */ private volatile long localConfigLastModified; + private volatile String lastContent; private volatile String content; private int taskId; private volatile boolean isInitializing = true; diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java new file mode 100644 index 000000000..ab2b480f5 --- /dev/null +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java @@ -0,0 +1,99 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.nacos.client.config.impl; + +import com.alibaba.nacos.api.config.ConfigType; +import org.yaml.snakeyaml.Yaml; + +import java.io.IOException; +import java.io.StringReader; +import java.util.*; + +/** + * ConfigChangeEvent + * + * @author rushsky518 + */ +public class ConfigChangeEvent { + private Map result; + + public ConfigChangeEvent(String dataId, String oldContent, String content) { + init(dataId, oldContent, content); + } + + public ConfigChangeItem getChangeItem(String key) { + return result.get(key); + } + + public Collection getChangeItems() { + return result.values(); + } + + private void init(String dataId, String oldContent, String content) { + result = new HashMap(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(ConfigType.YML.getType()) || dataId.endsWith(ConfigType.YAML.getType())) { + Yaml oldYaml = new Yaml(); + Yaml newYaml = new Yaml(); + Map oldMap = oldYaml.load(oldContent); + Map newMap = newYaml.load(content); + + filterData(oldMap, newMap); + } + } + + private void filterData(Map oldMap, Map newMap) { + for (Iterator> entryItr = oldMap.entrySet().iterator(); entryItr.hasNext();) { + Map.Entry e = entryItr.next(); + ConfigChangeItem cci = null; + if (newMap.containsKey(e.getKey())) { + if (e.getValue().equals(newMap.get(e.getKey()))) { + continue; + } + cci = new ConfigChangeItem(e.getKey(), e.getValue().toString(), newMap.get(e.getKey()).toString()); + cci.setType(ConfigChangeItem.PropertyChangeType.MODIFIED); + } else { + cci = new ConfigChangeItem(e.getKey(), e.getValue().toString(), null); + cci.setType(ConfigChangeItem.PropertyChangeType.DELETED); + } + + result.put(e.getKey(), cci); + } + + for (Iterator> entryItr = newMap.entrySet().iterator(); entryItr.hasNext();) { + Map.Entry e = entryItr.next(); + if (!oldMap.containsKey(e.getKey())) { + ConfigChangeItem cci = new ConfigChangeItem(e.getKey(), null, e.getValue().toString()); + cci.setType(ConfigChangeItem.PropertyChangeType.ADDED); + result.put(e.getKey(), cci); + } + } + } + +} + diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeItem.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeItem.java new file mode 100644 index 000000000..27e6593b1 --- /dev/null +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeItem.java @@ -0,0 +1,85 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.nacos.client.config.impl; + +/** + * ConfigChangeItem + * + * @author rushsky518 + */ +public class ConfigChangeItem { + private String key; + private String oldValue; + private String newValue; + + private PropertyChangeType type; + public enum PropertyChangeType { + /** add */ + ADDED, + /** modified */ + MODIFIED, + /** deleted */ + DELETED + } + + public ConfigChangeItem(String key, String oldValue, String newValue) { + this.key = key; + this.oldValue = oldValue; + this.newValue = newValue; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getOldValue() { + return oldValue; + } + + public void setOldValue(String oldValue) { + this.oldValue = oldValue; + } + + public String getNewValue() { + return newValue; + } + + public void setNewValue(String newValue) { + this.newValue = newValue; + } + + public PropertyChangeType getType() { + return type; + } + + public void setType(PropertyChangeType type) { + this.type = type; + } + + @Override + public String toString() { + return "ConfigChangeItem{" + + "key='" + key + '\'' + + ", oldValue='" + oldValue + '\'' + + ", newValue='" + newValue + '\'' + + ", type=" + type + + '}'; + } +} diff --git a/client/src/main/java/com/alibaba/nacos/client/config/listener/impl/ConfigChangeListener.java b/client/src/main/java/com/alibaba/nacos/client/config/listener/impl/ConfigChangeListener.java new file mode 100644 index 000000000..13520515b --- /dev/null +++ b/client/src/main/java/com/alibaba/nacos/client/config/listener/impl/ConfigChangeListener.java @@ -0,0 +1,37 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.nacos.client.config.listener.impl; + +import com.alibaba.nacos.api.config.listener.AbstractListener; +import com.alibaba.nacos.client.config.impl.ConfigChangeEvent; + +/** + * ConfigChangeListener + * + * @author rushsky518 + */ +@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule") +public abstract class ConfigChangeListener extends AbstractListener { + /** + * handle config change + * @param event + */ + public abstract void receiveConfigChange(final ConfigChangeEvent event); + + @Override + public void receiveConfigInfo(final String configInfo) {} +} + diff --git a/console/src/main/resources/application.properties b/console/src/main/resources/application.properties index 64c42676e..4bdd41518 100644 --- a/console/src/main/resources/application.properties +++ b/console/src/main/resources/application.properties @@ -38,3 +38,9 @@ server.tomcat.basedir= #nacos.security.ignore.urls=/** nacos.security.ignore.urls=/,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/login,/v1/console/health/**,/v1/cs/**,/v1/ns/**,/v1/cmdb/**,/actuator/**,/v1/console/server/** + +spring.datasource.platform=mysql +db.num=1 +db.url.0=jdbc:mysql://localhost:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true +db.user=root +db.password=123456 diff --git a/example/src/main/java/com/alibaba/nacos/example/ConfigExample.java b/example/src/main/java/com/alibaba/nacos/example/ConfigExample.java index bf628d370..3c663a019 100644 --- a/example/src/main/java/com/alibaba/nacos/example/ConfigExample.java +++ b/example/src/main/java/com/alibaba/nacos/example/ConfigExample.java @@ -16,11 +16,12 @@ package com.alibaba.nacos.example; import java.util.Properties; -import java.util.concurrent.Executor; +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.api.config.listener.Listener; +import com.alibaba.nacos.client.config.listener.impl.ConfigChangeListener; import com.alibaba.nacos.api.exception.NacosException; /** @@ -32,39 +33,36 @@ public class ConfigExample { public static void main(String[] args) throws NacosException, InterruptedException { String serverAddr = "localhost"; - String dataId = "test"; - String group = "DEFAULT_GROUP"; + String dataId = "redis.properties"; + String group = "multi-data-ids"; Properties properties = new Properties(); properties.put("serverAddr", serverAddr); ConfigService configService = NacosFactory.createConfigService(properties); String content = configService.getConfig(dataId, group, 5000); System.out.println(content); - configService.addListener(dataId, group, new Listener() { - @Override - public void receiveConfigInfo(String configInfo) { - System.out.println("receive:" + configInfo); - } + configService.addListener(dataId, group, new ConfigChangeListener() { @Override - public Executor getExecutor() { - return null; + public void receiveConfigChange(final ConfigChangeEvent event) { + System.out.println(event.getChangeItems()); } }); - boolean isPublishOk = configService.publishConfig(dataId, group, "content"); - System.out.println(isPublishOk); - - Thread.sleep(3000); - content = configService.getConfig(dataId, group, 5000); - System.out.println(content); - - boolean isRemoveOk = configService.removeConfig(dataId, group); - System.out.println(isRemoveOk); - Thread.sleep(3000); - - content = configService.getConfig(dataId, group, 5000); - System.out.println(content); - Thread.sleep(300000); + LockSupport.park(); +// boolean isPublishOk = configService.publishConfig(dataId, group, "content"); +// System.out.println(isPublishOk); +// +// Thread.sleep(3000); +// content = configService.getConfig(dataId, group, 5000); +// System.out.println(content); +// +// boolean isRemoveOk = configService.removeConfig(dataId, group); +// System.out.println(isRemoveOk); +// Thread.sleep(3000); +// +// content = configService.getConfig(dataId, group, 5000); +// System.out.println(content); +// Thread.sleep(300000); } } From b29e8c089cb8bda9b116809f3afc6242475ef45d Mon Sep 17 00:00:00 2001 From: rushsky518 Date: Fri, 16 Aug 2019 17:11:24 +0800 Subject: [PATCH 03/17] =?UTF-8?q?#1550=20yaml=20=E5=B1=95=E5=B9=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alibaba/nacos/api/config/ConfigType.java | 7 +- .../nacos/client/config/impl/CacheData.java | 17 ++-- .../client/config/impl/ConfigChangeEvent.java | 94 ++++++++++++++----- ...java => AbstractConfigChangeListener.java} | 5 +- .../alibaba/nacos/example/ConfigExample.java | 17 +++- 5 files changed, 97 insertions(+), 43 deletions(-) rename client/src/main/java/com/alibaba/nacos/client/config/listener/impl/{ConfigChangeListener.java => AbstractConfigChangeListener.java} (86%) diff --git a/api/src/main/java/com/alibaba/nacos/api/config/ConfigType.java b/api/src/main/java/com/alibaba/nacos/api/config/ConfigType.java index 354fcdb9b..be063af83 100644 --- a/api/src/main/java/com/alibaba/nacos/api/config/ConfigType.java +++ b/api/src/main/java/com/alibaba/nacos/api/config/ConfigType.java @@ -50,12 +50,7 @@ public enum ConfigType { /** * config type is "yaml" */ - YAML("yaml"), - - /** - * config type is "yaml" - */ - YML("yml"); + YAML("yaml"); String type; diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java index 12a6c6833..9a46d76ae 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java @@ -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); diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java index ab2b480f5..a70e16a27 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java @@ -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 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(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 oldMap = oldYaml.load(oldContent); - Map 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 oldMap = Collections.emptyMap(); + Map 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> entryItr = oldMap.entrySet().iterator(); entryItr.hasNext();) { + for (@SuppressWarnings("unchecked") Iterator> entryItr = + oldMap.entrySet().iterator(); entryItr.hasNext();) { Map.Entry 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> entryItr = newMap.entrySet().iterator(); entryItr.hasNext();) { + for (@SuppressWarnings("unchecked") Iterator> entryItr = + newMap.entrySet().iterator(); entryItr.hasNext();) { Map.Entry 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 getFlattenedMap(Map source) { + Map result = new LinkedHashMap(128); + buildFlattenedMap(result, source, null); + return result; + } + + private void buildFlattenedMap(Map result, Map source, String path) { + for (Iterator> itr = source.entrySet().iterator(); itr.hasNext(); ) { + Map.Entry 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 map = (Map) e.getValue(); + buildFlattenedMap(result, map, key); + } else if (e.getValue() instanceof Collection) { + @SuppressWarnings("unchecked") + Collection collection = (Collection) 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"; } diff --git a/client/src/main/java/com/alibaba/nacos/client/config/listener/impl/ConfigChangeListener.java b/client/src/main/java/com/alibaba/nacos/client/config/listener/impl/AbstractConfigChangeListener.java similarity index 86% rename from client/src/main/java/com/alibaba/nacos/client/config/listener/impl/ConfigChangeListener.java rename to client/src/main/java/com/alibaba/nacos/client/config/listener/impl/AbstractConfigChangeListener.java index 13520515b..d456d4da0 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/listener/impl/ConfigChangeListener.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/listener/impl/AbstractConfigChangeListener.java @@ -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 diff --git a/example/src/main/java/com/alibaba/nacos/example/ConfigExample.java b/example/src/main/java/com/alibaba/nacos/example/ConfigExample.java index 3c663a019..86f5a3d1a 100644 --- a/example/src/main/java/com/alibaba/nacos/example/ConfigExample.java +++ b/example/src/main/java/com/alibaba/nacos/example/ConfigExample.java @@ -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); } + + } From 5174eac8d22ffbbcc57886be2b11034ce7cd40b7 Mon Sep 17 00:00:00 2001 From: rushsky518 Date: Fri, 16 Aug 2019 17:29:55 +0800 Subject: [PATCH 04/17] #1550 pmd check --- .../nacos/client/config/impl/CacheData.java | 3 +-- .../client/config/impl/ConfigChangeEvent.java | 6 ++---- .../com/alibaba/nacos/example/ConfigExample.java | 15 +++++++++++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java index 9a46d76ae..6bf4b5bd1 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java @@ -194,8 +194,7 @@ public class CacheData { String contentTmp = cr.getContent(); listener.receiveConfigInfo(contentTmp); - if (listener instanceof AbstractConfigChangeListener && - (dataId.endsWith(YAML_SUFFIX) || dataId.endsWith(YML_SUFFIX) || dataId.endsWith(PROPERTIES_SUFFIX))) { + if (listener instanceof AbstractConfigChangeListener) { // compare lastContent and content ConfigChangeEvent event = new ConfigChangeEvent(dataId, lastContent, content); ((AbstractConfigChangeListener)listener).receiveConfigChange(event); diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java index a70e16a27..ec0f25f5d 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java @@ -75,8 +75,7 @@ public class ConfigChangeEvent { } private void filterData(Map oldMap, Map newMap) { - for (@SuppressWarnings("unchecked") Iterator> entryItr = - oldMap.entrySet().iterator(); entryItr.hasNext();) { + for (Iterator> entryItr = oldMap.entrySet().iterator(); entryItr.hasNext();) { Map.Entry e = entryItr.next(); ConfigChangeItem cci = null; if (newMap.containsKey(e.getKey())) { @@ -93,8 +92,7 @@ public class ConfigChangeEvent { result.put(e.getKey(), cci); } - for (@SuppressWarnings("unchecked") Iterator> entryItr = - newMap.entrySet().iterator(); entryItr.hasNext();) { + for (Iterator> entryItr = newMap.entrySet().iterator(); entryItr.hasNext();) { Map.Entry e = entryItr.next(); if (!oldMap.containsKey(e.getKey())) { ConfigChangeItem cci = new ConfigChangeItem(e.getKey(), null, e.getValue().toString()); diff --git a/example/src/main/java/com/alibaba/nacos/example/ConfigExample.java b/example/src/main/java/com/alibaba/nacos/example/ConfigExample.java index 86f5a3d1a..0144be422 100644 --- a/example/src/main/java/com/alibaba/nacos/example/ConfigExample.java +++ b/example/src/main/java/com/alibaba/nacos/example/ConfigExample.java @@ -16,9 +16,11 @@ package com.alibaba.nacos.example; import java.util.*; +import java.util.concurrent.Executor; import java.util.concurrent.locks.LockSupport; import com.alibaba.nacos.api.NacosFactory; +import com.alibaba.nacos.api.config.listener.Listener; import com.alibaba.nacos.client.config.impl.ConfigChangeEvent; import com.alibaba.nacos.api.config.ConfigService; import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener; @@ -53,6 +55,19 @@ public class ConfigExample { } }); + configService.addListener(dataId, group, new Listener() { + + @Override + public Executor getExecutor() { + return null; + } + + @Override + public void receiveConfigInfo(String configInfo) { + System.out.println(configInfo); + } + }); + LockSupport.park(); // boolean isPublishOk = configService.publishConfig(dataId, group, "content"); // System.out.println(isPublishOk); From 01199aac69840e2eddecad9be7208e1ee0f46af3 Mon Sep 17 00:00:00 2001 From: rushsky518 Date: Mon, 19 Aug 2019 14:08:00 +0800 Subject: [PATCH 05/17] #1550 correct 'yaml' literal --- .../com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java index ec0f25f5d..1bc81d579 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java @@ -143,7 +143,7 @@ public class ConfigChangeEvent { } static final String PROPERTIES_SUFFIX = ".properties"; - static final String YAML_SUFFIX = ".ymal"; + static final String YAML_SUFFIX = ".yaml"; static final String YML_SUFFIX = ".yml"; } From f65e4bbade2fc4b3461f411fcf72c5fcca54ac7f Mon Sep 17 00:00:00 2001 From: rushsky518 Date: Mon, 19 Aug 2019 14:42:21 +0800 Subject: [PATCH 06/17] revert files --- .../src/main/resources/application.properties | 6 -- .../alibaba/nacos/example/ConfigExample.java | 62 +++++++------------ 2 files changed, 21 insertions(+), 47 deletions(-) diff --git a/console/src/main/resources/application.properties b/console/src/main/resources/application.properties index 4bdd41518..64c42676e 100644 --- a/console/src/main/resources/application.properties +++ b/console/src/main/resources/application.properties @@ -38,9 +38,3 @@ server.tomcat.basedir= #nacos.security.ignore.urls=/** nacos.security.ignore.urls=/,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/login,/v1/console/health/**,/v1/cs/**,/v1/ns/**,/v1/cmdb/**,/actuator/**,/v1/console/server/** - -spring.datasource.platform=mysql -db.num=1 -db.url.0=jdbc:mysql://localhost:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true -db.user=root -db.password=123456 diff --git a/example/src/main/java/com/alibaba/nacos/example/ConfigExample.java b/example/src/main/java/com/alibaba/nacos/example/ConfigExample.java index 0144be422..bf628d370 100644 --- a/example/src/main/java/com/alibaba/nacos/example/ConfigExample.java +++ b/example/src/main/java/com/alibaba/nacos/example/ConfigExample.java @@ -15,19 +15,13 @@ */ package com.alibaba.nacos.example; -import java.util.*; +import java.util.Properties; import java.util.concurrent.Executor; -import java.util.concurrent.locks.LockSupport; import com.alibaba.nacos.api.NacosFactory; -import com.alibaba.nacos.api.config.listener.Listener; -import com.alibaba.nacos.client.config.impl.ConfigChangeEvent; import com.alibaba.nacos.api.config.ConfigService; -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 org.springframework.lang.Nullable; -import org.springframework.util.StringUtils; -import org.yaml.snakeyaml.Yaml; /** * Config service example @@ -38,53 +32,39 @@ public class ConfigExample { public static void main(String[] args) throws NacosException, InterruptedException { String serverAddr = "localhost"; - String dataId = "zhang.yml"; + String dataId = "test"; 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 AbstractConfigChangeListener() { - - @Override - public void receiveConfigChange(final ConfigChangeEvent event) { - System.out.println(event.getChangeItems()); - } - }); - configService.addListener(dataId, group, new Listener() { + @Override + public void receiveConfigInfo(String configInfo) { + System.out.println("receive:" + configInfo); + } @Override public Executor getExecutor() { return null; } - - @Override - public void receiveConfigInfo(String configInfo) { - System.out.println(configInfo); - } }); - LockSupport.park(); -// boolean isPublishOk = configService.publishConfig(dataId, group, "content"); -// System.out.println(isPublishOk); -// -// Thread.sleep(3000); -// content = configService.getConfig(dataId, group, 5000); -// System.out.println(content); -// -// boolean isRemoveOk = configService.removeConfig(dataId, group); -// System.out.println(isRemoveOk); -// Thread.sleep(3000); -// -// content = configService.getConfig(dataId, group, 5000); -// System.out.println(content); -// Thread.sleep(300000); + boolean isPublishOk = configService.publishConfig(dataId, group, "content"); + System.out.println(isPublishOk); + + Thread.sleep(3000); + content = configService.getConfig(dataId, group, 5000); + System.out.println(content); + + boolean isRemoveOk = configService.removeConfig(dataId, group); + System.out.println(isRemoveOk); + Thread.sleep(3000); + + content = configService.getConfig(dataId, group, 5000); + System.out.println(content); + Thread.sleep(300000); } - - } From d6baf1dfcf9056f5bf7675fd508758b5820f08a7 Mon Sep 17 00:00:00 2001 From: rushsky518 Date: Mon, 19 Aug 2019 14:53:50 +0800 Subject: [PATCH 07/17] =?UTF-8?q?#1550=20=E5=8E=BB=E9=99=A4=E5=A4=9A?= =?UTF-8?q?=E4=BD=99=20import?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/alibaba/nacos/client/config/impl/CacheData.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java index 6bf4b5bd1..6e2a0af2f 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java @@ -16,13 +16,12 @@ 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.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; import com.alibaba.nacos.client.config.filter.impl.ConfigResponse; +import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener; import com.alibaba.nacos.client.config.utils.MD5; import com.alibaba.nacos.client.utils.LogUtils; import com.alibaba.nacos.client.utils.TenantUtil; @@ -32,8 +31,6 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -import static com.alibaba.nacos.client.config.impl.ConfigChangeEvent.*; - /** * Listner Management * From f3bd1473178859b943bdca1da787b69edaf14039 Mon Sep 17 00:00:00 2001 From: rushsky518 Date: Fri, 11 Oct 2019 19:58:42 +0800 Subject: [PATCH 08/17] #1550 nacos server return config type --- .../alibaba/nacos/api/common/Constants.java | 2 ++ .../client/config/NacosConfigService.java | 4 +-- .../nacos/client/config/impl/CacheData.java | 15 ++++++++--- .../client/config/impl/ClientWorker.java | 25 +++++++++++++------ .../client/config/impl/ConfigChangeEvent.java | 17 +++++++------ .../server/controller/ConfigServletInner.java | 4 +++ .../nacos/config/server/model/CacheItem.java | 9 +++++++ .../nacos/config/server/model/ConfigInfo.java | 10 ++++++++ .../config/server/service/ConfigService.java | 5 ++-- .../config/server/service/PersistService.java | 8 +++--- .../config/server/service/dump/DumpTask.java | 4 +-- 11 files changed, 75 insertions(+), 28 deletions(-) diff --git a/api/src/main/java/com/alibaba/nacos/api/common/Constants.java b/api/src/main/java/com/alibaba/nacos/api/common/Constants.java index e5d61a3fd..9776f1a16 100644 --- a/api/src/main/java/com/alibaba/nacos/api/common/Constants.java +++ b/api/src/main/java/com/alibaba/nacos/api/common/Constants.java @@ -62,6 +62,8 @@ public class Constants { public static final String CONFIG_VERSION = "Config-Version"; + public static final String CONFIG_TYPE = "Config-Type"; + public static final String IF_MODIFIED_SINCE = "If-Modified-Since"; public static final String SPACING_INTERVAL = "client-spacing-interval"; diff --git a/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java b/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java index a9ac0c9b9..1ff9901ea 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java @@ -170,9 +170,9 @@ public class NacosConfigService implements ConfigService { } try { - content = worker.getServerConfig(dataId, group, tenant, timeoutMs); + String[] ct = worker.getServerConfig(dataId, group, tenant, timeoutMs); - cr.setContent(content); + cr.setContent(ct[0]); configFilterChainManager.doFilter(null, cr); content = cr.getContent(); diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java index 6e2a0af2f..0505e96a3 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java @@ -66,6 +66,14 @@ public class CacheData { this.md5 = getMd5String(content); } + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + /** * Add listener * if CacheData already set new content, Listener should init lastCallMd5 by CacheData.md5 @@ -160,12 +168,12 @@ public class CacheData { void checkListenerMd5() { for (ManagerListenerWrap wrap : listeners) { if (!md5.equals(wrap.lastCallMd5)) { - safeNotifyListener(dataId, group, content, md5, wrap); + safeNotifyListener(dataId, group, content, type, md5, wrap); } } } - private void safeNotifyListener(final String dataId, final String group, final String content, + private void safeNotifyListener(final String dataId, final String group, final String content, final String type, final String md5, final ManagerListenerWrap listenerWrap) { final Listener listener = listenerWrap.listener; @@ -193,7 +201,7 @@ public class CacheData { if (listener instanceof AbstractConfigChangeListener) { // compare lastContent and content - ConfigChangeEvent event = new ConfigChangeEvent(dataId, lastContent, content); + ConfigChangeEvent event = new ConfigChangeEvent(dataId, lastContent, content, type); ((AbstractConfigChangeListener)listener).receiveConfigChange(event); } @@ -292,6 +300,7 @@ public class CacheData { private volatile String content; private int taskId; private volatile boolean isInitializing = true; + private String type; } class ManagerListenerWrap { diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java index 4e89dcbdf..50b764b0a 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java @@ -53,6 +53,7 @@ import java.util.concurrent.atomic.AtomicReference; import static com.alibaba.nacos.api.common.Constants.LINE_SEPARATOR; import static com.alibaba.nacos.api.common.Constants.WORD_SEPARATOR; +import static com.alibaba.nacos.api.common.Constants.CONFIG_TYPE; /** * Longpolling @@ -190,8 +191,8 @@ public class ClientWorker { cache = new CacheData(configFilterChainManager, agent.getName(), dataId, group, tenant); // fix issue # 1317 if (enableRemoteSyncConfig) { - String content = getServerConfig(dataId, group, tenant, 3000L); - cache.setContent(content); + String[] ct = getServerConfig(dataId, group, tenant, 3000L); + cache.setContent(ct[0]); } } @@ -217,8 +218,9 @@ public class ClientWorker { return cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant)); } - public String getServerConfig(String dataId, String group, String tenant, long readTimeout) + public String[] getServerConfig(String dataId, String group, String tenant, long readTimeout) throws NacosException { + String[] ct = new String[2]; if (StringUtils.isBlank(group)) { group = Constants.DEFAULT_GROUP; } @@ -243,7 +245,11 @@ public class ClientWorker { switch (result.code) { case HttpURLConnection.HTTP_OK: LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, result.content); - return result.content; + ct[0] = result.content; + if (result.headers.containsKey(CONFIG_TYPE)) { + ct[1] = result.headers.get(CONFIG_TYPE).get(0); + } + return ct; case HttpURLConnection.HTTP_NOT_FOUND: LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, null); return null; @@ -520,12 +526,15 @@ public class ClientWorker { tenant = key[2]; } try { - String content = getServerConfig(dataId, group, tenant, 3000L); + String[] ct = getServerConfig(dataId, group, tenant, 3000L); CacheData cache = cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant)); - cache.setContent(content); - LOGGER.info("[{}] [data-received] dataId={}, group={}, tenant={}, md5={}, content={}", + cache.setContent(ct[0]); + if (null != ct[1]) { + cache.setType(ct[1]); + } + LOGGER.info("[{}] [data-received] dataId={}, group={}, tenant={}, md5={}, content={}, type={}", agent.getName(), dataId, group, tenant, cache.getMd5(), - ContentUtils.truncateContent(content)); + ContentUtils.truncateContent(ct[0]), ct[1]); } catch (NacosException ioe) { String message = String.format( "[%s] [get-update] get changed config exception. dataId=%s, group=%s, tenant=%s", diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java index 1bc81d579..23bbea956 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java @@ -30,8 +30,8 @@ import java.util.*; public class ConfigChangeEvent { private Map result; - public ConfigChangeEvent(String dataId, String oldContent, String content) throws IOException { - init(dataId, oldContent, content); + public ConfigChangeEvent(String dataId, String oldContent, String content, String type) throws IOException { + init(dataId, oldContent, content, type); } public ConfigChangeItem getChangeItem(String key) { @@ -42,10 +42,10 @@ public class ConfigChangeEvent { return result.values(); } - private void init(String dataId, String oldContent, String content) throws IOException { + private void init(String dataId, String oldContent, String content, String type) throws IOException { result = new HashMap(32); - if (dataId.endsWith(PROPERTIES_SUFFIX)) { + if (dataId.endsWith(PROPERTIES_SUFFIX) || PROPERTIES_SUFFIX.equalsIgnoreCase(type)) { Properties oldProps = new Properties(); Properties newProps = new Properties(); @@ -57,7 +57,8 @@ public class ConfigChangeEvent { } filterData(oldProps, newProps); - } else if (dataId.endsWith(YML_SUFFIX) || dataId.endsWith(YAML_SUFFIX)) { + } else if (dataId.endsWith(YML_SUFFIX) || dataId.endsWith(YAML_SUFFIX) + || YAML_SUFFIX.equalsIgnoreCase(type)) { Map oldMap = Collections.emptyMap(); Map newMap = Collections.emptyMap(); @@ -142,8 +143,8 @@ public class ConfigChangeEvent { } } - static final String PROPERTIES_SUFFIX = ".properties"; - static final String YAML_SUFFIX = ".yaml"; - static final String YML_SUFFIX = ".yml"; + static final String PROPERTIES_SUFFIX = "properties"; + static final String YAML_SUFFIX = "yaml"; + static final String YML_SUFFIX = "yml"; } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigServletInner.java b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigServletInner.java index 62e396a04..3ae982e40 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigServletInner.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigServletInner.java @@ -130,6 +130,10 @@ public class ConfigServletInner { isBeta = true; } } + String configType = cacheItem.getType(); + if (null != configType) { + response.setHeader("Config-Type", configType); + } } File file = null; ConfigInfoBase configInfoBase = null; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/CacheItem.java b/config/src/main/java/com/alibaba/nacos/config/server/model/CacheItem.java index 0258a89ac..0be7eb881 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/CacheItem.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/CacheItem.java @@ -109,6 +109,14 @@ public class CacheItem { this.tagLastModifiedTs = tagLastModifiedTs; } + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + final String groupKey; public volatile String md5 = Constants.NULL; public volatile long lastModifiedTs; @@ -123,5 +131,6 @@ public class CacheItem { public volatile Map tagMd5; public volatile Map tagLastModifiedTs; public SimpleReadWriteLock rwLock = new SimpleReadWriteLock(); + public String type; } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfo.java b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfo.java index be0d2de0d..218290070 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfo.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfo.java @@ -28,6 +28,8 @@ public class ConfigInfo extends ConfigInfoBase { private String appName; + private String type; + public ConfigInfo() { } @@ -63,6 +65,14 @@ public class ConfigInfo extends ConfigInfoBase { this.appName = appName; } + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + @Override public int hashCode() { return super.hashCode(); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigService.java index 83983f6d5..62c79028c 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigService.java @@ -57,9 +57,10 @@ public class ConfigService { /** * 保存配置文件,并缓存md5. */ - static public boolean dump(String dataId, String group, String tenant, String content, long lastModifiedTs) { + static public boolean dump(String dataId, String group, String tenant, String content, long lastModifiedTs, String type) { String groupKey = GroupKey2.getKey(dataId, group, tenant); - makeSure(groupKey); + CacheItem ci = makeSure(groupKey); + ci.setType(type); final int lockResult = tryWriteLock(groupKey); assert (lockResult != 0); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/PersistService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/PersistService.java index 04e8bea17..d3b78c4ca 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/PersistService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/PersistService.java @@ -113,6 +113,7 @@ public class PersistService { info.setGroup(rs.getString("group_id")); info.setTenant(rs.getString("tenant_id")); info.setAppName(rs.getString("app_name")); + info.setType(rs.getString("type")); try { info.setContent(rs.getString("content")); @@ -219,6 +220,7 @@ public class PersistService { info.setGroup(rs.getString("group_id")); info.setTenant(rs.getString("tenant_id")); info.setAppName(rs.getString("app_name")); + info.setType(rs.getString("type")); try { info.setContent(rs.getString("content")); @@ -1325,7 +1327,7 @@ public class PersistService { final String appName = configAdvanceInfo == null ? null : (String)configAdvanceInfo.get("appName"); final String configTags = configAdvanceInfo == null ? null : (String)configAdvanceInfo.get("config_tags"); String sqlCount = "select count(*) from config_info"; - String sql = "select ID,data_id,group_id,tenant_id,app_name,content from config_info"; + String sql = "select ID,data_id,group_id,tenant_id,app_name,content,type from config_info"; StringBuilder where = new StringBuilder(" where "); List paramList = new ArrayList(); paramList.add(tenantTmp); @@ -1944,7 +1946,7 @@ public class PersistService { public Page findAllConfigInfoFragment(final long lastMaxId, final int pageSize) { String select - = "SELECT id,data_id,group_id,tenant_id,app_name,content,md5,gmt_modified from config_info where id > ? " + = "SELECT id,data_id,group_id,tenant_id,app_name,content,md5,gmt_modified,type from config_info where id > ? " + "order by id asc limit ?,?"; PaginationHelper helper = new PaginationHelper(); try { @@ -2927,7 +2929,7 @@ public class PersistService { final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; try { return this.jt.queryForObject( - "SELECT ID,data_id,group_id,tenant_id,app_name,content,md5 FROM config_info WHERE data_id=? AND group_id=? AND tenant_id=?", + "SELECT ID,data_id,group_id,tenant_id,app_name,content,md5,type FROM config_info WHERE data_id=? AND group_id=? AND tenant_id=?", new Object[] {dataId, group, tenantTmp}, CONFIG_INFO_ROW_MAPPER); } catch (EmptyResultDataAccessException e) { // 表明数据不存在, 返回null return null; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpTask.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpTask.java index 2c93dacb1..513e9f6f1 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpTask.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpTask.java @@ -187,7 +187,7 @@ class DumpProcessor implements TaskProcessor { boolean result; if (null != cf) { - result = ConfigService.dump(dataId, group, tenant, cf.getContent(), lastModified); + result = ConfigService.dump(dataId, group, tenant, cf.getContent(), lastModified, cf.getType()); if (result) { ConfigTraceService.logDumpEvent(dataId, group, tenant, null, lastModified, handleIp, @@ -261,7 +261,7 @@ class DumpAllProcessor implements TaskProcessor { } boolean result = ConfigService.dump(cf.getDataId(), cf.getGroup(), cf.getTenant(), cf.getContent(), - cf.getLastModified()); + cf.getLastModified(), cf.getType()); final String content = cf.getContent(); final String md5 = MD5.getInstance().getMD5String(content); From 5a583f1997cfd2ef68c7cfd789a725b9549c28e3 Mon Sep 17 00:00:00 2001 From: rushsky518 Date: Tue, 5 Nov 2019 11:44:30 +0800 Subject: [PATCH 09/17] #1550 clean code --- .../impl/AbstractConfigChangeParser.java | 104 +++++++++++++++ .../nacos/client/config/impl/CacheData.java | 6 +- .../client/config/impl/ConfigChangeEvent.java | 122 +----------------- .../config/impl/ConfigChangeHander.java | 41 ++++++ .../config/impl/PropertiesChangeParser.java | 50 +++++++ .../client/config/impl/YmlChangeParser.java | 91 +++++++++++++ 6 files changed, 297 insertions(+), 117 deletions(-) create mode 100644 client/src/main/java/com/alibaba/nacos/client/config/impl/AbstractConfigChangeParser.java create mode 100644 client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHander.java create mode 100644 client/src/main/java/com/alibaba/nacos/client/config/impl/PropertiesChangeParser.java create mode 100644 client/src/main/java/com/alibaba/nacos/client/config/impl/YmlChangeParser.java diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/AbstractConfigChangeParser.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/AbstractConfigChangeParser.java new file mode 100644 index 000000000..1447c83a2 --- /dev/null +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/AbstractConfigChangeParser.java @@ -0,0 +1,104 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.nacos.client.config.impl; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * AbstractConfigChangeParser + * + * @author rushsky518 + */ +public abstract class AbstractConfigChangeParser { + private String configType; + + private AbstractConfigChangeParser next; + + public AbstractConfigChangeParser(String configType) { + this.configType = configType; + } + + public AbstractConfigChangeParser addNext(AbstractConfigChangeParser configChangeParser) { + if (null == this.next) { + this.next = configChangeParser; + } else { + this.next.addNext(configChangeParser); + } + return this; + } + + protected boolean isResponsibleFor(String type) { + return this.configType.equalsIgnoreCase(type); + } + + public Map parseChangeData(String oldContent, String newContent, String type) throws IOException { + if (isResponsibleFor(type)) { + return this.doParse(oldContent, newContent, type); + } + + if (null != this.next) { + return this.next.parseChangeData(oldContent, newContent, type); + } + + return Collections.emptyMap(); + } + + /** + * parse and compare config data + * @param oldContent + * @param newContent + * @param type + * @return + * @throws IOException + */ + protected abstract Map doParse(String oldContent, String newContent, String type) throws IOException; + + protected Map filterChangeData(Map oldMap, Map newMap) { + Map result = new HashMap(16); + for (Iterator> entryItr = oldMap.entrySet().iterator(); entryItr.hasNext();) { + Map.Entry e = entryItr.next(); + ConfigChangeItem cci = null; + if (newMap.containsKey(e.getKey())) { + if (e.getValue().equals(newMap.get(e.getKey()))) { + continue; + } + cci = new ConfigChangeItem(e.getKey(), e.getValue().toString(), newMap.get(e.getKey()).toString()); + cci.setType(ConfigChangeItem.PropertyChangeType.MODIFIED); + } else { + cci = new ConfigChangeItem(e.getKey(), e.getValue().toString(), null); + cci.setType(ConfigChangeItem.PropertyChangeType.DELETED); + } + + result.put(e.getKey(), cci); + } + + for (Iterator> entryItr = newMap.entrySet().iterator(); entryItr.hasNext();) { + Map.Entry e = entryItr.next(); + if (!oldMap.containsKey(e.getKey())) { + ConfigChangeItem cci = new ConfigChangeItem(e.getKey(), null, e.getValue().toString()); + cci.setType(ConfigChangeItem.PropertyChangeType.ADDED); + result.put(e.getKey(), cci); + } + } + + return result; + } + +} diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java index 0505e96a3..face08b39 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java @@ -29,6 +29,7 @@ import org.slf4j.Logger; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; /** @@ -199,9 +200,10 @@ public class CacheData { String contentTmp = cr.getContent(); listener.receiveConfigInfo(contentTmp); + // compare lastContent and content if (listener instanceof AbstractConfigChangeListener) { - // compare lastContent and content - ConfigChangeEvent event = new ConfigChangeEvent(dataId, lastContent, content, type); + Map data = ConfigChangeHander.getChangeParserInstance().parseChangeData(lastContent, content, type); + ConfigChangeEvent event = new ConfigChangeEvent(data); ((AbstractConfigChangeListener)listener).receiveConfigChange(event); } diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java index 23bbea956..172056daf 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java @@ -15,12 +15,8 @@ */ package com.alibaba.nacos.client.config.impl; -import com.alibaba.nacos.client.utils.StringUtils; -import org.yaml.snakeyaml.Yaml; - -import java.io.IOException; -import java.io.StringReader; -import java.util.*; +import java.util.Collection; +import java.util.Map; /** * ConfigChangeEvent @@ -28,123 +24,19 @@ import java.util.*; * @author rushsky518 */ public class ConfigChangeEvent { - private Map result; + private Map data; - public ConfigChangeEvent(String dataId, String oldContent, String content, String type) throws IOException { - init(dataId, oldContent, content, type); + public ConfigChangeEvent(Map data) { + this.data = data; } public ConfigChangeItem getChangeItem(String key) { - return result.get(key); + return data.get(key); } public Collection getChangeItems() { - return result.values(); + return data.values(); } - private void init(String dataId, String oldContent, String content, String type) throws IOException { - result = new HashMap(32); - - if (dataId.endsWith(PROPERTIES_SUFFIX) || PROPERTIES_SUFFIX.equalsIgnoreCase(type)) { - Properties oldProps = new Properties(); - Properties newProps = new Properties(); - - 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) - || YAML_SUFFIX.equalsIgnoreCase(type)) { - Map oldMap = Collections.emptyMap(); - Map 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> entryItr = oldMap.entrySet().iterator(); entryItr.hasNext();) { - Map.Entry e = entryItr.next(); - ConfigChangeItem cci = null; - if (newMap.containsKey(e.getKey())) { - if (e.getValue().equals(newMap.get(e.getKey()))) { - continue; - } - cci = new ConfigChangeItem(e.getKey(), e.getValue().toString(), newMap.get(e.getKey()).toString()); - cci.setType(ConfigChangeItem.PropertyChangeType.MODIFIED); - } else { - cci = new ConfigChangeItem(e.getKey(), e.getValue().toString(), null); - cci.setType(ConfigChangeItem.PropertyChangeType.DELETED); - } - - result.put(e.getKey(), cci); - } - - for (Iterator> entryItr = newMap.entrySet().iterator(); entryItr.hasNext();) { - Map.Entry e = entryItr.next(); - if (!oldMap.containsKey(e.getKey())) { - ConfigChangeItem cci = new ConfigChangeItem(e.getKey(), null, e.getValue().toString()); - cci.setType(ConfigChangeItem.PropertyChangeType.ADDED); - result.put(e.getKey(), cci); - } - } - } - - private final Map getFlattenedMap(Map source) { - Map result = new LinkedHashMap(128); - buildFlattenedMap(result, source, null); - return result; - } - - private void buildFlattenedMap(Map result, Map source, String path) { - for (Iterator> itr = source.entrySet().iterator(); itr.hasNext(); ) { - Map.Entry 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 map = (Map) e.getValue(); - buildFlattenedMap(result, map, key); - } else if (e.getValue() instanceof Collection) { - @SuppressWarnings("unchecked") - Collection collection = (Collection) 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 = "yaml"; - static final String YML_SUFFIX = "yml"; } diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHander.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHander.java new file mode 100644 index 000000000..95944a9e1 --- /dev/null +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHander.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package com.alibaba.nacos.client.config.impl; + +/** + * ConfigChangeHander + * + * @author za-zhangzejiang + * @version v0.1 2019-11-04 15:39 za-zhangzejiang Exp $ + */ +public class ConfigChangeHander { + private ConfigChangeHander() { + this.configChangeParser = new PropertiesChangeParser("properties").addNext(new YmlChangeParser("yaml")); + } + + public static ConfigChangeHander getInstance() { + return ConfigChangeHanderHolder.INSTANCE; + } + + public static AbstractConfigChangeParser getChangeParserInstance() { + return ConfigChangeHanderHolder.INSTANCE.configChangeParser; + } + + private static class ConfigChangeHanderHolder { + private final static ConfigChangeHander INSTANCE = new ConfigChangeHander(); + } + + private AbstractConfigChangeParser configChangeParser; + +} + diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/PropertiesChangeParser.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/PropertiesChangeParser.java new file mode 100644 index 000000000..5f56bd67b --- /dev/null +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/PropertiesChangeParser.java @@ -0,0 +1,50 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.nacos.client.config.impl; + +import com.alibaba.nacos.client.utils.StringUtils; + +import java.io.IOException; +import java.io.StringReader; +import java.util.Map; +import java.util.Properties; + +/** + * PropertiesChangeParser + * + * @author rushsky518 + */ +public class PropertiesChangeParser extends AbstractConfigChangeParser { + + public PropertiesChangeParser(String configType) { + super(configType); + } + + @Override + protected Map doParse(String oldContent, String newContent, String type) throws IOException { + Properties oldProps = new Properties(); + Properties newProps = new Properties(); + + if (StringUtils.isNotBlank(oldContent)) { + oldProps.load(new StringReader(oldContent)); + } + if (StringUtils.isNotBlank(newContent)) { + newProps.load(new StringReader(newContent)); + } + + return filterChangeData(oldProps, newProps); + } +} diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/YmlChangeParser.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/YmlChangeParser.java new file mode 100644 index 000000000..7f361d40c --- /dev/null +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/YmlChangeParser.java @@ -0,0 +1,91 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.nacos.client.config.impl; + +import com.alibaba.nacos.client.utils.StringUtils; +import org.yaml.snakeyaml.Yaml; +import java.util.*; + +/** + * YmlChangeParser + * + * @author rushsky518 + */ +public class YmlChangeParser extends AbstractConfigChangeParser { + + public YmlChangeParser(String configType) { + super(configType); + } + + @Override + protected Map doParse(String oldContent, String newContent, String type) { + Map oldMap = Collections.emptyMap(); + Map newMap = Collections.emptyMap(); + + if (StringUtils.isNotBlank(oldContent)) { + oldMap = (new Yaml()).load(oldContent); + oldMap = getFlattenedMap(oldMap); + } + if (StringUtils.isNotBlank(newContent)) { + newMap = (new Yaml()).load(newContent); + newMap = getFlattenedMap(newMap); + } + + return filterChangeData(oldMap, newMap); + } + + private final Map getFlattenedMap(Map source) { + Map result = new LinkedHashMap(128); + buildFlattenedMap(result, source, null); + return result; + } + + private void buildFlattenedMap(Map result, Map source, String path) { + for (Iterator> itr = source.entrySet().iterator(); itr.hasNext(); ) { + Map.Entry 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 map = (Map) e.getValue(); + buildFlattenedMap(result, map, key); + } else if (e.getValue() instanceof Collection) { + @SuppressWarnings("unchecked") + Collection collection = (Collection) 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() : "")); + } + } + } + +} + From 98d35d24200bfb1d0a89ef8b529591d654fde605 Mon Sep 17 00:00:00 2001 From: rushsky518 Date: Tue, 5 Nov 2019 13:41:05 +0800 Subject: [PATCH 10/17] correct word spell --- .../nacos/client/config/impl/CacheData.java | 2 +- .../config/impl/ConfigChangeHander.java | 41 ------------------ .../config/impl/ConfigChangeHandler.java | 42 +++++++++++++++++++ 3 files changed, 43 insertions(+), 42 deletions(-) delete mode 100644 client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHander.java create mode 100644 client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHandler.java diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java index face08b39..73a123ad1 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java @@ -202,7 +202,7 @@ public class CacheData { // compare lastContent and content if (listener instanceof AbstractConfigChangeListener) { - Map data = ConfigChangeHander.getChangeParserInstance().parseChangeData(lastContent, content, type); + Map data = ConfigChangeHandler.getChangeParserInstance().parseChangeData(lastContent, content, type); ConfigChangeEvent event = new ConfigChangeEvent(data); ((AbstractConfigChangeListener)listener).receiveConfigChange(event); } diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHander.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHander.java deleted file mode 100644 index 95944a9e1..000000000 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHander.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE - * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file - * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.alibaba.nacos.client.config.impl; - -/** - * ConfigChangeHander - * - * @author za-zhangzejiang - * @version v0.1 2019-11-04 15:39 za-zhangzejiang Exp $ - */ -public class ConfigChangeHander { - private ConfigChangeHander() { - this.configChangeParser = new PropertiesChangeParser("properties").addNext(new YmlChangeParser("yaml")); - } - - public static ConfigChangeHander getInstance() { - return ConfigChangeHanderHolder.INSTANCE; - } - - public static AbstractConfigChangeParser getChangeParserInstance() { - return ConfigChangeHanderHolder.INSTANCE.configChangeParser; - } - - private static class ConfigChangeHanderHolder { - private final static ConfigChangeHander INSTANCE = new ConfigChangeHander(); - } - - private AbstractConfigChangeParser configChangeParser; - -} - diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHandler.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHandler.java new file mode 100644 index 000000000..1f7de1e81 --- /dev/null +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHandler.java @@ -0,0 +1,42 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.nacos.client.config.impl; + +/** + * ConfigChangeHandler + * + * @author rushsky518 + */ +public class ConfigChangeHandler { + private ConfigChangeHandler() { + this.configChangeParser = new PropertiesChangeParser("properties").addNext(new YmlChangeParser("yaml")); + } + + public static ConfigChangeHandler getInstance() { + return ConfigChangeHandlerHolder.INSTANCE; + } + + public static AbstractConfigChangeParser getChangeParserInstance() { + return ConfigChangeHandlerHolder.INSTANCE.configChangeParser; + } + + private static class ConfigChangeHandlerHolder { + private final static ConfigChangeHandler INSTANCE = new ConfigChangeHandler(); + } + + private AbstractConfigChangeParser configChangeParser; + +} From 64b6dbe9cb64723306087dad229770a5054065c7 Mon Sep 17 00:00:00 2001 From: rushsky518 Date: Fri, 22 Nov 2019 14:43:30 +0800 Subject: [PATCH 11/17] =?UTF-8?q?#1550=20=E6=8A=8A=20lastContent=20?= =?UTF-8?q?=E6=94=BE=E5=85=A5=20listener=20=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nacos/client/config/impl/CacheData.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java index 73a123ad1..9ada4ba63 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java @@ -61,10 +61,9 @@ public class CacheData { return content; } - public void setContent(String newContent) { - this.lastContent = this.content; - this.content = newContent; - this.md5 = getMd5String(content); + public void setContent(String content) { + this.content = content; + this.md5 = getMd5String(this.content); } public String getType() { @@ -85,7 +84,7 @@ public class CacheData { if (null == listener) { throw new IllegalArgumentException("listener is null"); } - ManagerListenerWrap wrap = new ManagerListenerWrap(listener, md5); + ManagerListenerWrap wrap = new ManagerListenerWrap(listener, md5, content); if (listeners.addIfAbsent(wrap)) { LOGGER.info("[{}] [add-listener] ok, tenant={}, dataId={}, group={}, cnt={}", name, tenant, dataId, group, listeners.size()); @@ -202,12 +201,13 @@ public class CacheData { // compare lastContent and content if (listener instanceof AbstractConfigChangeListener) { - Map data = ConfigChangeHandler.getChangeParserInstance().parseChangeData(lastContent, content, type); + Map data = ConfigChangeHandler.getChangeParserInstance().parseChangeData(listenerWrap.lastContent, content, type); ConfigChangeEvent event = new ConfigChangeEvent(data); ((AbstractConfigChangeListener)listener).receiveConfigChange(event); } listenerWrap.lastCallMd5 = md5; + listenerWrap.lastContent = content; LOGGER.info("[{}] [notify-ok] dataId={}, group={}, md5={}, listener={} ", name, dataId, group, md5, listener); } catch (NacosException de) { @@ -298,7 +298,6 @@ public class CacheData { * last modify time */ private volatile long localConfigLastModified; - private volatile String lastContent; private volatile String content; private int taskId; private volatile boolean isInitializing = true; @@ -308,14 +307,16 @@ public class CacheData { class ManagerListenerWrap { final Listener listener; String lastCallMd5 = CacheData.getMd5String(null); + String lastContent = null; ManagerListenerWrap(Listener listener) { this.listener = listener; } - ManagerListenerWrap(Listener listener, String md5) { + ManagerListenerWrap(Listener listener, String md5, String lastContent) { this.listener = listener; this.lastCallMd5 = md5; + this.lastContent = lastContent; } @Override From f535ab984632ccf22dfe7a5b9e14127341a926d7 Mon Sep 17 00:00:00 2001 From: rushsky518 Date: Sun, 24 Nov 2019 16:53:06 +0800 Subject: [PATCH 12/17] =?UTF-8?q?#1550=20=E6=99=AE=E9=80=9A=20listener=20?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E4=B8=8D=E4=BF=9D=E5=AD=98=20lastContent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alibaba/nacos/client/config/impl/CacheData.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java index 9ada4ba63..23953cb47 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java @@ -84,7 +84,9 @@ public class CacheData { if (null == listener) { throw new IllegalArgumentException("listener is null"); } - ManagerListenerWrap wrap = new ManagerListenerWrap(listener, md5, content); + ManagerListenerWrap wrap = (listener instanceof AbstractConfigChangeListener) ? + new ManagerListenerWrap(listener, md5, content) : new ManagerListenerWrap(listener, md5); + if (listeners.addIfAbsent(wrap)) { LOGGER.info("[{}] [add-listener] ok, tenant={}, dataId={}, group={}, cnt={}", name, tenant, dataId, group, listeners.size()); @@ -204,10 +206,10 @@ public class CacheData { Map data = ConfigChangeHandler.getChangeParserInstance().parseChangeData(listenerWrap.lastContent, content, type); ConfigChangeEvent event = new ConfigChangeEvent(data); ((AbstractConfigChangeListener)listener).receiveConfigChange(event); + listenerWrap.lastContent = content; } listenerWrap.lastCallMd5 = md5; - listenerWrap.lastContent = content; LOGGER.info("[{}] [notify-ok] dataId={}, group={}, md5={}, listener={} ", name, dataId, group, md5, listener); } catch (NacosException de) { @@ -313,6 +315,11 @@ class ManagerListenerWrap { this.listener = listener; } + ManagerListenerWrap(Listener listener, String md5) { + this.listener = listener; + this.lastCallMd5 = md5; + } + ManagerListenerWrap(Listener listener, String md5, String lastContent) { this.listener = listener; this.lastCallMd5 = md5; From 93773c47d6c91085fd54da6f7b71fc5b72efc126 Mon Sep 17 00:00:00 2001 From: rushsky518 Date: Tue, 26 Nov 2019 21:35:05 +0800 Subject: [PATCH 13/17] =?UTF-8?q?#1550=20=E6=8A=BD=E8=B1=A1=E5=87=BA=20spi?= =?UTF-8?q?=20=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/listener/ConfigChangeParser.java | 43 +++++++++++++++++++ .../impl/AbstractConfigChangeParser.java | 42 +++--------------- .../nacos/client/config/impl/CacheData.java | 2 +- .../client/config/impl/ClientWorker.java | 3 ++ .../config/impl/ConfigChangeHandler.java | 39 +++++++++++++---- .../config/impl/PropertiesChangeParser.java | 7 ++- .../client/config/impl/YmlChangeParser.java | 8 ++-- .../server/controller/ConfigServletInner.java | 4 +- 8 files changed, 90 insertions(+), 58 deletions(-) create mode 100644 api/src/main/java/com/alibaba/nacos/api/config/listener/ConfigChangeParser.java diff --git a/api/src/main/java/com/alibaba/nacos/api/config/listener/ConfigChangeParser.java b/api/src/main/java/com/alibaba/nacos/api/config/listener/ConfigChangeParser.java new file mode 100644 index 000000000..9a6f053c0 --- /dev/null +++ b/api/src/main/java/com/alibaba/nacos/api/config/listener/ConfigChangeParser.java @@ -0,0 +1,43 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.nacos.api.config.listener; + +import java.io.IOException; +import java.util.Map; + +/** + * ConfigChangeParser + * + * @author rushsky518 + */ +public interface ConfigChangeParser { + /** + * judge type + * @param type + * @return + */ + boolean isResponsibleFor(String type); + + /** + * compare old and new data + * @param oldContent + * @param newContent + * @param type + * @return + * @throws IOException + */ + Map doParse(String oldContent, String newContent, String type) throws IOException; +} diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/AbstractConfigChangeParser.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/AbstractConfigChangeParser.java index 1447c83a2..6c8ee6f51 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/AbstractConfigChangeParser.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/AbstractConfigChangeParser.java @@ -15,8 +15,8 @@ */ package com.alibaba.nacos.client.config.impl; -import java.io.IOException; -import java.util.Collections; +import com.alibaba.nacos.api.config.listener.ConfigChangeParser; + import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -26,50 +26,18 @@ import java.util.Map; * * @author rushsky518 */ -public abstract class AbstractConfigChangeParser { +public abstract class AbstractConfigChangeParser implements ConfigChangeParser { private String configType; - private AbstractConfigChangeParser next; - public AbstractConfigChangeParser(String configType) { this.configType = configType; } - public AbstractConfigChangeParser addNext(AbstractConfigChangeParser configChangeParser) { - if (null == this.next) { - this.next = configChangeParser; - } else { - this.next.addNext(configChangeParser); - } - return this; - } - - protected boolean isResponsibleFor(String type) { + @Override + public boolean isResponsibleFor(String type) { return this.configType.equalsIgnoreCase(type); } - public Map parseChangeData(String oldContent, String newContent, String type) throws IOException { - if (isResponsibleFor(type)) { - return this.doParse(oldContent, newContent, type); - } - - if (null != this.next) { - return this.next.parseChangeData(oldContent, newContent, type); - } - - return Collections.emptyMap(); - } - - /** - * parse and compare config data - * @param oldContent - * @param newContent - * @param type - * @return - * @throws IOException - */ - protected abstract Map doParse(String oldContent, String newContent, String type) throws IOException; - protected Map filterChangeData(Map oldMap, Map newMap) { Map result = new HashMap(16); for (Iterator> entryItr = oldMap.entrySet().iterator(); entryItr.hasNext();) { diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java index 23953cb47..5ebabe084 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java @@ -203,7 +203,7 @@ public class CacheData { // compare lastContent and content if (listener instanceof AbstractConfigChangeListener) { - Map data = ConfigChangeHandler.getChangeParserInstance().parseChangeData(listenerWrap.lastContent, content, type); + Map data = ConfigChangeHandler.getInstance().parseChangeData(listenerWrap.lastContent, content, type); ConfigChangeEvent event = new ConfigChangeEvent(data); ((AbstractConfigChangeListener)listener).receiveConfigChange(event); listenerWrap.lastContent = content; diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java index 50b764b0a..278e26e65 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java @@ -17,6 +17,7 @@ package com.alibaba.nacos.client.config.impl; import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.api.common.Constants; +import com.alibaba.nacos.api.config.ConfigType; import com.alibaba.nacos.api.config.listener.Listener; import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.client.config.common.GroupKey; @@ -248,6 +249,8 @@ public class ClientWorker { ct[0] = result.content; if (result.headers.containsKey(CONFIG_TYPE)) { ct[1] = result.headers.get(CONFIG_TYPE).get(0); + } else { + ct[1] = ConfigType.TEXT.getType(); } return ct; case HttpURLConnection.HTTP_NOT_FOUND: diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHandler.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHandler.java index 1f7de1e81..586646a09 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHandler.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHandler.java @@ -15,28 +15,51 @@ */ package com.alibaba.nacos.client.config.impl; +import com.alibaba.nacos.api.config.listener.ConfigChangeParser; + +import java.io.IOException; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.ServiceLoader; +import java.util.Map; + /** * ConfigChangeHandler * * @author rushsky518 */ public class ConfigChangeHandler { + private static class ConfigChangeHandlerHolder { + private final static ConfigChangeHandler INSTANCE = new ConfigChangeHandler(); + } + private ConfigChangeHandler() { - this.configChangeParser = new PropertiesChangeParser("properties").addNext(new YmlChangeParser("yaml")); + this.parserList = new LinkedList(); + + ServiceLoader loader = ServiceLoader.load(ConfigChangeParser.class); + if (loader.iterator().hasNext()) { + this.parserList.add(loader.iterator().next()); + } + + this.parserList.add(new PropertiesChangeParser()); + this.parserList.add(new YmlChangeParser()); } public static ConfigChangeHandler getInstance() { return ConfigChangeHandlerHolder.INSTANCE; } - public static AbstractConfigChangeParser getChangeParserInstance() { - return ConfigChangeHandlerHolder.INSTANCE.configChangeParser; + public Map parseChangeData(String oldContent, String newContent, String type) throws IOException { + for (ConfigChangeParser changeParser: this.parserList) { + if (changeParser.isResponsibleFor(type)) { + return changeParser.doParse(oldContent, newContent, type); + } + } + + return Collections.emptyMap(); } - private static class ConfigChangeHandlerHolder { - private final static ConfigChangeHandler INSTANCE = new ConfigChangeHandler(); - } - - private AbstractConfigChangeParser configChangeParser; + private List parserList; } diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/PropertiesChangeParser.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/PropertiesChangeParser.java index 5f56bd67b..4d5354869 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/PropertiesChangeParser.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/PropertiesChangeParser.java @@ -28,13 +28,12 @@ import java.util.Properties; * @author rushsky518 */ public class PropertiesChangeParser extends AbstractConfigChangeParser { - - public PropertiesChangeParser(String configType) { - super(configType); + public PropertiesChangeParser() { + super("properties"); } @Override - protected Map doParse(String oldContent, String newContent, String type) throws IOException { + public Map doParse(String oldContent, String newContent, String type) throws IOException { Properties oldProps = new Properties(); Properties newProps = new Properties(); diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/YmlChangeParser.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/YmlChangeParser.java index 7f361d40c..19eaa2052 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/YmlChangeParser.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/YmlChangeParser.java @@ -25,13 +25,12 @@ import java.util.*; * @author rushsky518 */ public class YmlChangeParser extends AbstractConfigChangeParser { - - public YmlChangeParser(String configType) { - super(configType); + public YmlChangeParser() { + super("yaml"); } @Override - protected Map doParse(String oldContent, String newContent, String type) { + public Map doParse(String oldContent, String newContent, String type) { Map oldMap = Collections.emptyMap(); Map newMap = Collections.emptyMap(); @@ -88,4 +87,3 @@ public class YmlChangeParser extends AbstractConfigChangeParser { } } - diff --git a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigServletInner.java b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigServletInner.java index 3ae982e40..885171707 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigServletInner.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigServletInner.java @@ -131,9 +131,7 @@ public class ConfigServletInner { } } String configType = cacheItem.getType(); - if (null != configType) { - response.setHeader("Config-Type", configType); - } + response.setHeader("Config-Type", (null != configType) ? configType : "text"); } File file = null; ConfigInfoBase configInfoBase = null; From ee660f335d03cbc54a811990e41818fd820c0413 Mon Sep 17 00:00:00 2001 From: rushsky518 Date: Wed, 27 Nov 2019 20:58:55 +0800 Subject: [PATCH 14/17] #1550 correct while --- .../alibaba/nacos/client/config/impl/ConfigChangeHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHandler.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHandler.java index 586646a09..2f8b866f8 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHandler.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHandler.java @@ -38,7 +38,7 @@ public class ConfigChangeHandler { this.parserList = new LinkedList(); ServiceLoader loader = ServiceLoader.load(ConfigChangeParser.class); - if (loader.iterator().hasNext()) { + while (loader.iterator().hasNext()) { this.parserList.add(loader.iterator().next()); } From 3c1d6d00c328c6907257aabffc88f50e84626924 Mon Sep 17 00:00:00 2001 From: rushsky518 Date: Thu, 28 Nov 2019 11:56:04 +0800 Subject: [PATCH 15/17] =?UTF-8?q?#1550=20=E6=B7=BB=E5=8A=A0=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95=EF=BC=9B=E9=83=A8=E5=88=86=E7=B1=BB?= =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=88=B0=20api=20=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nacos/api/config}/ConfigChangeEvent.java | 4 +- .../nacos/api/config}/ConfigChangeItem.java | 10 +--- .../nacos/api/config/PropertyChangeType.java | 30 ++++++++++ .../config/listener/ConfigChangeParser.java | 4 +- .../impl/AbstractConfigChangeParser.java | 10 ++-- .../nacos/client/config/impl/CacheData.java | 1 + .../config/impl/PropertiesChangeParser.java | 3 +- .../client/config/impl/YmlChangeParser.java | 3 +- .../impl/AbstractConfigChangeListener.java | 2 +- .../impl/ConfigChangeHandlerTest.java | 39 +++++++++++++ .../impl/PropertiesChangeParserTest.java | 58 +++++++++++++++++++ .../listener/impl/YmlChangeParserTest.java | 57 ++++++++++++++++++ 12 files changed, 203 insertions(+), 18 deletions(-) rename {client/src/main/java/com/alibaba/nacos/client/config/impl => api/src/main/java/com/alibaba/nacos/api/config}/ConfigChangeEvent.java (92%) rename {client/src/main/java/com/alibaba/nacos/client/config/impl => api/src/main/java/com/alibaba/nacos/api/config}/ConfigChangeItem.java (90%) create mode 100644 api/src/main/java/com/alibaba/nacos/api/config/PropertyChangeType.java create mode 100644 client/src/test/java/com/alibaba/nacos/client/config/listener/impl/ConfigChangeHandlerTest.java create mode 100644 client/src/test/java/com/alibaba/nacos/client/config/listener/impl/PropertiesChangeParserTest.java create mode 100644 client/src/test/java/com/alibaba/nacos/client/config/listener/impl/YmlChangeParserTest.java diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java b/api/src/main/java/com/alibaba/nacos/api/config/ConfigChangeEvent.java similarity index 92% rename from client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java rename to api/src/main/java/com/alibaba/nacos/api/config/ConfigChangeEvent.java index 172056daf..92eccb86c 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeEvent.java +++ b/api/src/main/java/com/alibaba/nacos/api/config/ConfigChangeEvent.java @@ -13,7 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.nacos.client.config.impl; +package com.alibaba.nacos.api.config; + +import com.alibaba.nacos.api.config.ConfigChangeItem; import java.util.Collection; import java.util.Map; diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeItem.java b/api/src/main/java/com/alibaba/nacos/api/config/ConfigChangeItem.java similarity index 90% rename from client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeItem.java rename to api/src/main/java/com/alibaba/nacos/api/config/ConfigChangeItem.java index 27e6593b1..b29d14ff4 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeItem.java +++ b/api/src/main/java/com/alibaba/nacos/api/config/ConfigChangeItem.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.nacos.client.config.impl; +package com.alibaba.nacos.api.config; /** * ConfigChangeItem @@ -26,14 +26,6 @@ public class ConfigChangeItem { private String newValue; private PropertyChangeType type; - public enum PropertyChangeType { - /** add */ - ADDED, - /** modified */ - MODIFIED, - /** deleted */ - DELETED - } public ConfigChangeItem(String key, String oldValue, String newValue) { this.key = key; diff --git a/api/src/main/java/com/alibaba/nacos/api/config/PropertyChangeType.java b/api/src/main/java/com/alibaba/nacos/api/config/PropertyChangeType.java new file mode 100644 index 000000000..93c47dfd4 --- /dev/null +++ b/api/src/main/java/com/alibaba/nacos/api/config/PropertyChangeType.java @@ -0,0 +1,30 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 = the "License""); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.nacos.api.config; + +/** + * Property Change Type + * + * @author rushsky518 + */ +public enum PropertyChangeType { + /** add */ + ADDED, + /** modified */ + MODIFIED, + /** deleted */ + DELETED +} diff --git a/api/src/main/java/com/alibaba/nacos/api/config/listener/ConfigChangeParser.java b/api/src/main/java/com/alibaba/nacos/api/config/listener/ConfigChangeParser.java index 9a6f053c0..c7a15f04f 100644 --- a/api/src/main/java/com/alibaba/nacos/api/config/listener/ConfigChangeParser.java +++ b/api/src/main/java/com/alibaba/nacos/api/config/listener/ConfigChangeParser.java @@ -15,6 +15,8 @@ */ package com.alibaba.nacos.api.config.listener; +import com.alibaba.nacos.api.config.ConfigChangeItem; + import java.io.IOException; import java.util.Map; @@ -39,5 +41,5 @@ public interface ConfigChangeParser { * @return * @throws IOException */ - Map doParse(String oldContent, String newContent, String type) throws IOException; + Map doParse(String oldContent, String newContent, String type) throws IOException; } diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/AbstractConfigChangeParser.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/AbstractConfigChangeParser.java index 6c8ee6f51..bea9e6d52 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/AbstractConfigChangeParser.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/AbstractConfigChangeParser.java @@ -15,6 +15,8 @@ */ package com.alibaba.nacos.client.config.impl; +import com.alibaba.nacos.api.config.ConfigChangeItem; +import com.alibaba.nacos.api.config.PropertyChangeType; import com.alibaba.nacos.api.config.listener.ConfigChangeParser; import java.util.HashMap; @@ -38,7 +40,7 @@ public abstract class AbstractConfigChangeParser implements ConfigChangeParser { return this.configType.equalsIgnoreCase(type); } - protected Map filterChangeData(Map oldMap, Map newMap) { + protected Map filterChangeData(Map oldMap, Map newMap) { Map result = new HashMap(16); for (Iterator> entryItr = oldMap.entrySet().iterator(); entryItr.hasNext();) { Map.Entry e = entryItr.next(); @@ -48,10 +50,10 @@ public abstract class AbstractConfigChangeParser implements ConfigChangeParser { continue; } cci = new ConfigChangeItem(e.getKey(), e.getValue().toString(), newMap.get(e.getKey()).toString()); - cci.setType(ConfigChangeItem.PropertyChangeType.MODIFIED); + cci.setType(PropertyChangeType.MODIFIED); } else { cci = new ConfigChangeItem(e.getKey(), e.getValue().toString(), null); - cci.setType(ConfigChangeItem.PropertyChangeType.DELETED); + cci.setType(PropertyChangeType.DELETED); } result.put(e.getKey(), cci); @@ -61,7 +63,7 @@ public abstract class AbstractConfigChangeParser implements ConfigChangeParser { Map.Entry e = entryItr.next(); if (!oldMap.containsKey(e.getKey())) { ConfigChangeItem cci = new ConfigChangeItem(e.getKey(), null, e.getValue().toString()); - cci.setType(ConfigChangeItem.PropertyChangeType.ADDED); + cci.setType(PropertyChangeType.ADDED); result.put(e.getKey(), cci); } } diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java index 5ebabe084..471ccb2ef 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.client.config.impl; import com.alibaba.nacos.api.common.Constants; +import com.alibaba.nacos.api.config.ConfigChangeEvent; import com.alibaba.nacos.api.config.listener.AbstractSharedListener; import com.alibaba.nacos.api.config.listener.Listener; import com.alibaba.nacos.api.exception.NacosException; diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/PropertiesChangeParser.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/PropertiesChangeParser.java index 4d5354869..2aad22346 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/PropertiesChangeParser.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/PropertiesChangeParser.java @@ -15,6 +15,7 @@ */ package com.alibaba.nacos.client.config.impl; +import com.alibaba.nacos.api.config.ConfigChangeItem; import com.alibaba.nacos.client.utils.StringUtils; import java.io.IOException; @@ -33,7 +34,7 @@ public class PropertiesChangeParser extends AbstractConfigChangeParser { } @Override - public Map doParse(String oldContent, String newContent, String type) throws IOException { + public Map doParse(String oldContent, String newContent, String type) throws IOException { Properties oldProps = new Properties(); Properties newProps = new Properties(); diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/YmlChangeParser.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/YmlChangeParser.java index 19eaa2052..f00e4c4fa 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/YmlChangeParser.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/YmlChangeParser.java @@ -15,6 +15,7 @@ */ package com.alibaba.nacos.client.config.impl; +import com.alibaba.nacos.api.config.ConfigChangeItem; import com.alibaba.nacos.client.utils.StringUtils; import org.yaml.snakeyaml.Yaml; import java.util.*; @@ -30,7 +31,7 @@ public class YmlChangeParser extends AbstractConfigChangeParser { } @Override - public Map doParse(String oldContent, String newContent, String type) { + public Map doParse(String oldContent, String newContent, String type) { Map oldMap = Collections.emptyMap(); Map newMap = Collections.emptyMap(); diff --git a/client/src/main/java/com/alibaba/nacos/client/config/listener/impl/AbstractConfigChangeListener.java b/client/src/main/java/com/alibaba/nacos/client/config/listener/impl/AbstractConfigChangeListener.java index d456d4da0..b4e94364c 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/listener/impl/AbstractConfigChangeListener.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/listener/impl/AbstractConfigChangeListener.java @@ -16,7 +16,7 @@ package com.alibaba.nacos.client.config.listener.impl; import com.alibaba.nacos.api.config.listener.AbstractListener; -import com.alibaba.nacos.client.config.impl.ConfigChangeEvent; +import com.alibaba.nacos.api.config.ConfigChangeEvent; /** * AbstractConfigChangeListener diff --git a/client/src/test/java/com/alibaba/nacos/client/config/listener/impl/ConfigChangeHandlerTest.java b/client/src/test/java/com/alibaba/nacos/client/config/listener/impl/ConfigChangeHandlerTest.java new file mode 100644 index 000000000..1e66699b7 --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/config/listener/impl/ConfigChangeHandlerTest.java @@ -0,0 +1,39 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.nacos.client.config.listener.impl; + + +import com.alibaba.nacos.api.config.ConfigChangeItem; +import com.alibaba.nacos.client.config.impl.ConfigChangeHandler; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.util.Map; + +public class ConfigChangeHandlerTest { + @Test + public void testParseProperties() throws IOException { + Map properties = ConfigChangeHandler.getInstance().parseChangeData("", "app.name = nacos", "properties"); + Assert.assertEquals("nacos", ((ConfigChangeItem)properties.get("app.name")).getNewValue()); + } + + @Test + public void testParseYaml() throws IOException { + Map properties = ConfigChangeHandler.getInstance().parseChangeData("", "app:\n name: nacos", "yaml"); + Assert.assertEquals("nacos", ((ConfigChangeItem)properties.get("app.name")).getNewValue()); + } +} diff --git a/client/src/test/java/com/alibaba/nacos/client/config/listener/impl/PropertiesChangeParserTest.java b/client/src/test/java/com/alibaba/nacos/client/config/listener/impl/PropertiesChangeParserTest.java new file mode 100644 index 000000000..a4d063907 --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/config/listener/impl/PropertiesChangeParserTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.nacos.client.config.listener.impl; + + +import com.alibaba.nacos.api.config.ConfigChangeItem; +import com.alibaba.nacos.client.config.impl.PropertiesChangeParser; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.util.Map; + +public class PropertiesChangeParserTest { + private PropertiesChangeParser parser = new PropertiesChangeParser(); + private final String type = "properties"; + + @Test + public void testType() { + Assert.assertEquals(true, parser.isResponsibleFor(type)); + } + + @Test + public void testAddKey() throws IOException { + Map map = parser.doParse("", "app.name = nacos", type); + Assert.assertEquals(null, map.get("app.name").getOldValue()); + Assert.assertEquals("nacos", map.get("app.name").getNewValue()); + } + + @Test + public void testRemoveKey() throws IOException { + Map map = parser.doParse("app.name = nacos", "", type); + Assert.assertEquals("nacos", map.get("app.name").getOldValue()); + Assert.assertEquals(null, map.get("app.name").getNewValue()); + } + + @Test + public void testModifyKey() throws IOException { + Map map = parser.doParse("app.name = rocketMQ", "app.name = nacos", type); + Assert.assertEquals("rocketMQ", map.get("app.name").getOldValue()); + Assert.assertEquals("nacos", map.get("app.name").getNewValue()); + } + +} + diff --git a/client/src/test/java/com/alibaba/nacos/client/config/listener/impl/YmlChangeParserTest.java b/client/src/test/java/com/alibaba/nacos/client/config/listener/impl/YmlChangeParserTest.java new file mode 100644 index 000000000..5174bf801 --- /dev/null +++ b/client/src/test/java/com/alibaba/nacos/client/config/listener/impl/YmlChangeParserTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.nacos.client.config.listener.impl; + + +import com.alibaba.nacos.api.config.ConfigChangeItem; +import com.alibaba.nacos.client.config.impl.YmlChangeParser; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.util.Map; + +public class YmlChangeParserTest { + private YmlChangeParser parser = new YmlChangeParser(); + private final String type = "yaml"; + + @Test + public void testType() { + Assert.assertEquals(true, parser.isResponsibleFor(type)); + } + + @Test + public void testAddKey() throws IOException { + Map map = parser.doParse("", "app:\n name: nacos", type); + Assert.assertEquals(null, map.get("app.name").getOldValue()); + Assert.assertEquals("nacos", map.get("app.name").getNewValue()); + } + + @Test + public void testRemoveKey() throws IOException { + Map map = parser.doParse("app:\n name: nacos", "", type); + Assert.assertEquals("nacos", map.get("app.name").getOldValue()); + Assert.assertEquals(null, map.get("app.name").getNewValue()); + } + + @Test + public void testModifyKey() throws IOException { + Map map = parser.doParse("app:\n name: rocketMQ", "app:\n name: nacos", type); + Assert.assertEquals("rocketMQ", map.get("app.name").getOldValue()); + Assert.assertEquals("nacos", map.get("app.name").getNewValue()); + } +} + From 1a4c8f8af127e5b651f8c12a7d6f96b9eae4a9b5 Mon Sep 17 00:00:00 2001 From: rushsky518 Date: Thu, 28 Nov 2019 15:56:29 +0800 Subject: [PATCH 16/17] =?UTF-8?q?#1550=20=E5=8A=A0=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/impl/ConfigChangeHandler.java | 6 +- .../ConfigLongPollReturnChanges_ITCase.java | 76 +++++++++++++++++++ .../nacos/test/config/TextChangeParser.java | 40 ++++++++++ ...cos.api.config.listener.ConfigChangeParser | 1 + 4 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 test/src/test/java/com/alibaba/nacos/test/config/ConfigLongPollReturnChanges_ITCase.java create mode 100644 test/src/test/java/com/alibaba/nacos/test/config/TextChangeParser.java create mode 100644 test/src/test/resources/META-INF/services/com.alibaba.nacos.api.config.listener.ConfigChangeParser diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHandler.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHandler.java index 2f8b866f8..4a4722134 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHandler.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigChangeHandler.java @@ -23,6 +23,7 @@ import java.util.LinkedList; import java.util.List; import java.util.ServiceLoader; import java.util.Map; +import java.util.Iterator; /** * ConfigChangeHandler @@ -38,8 +39,9 @@ public class ConfigChangeHandler { this.parserList = new LinkedList(); ServiceLoader loader = ServiceLoader.load(ConfigChangeParser.class); - while (loader.iterator().hasNext()) { - this.parserList.add(loader.iterator().next()); + Iterator itr = loader.iterator(); + while (itr.hasNext()) { + this.parserList.add(itr.next()); } this.parserList.add(new PropertiesChangeParser()); diff --git a/test/src/test/java/com/alibaba/nacos/test/config/ConfigLongPollReturnChanges_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/config/ConfigLongPollReturnChanges_ITCase.java new file mode 100644 index 000000000..592d6a6f0 --- /dev/null +++ b/test/src/test/java/com/alibaba/nacos/test/config/ConfigLongPollReturnChanges_ITCase.java @@ -0,0 +1,76 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.nacos.test.config; + +import com.alibaba.nacos.api.NacosFactory; +import com.alibaba.nacos.api.PropertyKeyConst; +import com.alibaba.nacos.api.config.ConfigChangeEvent; +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.config.listener.Listener; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener; +import com.alibaba.nacos.config.server.Config; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.Properties; +import java.util.Random; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Config.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ConfigLongPollReturnChanges_ITCase { + + @LocalServerPort + private int port; + + private ConfigService configService; + + @Before + public void init() throws NacosException { + Properties properties = new Properties(); + properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:" + port); + properties.put(PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT, "20000"); + properties.put(PropertyKeyConst.CONFIG_RETRY_TIME, "3000"); + properties.put(PropertyKeyConst.MAX_RETRY, "5"); + configService = NacosFactory.createConfigService(properties); + } + + @Test + public void test() throws InterruptedException, NacosException { + final String dataId = "test"; + final String group = "DEFAULT_GROUP"; + final String content = "test" + new Random().nextInt(1000); + + configService.addListener(dataId, group, new AbstractConfigChangeListener() { + @Override + public void receiveConfigChange(ConfigChangeEvent event) { + System.out.println(event.getChangeItems()); + } + + }); + + configService.publishConfig(dataId, group, content); + + TimeUnit.SECONDS.sleep(10); + } + +} diff --git a/test/src/test/java/com/alibaba/nacos/test/config/TextChangeParser.java b/test/src/test/java/com/alibaba/nacos/test/config/TextChangeParser.java new file mode 100644 index 000000000..4fb5dcdc1 --- /dev/null +++ b/test/src/test/java/com/alibaba/nacos/test/config/TextChangeParser.java @@ -0,0 +1,40 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.test.config; + +import com.alibaba.nacos.api.config.ConfigChangeItem; +import com.alibaba.nacos.api.config.listener.ConfigChangeParser; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class TextChangeParser implements ConfigChangeParser { + @Override + public boolean isResponsibleFor(String type) { + return (null == type || "text".equalsIgnoreCase(type)); + } + + @Override + public Map doParse(String oldContent, String newContent, String type) throws IOException { + Map map = new HashMap<>(4); + final String key = "content"; + map.put(key, new ConfigChangeItem(key, oldContent, newContent)); + return map; + } +} + diff --git a/test/src/test/resources/META-INF/services/com.alibaba.nacos.api.config.listener.ConfigChangeParser b/test/src/test/resources/META-INF/services/com.alibaba.nacos.api.config.listener.ConfigChangeParser new file mode 100644 index 000000000..a57d2d476 --- /dev/null +++ b/test/src/test/resources/META-INF/services/com.alibaba.nacos.api.config.listener.ConfigChangeParser @@ -0,0 +1 @@ +com.alibaba.nacos.test.config.TextChangeParser From 2acee9588513159324bc84088a726afb48653160 Mon Sep 17 00:00:00 2001 From: rushsky518 Date: Sat, 30 Nov 2019 13:22:47 +0800 Subject: [PATCH 17/17] =?UTF-8?q?#1550=20=E5=AE=8C=E5=96=84=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/config/NacosConfigService.java | 1 - .../client/config/impl/ClientWorker.java | 2 +- .../config/server/service/PersistService.java | 6 +- .../ConfigLongPollReturnChanges_ITCase.java | 95 +++++++++++++++++-- .../nacos/test/config/TextChangeParser.java | 13 ++- 5 files changed, 103 insertions(+), 14 deletions(-) diff --git a/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java b/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java index 1ff9901ea..87dfc1d1a 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java @@ -171,7 +171,6 @@ public class NacosConfigService implements ConfigService { try { String[] ct = worker.getServerConfig(dataId, group, tenant, timeoutMs); - cr.setContent(ct[0]); configFilterChainManager.doFilter(null, cr); diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java index 278e26e65..edf52e3a6 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java @@ -255,7 +255,7 @@ public class ClientWorker { return ct; case HttpURLConnection.HTTP_NOT_FOUND: LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, null); - return null; + return ct; case HttpURLConnection.HTTP_CONFLICT: { LOGGER.error( "[{}] [sub-server-error] get server config being modified concurrently, dataId={}, group={}, " diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/PersistService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/PersistService.java index 3e9134d8c..15527a771 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/PersistService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/PersistService.java @@ -220,7 +220,6 @@ public class PersistService { info.setGroup(rs.getString("group_id")); info.setTenant(rs.getString("tenant_id")); info.setAppName(rs.getString("app_name")); - info.setType(rs.getString("type")); try { info.setContent(rs.getString("content")); @@ -237,6 +236,11 @@ public class PersistService { } catch (SQLException e) { // ignore } + try { + info.setType(rs.getString("type")); + } catch (SQLException e) { + // ignore + } return info; } } diff --git a/test/src/test/java/com/alibaba/nacos/test/config/ConfigLongPollReturnChanges_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/config/ConfigLongPollReturnChanges_ITCase.java index 592d6a6f0..a723efe98 100644 --- a/test/src/test/java/com/alibaba/nacos/test/config/ConfigLongPollReturnChanges_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/config/ConfigLongPollReturnChanges_ITCase.java @@ -18,11 +18,13 @@ package com.alibaba.nacos.test.config; import com.alibaba.nacos.api.NacosFactory; import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.api.config.ConfigChangeEvent; +import com.alibaba.nacos.api.config.ConfigChangeItem; import com.alibaba.nacos.api.config.ConfigService; -import com.alibaba.nacos.api.config.listener.Listener; +import com.alibaba.nacos.api.config.PropertyChangeType; import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener; import com.alibaba.nacos.config.server.Config; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -31,14 +33,12 @@ import org.springframework.boot.web.server.LocalServerPort; import org.springframework.test.context.junit4.SpringRunner; import java.util.Properties; -import java.util.Random; -import java.util.concurrent.Executor; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @RunWith(SpringRunner.class) @SpringBootTest(classes = Config.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class ConfigLongPollReturnChanges_ITCase { - @LocalServerPort private int port; @@ -55,22 +55,97 @@ public class ConfigLongPollReturnChanges_ITCase { } @Test - public void test() throws InterruptedException, NacosException { - final String dataId = "test"; + public void testAdd() throws InterruptedException, NacosException { + CountDownLatch latch = new CountDownLatch(1); + + final String dataId = "test" + System.currentTimeMillis(); final String group = "DEFAULT_GROUP"; - final String content = "test" + new Random().nextInt(1000); + final String content = "config data"; configService.addListener(dataId, group, new AbstractConfigChangeListener() { @Override public void receiveConfigChange(ConfigChangeEvent event) { - System.out.println(event.getChangeItems()); + ConfigChangeItem cci = event.getChangeItem("content"); + Assert.assertEquals(null, cci.getOldValue()); + Assert.assertEquals(content, cci.getNewValue()); + Assert.assertEquals(PropertyChangeType.ADDED, cci.getType()); + System.out.println(cci); + latch.countDown(); } }); - configService.publishConfig(dataId, group, content); - TimeUnit.SECONDS.sleep(10); + latch.await(); + } + + @Test + public void testModify() throws InterruptedException, NacosException { + CountDownLatch latch = new CountDownLatch(1); + + final String dataId = "test" + System.currentTimeMillis(); + final String group = "DEFAULT_GROUP"; + final String oldData = "old data"; + final String newData = "new data"; + + configService.publishConfig(dataId, group, oldData); + + // query config immediately may return null + String config = null; + do { + TimeUnit.SECONDS.sleep(1); + config = configService.getConfig(dataId, group, 50); + } while(null == config); + + configService.addListener(dataId, group, new AbstractConfigChangeListener() { + @Override + public void receiveConfigChange(ConfigChangeEvent event) { + ConfigChangeItem cci = event.getChangeItem("content"); + Assert.assertEquals(oldData, cci.getOldValue()); + Assert.assertEquals(newData, cci.getNewValue()); + Assert.assertEquals(PropertyChangeType.MODIFIED, cci.getType()); + System.out.println(cci); + latch.countDown(); + } + + }); + configService.publishConfig(dataId, group, newData); + + latch.await(); + } + + @Test + public void testDelete() throws InterruptedException, NacosException { + CountDownLatch latch = new CountDownLatch(1); + + final String dataId = "test" + System.currentTimeMillis(); + final String group = "DEFAULT_GROUP"; + final String oldData = "old data"; + + configService.publishConfig(dataId, group, oldData); + + // query config immediately may return null + String config = null; + do { + TimeUnit.SECONDS.sleep(1); + config = configService.getConfig(dataId, group, 50); + } while(null == config); + + configService.addListener(dataId, group, new AbstractConfigChangeListener() { + @Override + public void receiveConfigChange(ConfigChangeEvent event) { + ConfigChangeItem cci = event.getChangeItem("content"); + Assert.assertEquals(oldData, cci.getOldValue()); + Assert.assertEquals(null, cci.getNewValue()); + Assert.assertEquals(PropertyChangeType.DELETED, cci.getType()); + System.out.println(cci); + latch.countDown(); + } + + }); + configService.removeConfig(dataId, group); + + latch.await(); } } diff --git a/test/src/test/java/com/alibaba/nacos/test/config/TextChangeParser.java b/test/src/test/java/com/alibaba/nacos/test/config/TextChangeParser.java index 4fb5dcdc1..998d6c8f8 100644 --- a/test/src/test/java/com/alibaba/nacos/test/config/TextChangeParser.java +++ b/test/src/test/java/com/alibaba/nacos/test/config/TextChangeParser.java @@ -17,6 +17,7 @@ package com.alibaba.nacos.test.config; import com.alibaba.nacos.api.config.ConfigChangeItem; +import com.alibaba.nacos.api.config.PropertyChangeType; import com.alibaba.nacos.api.config.listener.ConfigChangeParser; import java.io.IOException; @@ -33,7 +34,17 @@ public class TextChangeParser implements ConfigChangeParser { public Map doParse(String oldContent, String newContent, String type) throws IOException { Map map = new HashMap<>(4); final String key = "content"; - map.put(key, new ConfigChangeItem(key, oldContent, newContent)); + + ConfigChangeItem cci = new ConfigChangeItem(key, oldContent, newContent); + if (null == oldContent && null != newContent) { + cci.setType(PropertyChangeType.ADDED); + } else if (null != oldContent && null != newContent && !oldContent.equals(newContent)) { + cci.setType(PropertyChangeType.MODIFIED); + } else if (null != oldContent && null == newContent) { + cci.setType(PropertyChangeType.DELETED); + } + map.put(key, cci); + return map; } }