From 189d76be5d94d43d8054cc58d48507380aea99a3 Mon Sep 17 00:00:00 2001 From: Lee hong <40360529+walkinggo@users.noreply.github.com> Date: Tue, 21 May 2024 11:36:53 +0800 Subject: [PATCH] check child is json or not in zookeeper.it will be continue if not. (#14166) * check child is json or not.it will be continue if not. * try to save code format problem. * child could be json array.so child could start with { or [. * fix the problem of it will continue some message to make zookeeper outtime. * try to continue the string without warn. * format the code. * catch the exception of JSONException. * try to fix java.lang.NoClassDefFoundError because of JSONException. * add isJson method and implement it in JSON. * implement the checkJson method and use it in ZookeeperRegistry * format the code. * add some test case. * format the code. * format the code. * format the code. * format the code. * format the code. * format the code. * format the code. * format the code. * format the code. * add some information. * format the code. * add human friendly comment. * format the code. * format the code. --------- Co-authored-by: Albumen Kevin Co-authored-by: Jermaine Hua --- .../org/apache/dubbo/common/json/JSON.java | 2 + .../dubbo/common/json/impl/FastJson2Impl.java | 8 ++++ .../dubbo/common/json/impl/FastJsonImpl.java | 10 +++++ .../dubbo/common/json/impl/GsonImpl.java | 13 ++++++ .../dubbo/common/json/impl/JacksonImpl.java | 12 ++++++ .../apache/dubbo/common/utils/JsonUtils.java | 4 ++ .../dubbo/common/utils/JsonUtilsTest.java | 43 +++++++++++++++++++ .../registry/zookeeper/ZookeeperRegistry.java | 12 +++++- 8 files changed, 103 insertions(+), 1 deletion(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/json/JSON.java b/dubbo-common/src/main/java/org/apache/dubbo/common/json/JSON.java index 7eddf3d988..f9da1d2fbc 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/json/JSON.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/json/JSON.java @@ -23,6 +23,8 @@ import java.util.Map; public interface JSON { boolean isSupport(); + boolean isJson(String json); + T toJavaObject(String json, Type type); List toJavaList(String json, Class clazz); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJson2Impl.java b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJson2Impl.java index ef3e783a74..ed0cca1d81 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJson2Impl.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJson2Impl.java @@ -19,9 +19,17 @@ package org.apache.dubbo.common.json.impl; import java.lang.reflect.Type; import java.util.List; +import com.alibaba.fastjson2.JSONValidator; import com.alibaba.fastjson2.JSONWriter; public class FastJson2Impl extends AbstractJSONImpl { + + @Override + public boolean isJson(String json) { + JSONValidator validator = JSONValidator.from(json); + return validator.validate(); + } + @Override public T toJavaObject(String json, Type type) { return com.alibaba.fastjson2.JSON.parseObject(json, type); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJsonImpl.java b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJsonImpl.java index 97af77891f..30d74d47a6 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJsonImpl.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJsonImpl.java @@ -23,6 +23,16 @@ import com.alibaba.fastjson.serializer.SerializerFeature; public class FastJsonImpl extends AbstractJSONImpl { + @Override + public boolean isJson(String json) { + try { + Object obj = com.alibaba.fastjson.JSON.parse(json); + return obj instanceof com.alibaba.fastjson.JSONObject || obj instanceof com.alibaba.fastjson.JSONArray; + } catch (com.alibaba.fastjson.JSONException e) { + return false; + } + } + @Override public T toJavaObject(String json, Type type) { return com.alibaba.fastjson.JSON.parseObject(json, type); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/GsonImpl.java b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/GsonImpl.java index cd4e53a7ad..da79d9e91a 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/GsonImpl.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/GsonImpl.java @@ -20,12 +20,25 @@ import java.lang.reflect.Type; import java.util.List; import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; public class GsonImpl extends AbstractJSONImpl { // weak reference of com.google.gson.Gson, prevent throw exception when init private volatile Object gsonCache = null; + @Override + public boolean isJson(String json) { + try { + JsonElement jsonElement = JsonParser.parseString(json); + return jsonElement.isJsonObject() || jsonElement.isJsonArray(); + } catch (JsonSyntaxException e) { + return false; + } + } + @Override public T toJavaObject(String json, Type type) { return getGson().fromJson(json, type); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/JacksonImpl.java b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/JacksonImpl.java index 28d822f860..aff9172644 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/JacksonImpl.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/JacksonImpl.java @@ -20,7 +20,9 @@ import java.lang.reflect.Type; import java.util.List; import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; @@ -31,6 +33,16 @@ public class JacksonImpl extends AbstractJSONImpl { private volatile Object jacksonCache = null; + @Override + public boolean isJson(String json) { + try { + JsonNode node = objectMapper.readTree(json); + return node.isObject() || node.isArray(); + } catch (JsonProcessingException e) { + return false; + } + } + @Override public T toJavaObject(String json, Type type) { try { diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/JsonUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/JsonUtils.java index 0d259c6e51..3ee05919d4 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/JsonUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/JsonUtils.java @@ -146,4 +146,8 @@ public class JsonUtils { public static List checkStringList(List rawList) { return getJson().checkStringList(rawList); } + + public static boolean checkJson(String json) { + return getJson().isJson(json); + } } diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/JsonUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/JsonUtilsTest.java index 1b63d217d5..4d04e58741 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/JsonUtilsTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/JsonUtilsTest.java @@ -63,6 +63,49 @@ class JsonUtilsTest { } } + @Test + void testIsJson() { + JsonUtils.setJson(null); + // prefer use fastjson2 + System.setProperty("dubbo.json-framework.prefer", "fastjson2"); + Assertions.assertTrue( + JsonUtils.getJson().isJson("{\"title\":\"Java Programming\",\"author\":\"John Doe\",\"pages\":300}")); + Assertions.assertFalse(JsonUtils.getJson().isJson("This is not a JSON string")); + Assertions.assertTrue( + JsonUtils.getJson().isJson("[{\"title\":\"Java Programming\"}, {\"title\":\"Python Programming\"}]")); + System.clearProperty("dubbo.json-framework.prefer"); + + // prefer use fastjson + JsonUtils.setJson(null); + System.setProperty("dubbo.json-framework.prefer", "fastjson"); + Assertions.assertTrue( + JsonUtils.getJson().isJson("{\"title\":\"Java Programming\",\"author\":\"John Doe\",\"pages\":300}")); + Assertions.assertFalse(JsonUtils.getJson().isJson("This is not a JSON string")); + Assertions.assertTrue( + JsonUtils.getJson().isJson("[{\"title\":\"Java Programming\"}, {\"title\":\"Python Programming\"}]")); + System.clearProperty("dubbo.json-framework.prefer"); + + // prefer use gson + JsonUtils.setJson(null); + System.setProperty("dubbo.json-framework.prefer", "gson"); + Assertions.assertTrue( + JsonUtils.getJson().isJson("{\"title\":\"Java Programming\",\"author\":\"John Doe\",\"pages\":300}")); + Assertions.assertFalse(JsonUtils.getJson().isJson("This is not a JSON string")); + Assertions.assertTrue( + JsonUtils.getJson().isJson("[{\"title\":\"Java Programming\"}, {\"title\":\"Python Programming\"}]")); + System.clearProperty("dubbo.json-framework.prefer"); + + // prefer use jackson + JsonUtils.setJson(null); + System.setProperty("dubbo.json-framework.prefer", "jackson"); + Assertions.assertTrue( + JsonUtils.getJson().isJson("{\"title\":\"Java Programming\",\"author\":\"John Doe\",\"pages\":300}")); + Assertions.assertFalse(JsonUtils.getJson().isJson("This is not a JSON string")); + Assertions.assertTrue( + JsonUtils.getJson().isJson("[{\"title\":\"Java Programming\"}, {\"title\":\"Python Programming\"}]")); + System.clearProperty("dubbo.json-framework.prefer"); + } + @Test void testGetJson1() { Assertions.assertNotNull(JsonUtils.getJson()); diff --git a/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperRegistry.java b/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperRegistry.java index 4052df8d26..e1eb953d72 100644 --- a/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperRegistry.java +++ b/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperRegistry.java @@ -22,6 +22,7 @@ import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.ConcurrentHashMapUtils; import org.apache.dubbo.common.utils.ConcurrentHashSet; +import org.apache.dubbo.common.utils.JsonUtils; import org.apache.dubbo.common.utils.UrlUtils; import org.apache.dubbo.registry.NotifyListener; import org.apache.dubbo.registry.support.CacheableFailbackRegistry; @@ -46,6 +47,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE; import static org.apache.dubbo.common.constants.CommonConstants.CHECK_KEY; import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY; import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_ERROR_DESERIALIZE; import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_ZOOKEEPER_EXCEPTION; import static org.apache.dubbo.common.constants.RegistryConstants.CONFIGURATORS_CATEGORY; import static org.apache.dubbo.common.constants.RegistryConstants.CONSUMERS_CATEGORY; @@ -201,7 +203,15 @@ public class ZookeeperRegistry extends CacheableFailbackRegistry { ChildListener zkListener = ConcurrentHashMapUtils.computeIfAbsent( listeners, listener, k -> (parentPath, currentChildren) -> { for (String child : currentChildren) { - child = URL.decode(child); + try { + child = URL.decode(child); + if (!(JsonUtils.checkJson(child))) { + throw new Exception("dubbo-admin subscribe " + child + " failed,beacause " + + child + "is root path in " + url); + } + } catch (Exception e) { + logger.warn(PROTOCOL_ERROR_DESERIALIZE, "", "", e.getMessage()); + } if (!anyServices.contains(child)) { anyServices.add(child); subscribe(