From eb6686111789c5836c9abcbd1019ea5f180f4aef Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Fri, 22 Jul 2022 09:55:05 +0800 Subject: [PATCH 01/13] Fix Qos Online command typo (#10350) --- .../main/java/org/apache/dubbo/qos/command/impl/Online.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java index 76e94be220..a099a99362 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java @@ -19,9 +19,9 @@ package org.apache.dubbo.qos.command.impl; import org.apache.dubbo.qos.command.annotation.Cmd; import org.apache.dubbo.rpc.model.FrameworkModel; -@Cmd(name = "onlineApp", summary = "online app addresses", example = { - "onlineApp dubbo", - "onlineApp xx.xx.xxx.service" +@Cmd(name = "online", summary = "online app addresses", example = { + "online dubbo", + "online xx.xx.xxx.service" }) public class Online extends BaseOnline { public Online(FrameworkModel frameworkModel) { From 8f06c8fae18257c2808da306d7340cc11fcd1df1 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Fri, 22 Jul 2022 11:27:39 +0800 Subject: [PATCH 02/13] Patch maven compiler byte code not support (#10355) --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index 38bef2f54a..1cdbb0f02d 100644 --- a/pom.xml +++ b/pom.xml @@ -109,6 +109,7 @@ 1.8 1.8 + 8 UTF-8 3.2.0 @@ -617,6 +618,7 @@ true ${java_source_version} ${java_target_version} + ${java_release_version} ${file_encoding} From c34bfd6c1a52bd9b5e36440e492ff7b0f600fdd3 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Fri, 22 Jul 2022 12:41:24 +0800 Subject: [PATCH 03/13] Fix pom configuration --- pom.xml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 1cdbb0f02d..a9a40e97d0 100644 --- a/pom.xml +++ b/pom.xml @@ -109,7 +109,6 @@ 1.8 1.8 - 8 UTF-8 3.2.0 @@ -525,6 +524,22 @@ + + jdk9-compile + + [1.9,) + + + + + maven-compiler-plugin + + 8 + + + + + @@ -618,7 +633,6 @@ true ${java_source_version} ${java_target_version} - ${java_release_version} ${file_encoding} From 8aa42274683140506b871c10557b85243988cb45 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Fri, 22 Jul 2022 14:11:09 +0800 Subject: [PATCH 04/13] Disable telnet command by default (#10351) * Disable telnet command by default * fix uts --- .../dubbo/remoting/telnet/support/TelnetHandlerAdapter.java | 4 ++-- .../remoting/telnet/support/TelnetHandlerAdapterTest.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/telnet/support/TelnetHandlerAdapter.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/telnet/support/TelnetHandlerAdapter.java index cc1b952e58..9168a87c05 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/telnet/support/TelnetHandlerAdapter.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/telnet/support/TelnetHandlerAdapter.java @@ -67,7 +67,7 @@ public class TelnetHandlerAdapter extends ChannelHandlerAdapter implements Telne } else { buf.append("Command: "); buf.append(command); - buf.append(" disabled"); + buf.append(" disabled for security reasons, please enable support by listing the commands through 'telnet'"); } } else { buf.append("Unsupported command: "); @@ -86,7 +86,7 @@ public class TelnetHandlerAdapter extends ChannelHandlerAdapter implements Telne private boolean commandEnabled(URL url, String command) { String supportCommands = url.getParameter(TELNET_KEY); if (StringUtils.isEmpty(supportCommands)) { - return true; + return false; } String[] commands = COMMA_SPLIT_PATTERN.split(supportCommands); for (String c : commands) { diff --git a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/telnet/support/TelnetHandlerAdapterTest.java b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/telnet/support/TelnetHandlerAdapterTest.java index 1bac08d8f2..17b120522e 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/telnet/support/TelnetHandlerAdapterTest.java +++ b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/telnet/support/TelnetHandlerAdapterTest.java @@ -53,7 +53,7 @@ class TelnetHandlerAdapterTest { Assertions.assertEquals(expectedResult, telnetHandlerAdapter.telnet(channel, message)); message = "--no-prompt help"; - expectedResult = "Command: help disabled\r\n"; + expectedResult = "Command: help disabled for security reasons, please enable support by listing the commands through 'telnet'\r\n"; Assertions.assertEquals(expectedResult, telnetHandlerAdapter.telnet(channel, message)); message = "--no-prompt"; @@ -61,7 +61,7 @@ class TelnetHandlerAdapterTest { Assertions.assertEquals(expectedResult, telnetHandlerAdapter.telnet(channel, message)); message = "help"; - expectedResult = "Command: help disabled\r\ndubbo>"; + expectedResult = "Command: help disabled for security reasons, please enable support by listing the commands through 'telnet'\r\ndubbo>"; Assertions.assertEquals(expectedResult, telnetHandlerAdapter.telnet(channel, message)); } } From eb18f64a41022c368d83b34be1856c6551de79ba Mon Sep 17 00:00:00 2001 From: liufeiyu1002 <32605119+liufeiyu1002@users.noreply.github.com> Date: Mon, 25 Jul 2022 10:12:46 +0800 Subject: [PATCH 05/13] =?UTF-8?q?fix=20=E7=89=B9=E6=AE=8A=E6=83=85?= =?UTF-8?q?=E5=86=B5=E4=B8=8B=E9=87=8D=E5=A4=8D=E6=B3=A8=E5=85=A5=E5=88=AB?= =?UTF-8?q?=E5=90=8D=20(#10359)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../annotation/ReferenceAnnotationBeanPostProcessor.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java index 1e4fda18d4..fd7e111176 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java @@ -427,9 +427,14 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean // the prev bean type is different, rename the new reference bean int index = 2; String newReferenceBeanName = null; - while (newReferenceBeanName == null || beanDefinitionRegistry.containsBeanDefinition(newReferenceBeanName)) { + while (newReferenceBeanName == null || beanDefinitionRegistry.containsBeanDefinition(newReferenceBeanName) + || beanDefinitionRegistry.isAlias(newReferenceBeanName)) { newReferenceBeanName = referenceBeanName + "#" + index; index++; + // double check found same name and reference key + if (registeredReferenceBeanNames.contains(newReferenceBeanName)) { + return newReferenceBeanName; + } } newBeanDesc = newReferenceBeanName + "[" + referenceKey + "]"; From e3cc8595dc56eb2a1107d8ea5f4f73312025aa71 Mon Sep 17 00:00:00 2001 From: monkeyWie Date: Tue, 26 Jul 2022 09:16:42 +0800 Subject: [PATCH 06/13] fix: metadata service port error when config DUBBO_PORT_TO_REGISTRY env (#10364) --- .../metadata/ConfigurableMetadataServiceExporter.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java index 481fdd0564..778b7c36a5 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java @@ -45,6 +45,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.METADATA_SERVICE import static org.apache.dubbo.common.constants.CommonConstants.METADATA_SERVICE_PROTOCOL_KEY; import static org.apache.dubbo.common.constants.CommonConstants.THREADPOOL_KEY; import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY; +import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY; /** * Export metadata service @@ -122,8 +123,12 @@ public class ConfigurableMetadataServiceExporter { // metadata service may export before normal service export, it.hasNext() will return false. // so need use specified protocol port. if (it.hasNext()) { - String addr = it.next().getAddress(); - String rawPort = addr.substring(addr.indexOf(":") + 1); + ProtocolServer server = it.next(); + String rawPort = server.getUrl().getParameter(BIND_PORT_KEY); + if (rawPort == null) { + String addr = server.getAddress(); + rawPort = addr.substring(addr.indexOf(":") + 1); + } protocolConfig.setPort(Integer.parseInt(rawPort)); } else { Integer protocolPort = getProtocolConfig(specifiedProtocol).getPort(); From 904703eb2265baa3e210da815f9db3d5ea0e66d8 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Wed, 27 Jul 2022 11:02:55 +0800 Subject: [PATCH 07/13] Fix CallbackRegistrationInvoker skip when throw exception (#10349) --- .../dubbo/rpc/cluster/filter/FilterChainBuilder.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/FilterChainBuilder.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/FilterChainBuilder.java index c01c5b67a9..2911eac412 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/FilterChainBuilder.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/FilterChainBuilder.java @@ -192,6 +192,7 @@ public interface FilterChainBuilder { public Result invoke(Invocation invocation) throws RpcException { Result asyncResult = filterInvoker.invoke(invocation); asyncResult.whenCompleteWithContext((r, t) -> { + RuntimeException filterRuntimeException = null; for (int i = filters.size() - 1; i >= 0; i--) { FILTER filter = filters.get(i); try { @@ -218,14 +219,18 @@ public interface FilterChainBuilder { listener.onError(t, filterInvoker, invocation); } } - } catch (Throwable filterThrowable) { + } catch (RuntimeException runtimeException) { LOGGER.error(String.format("Exception occurred while executing the %s filter named %s.", i, filter.getClass().getSimpleName())); if (LOGGER.isDebugEnabled()) { LOGGER.debug(String.format("Whole filter list is: %s", filters.stream().map(tmpFilter -> tmpFilter.getClass().getSimpleName()).collect(Collectors.toList()))); } - throw filterThrowable; + filterRuntimeException = runtimeException; + t = runtimeException; } } + if (filterRuntimeException != null) { + throw filterRuntimeException; + } }); return asyncResult; From 0e1c120870d59ed14054bc5084c353cf369f3460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=81=BC=E5=8D=8E?= <43363120+BurningCN@users.noreply.github.com> Date: Wed, 27 Jul 2022 11:17:28 +0800 Subject: [PATCH 08/13] Fix override configMode (#10371) --- .../apache/dubbo/config/AbstractConfig.java | 2 +- .../config/context/AbstractConfigManager.java | 2 +- .../dubbo/config/context/ConfigMode.java | 4 +- .../config/context/ConfigManagerTest.java | 48 ++++++++++++++++++- 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java index d37f3e919f..05e83a40e8 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java @@ -594,7 +594,7 @@ public abstract class AbstractConfig implements Serializable { if (overrideAll || oldOne == null) { Object newResult = getterMethod.invoke(newOne); // if new one is non-null and new one is not equals old one - if (newResult != null && Objects.equals(newResult, oldOne)) { + if (newResult != null && !Objects.equals(newResult, oldOne)) { method.invoke(this, newResult); } } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java b/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java index ebd903ba33..81c8b068cb 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java @@ -639,7 +639,7 @@ public abstract class AbstractConfigManager extends LifecycleAdapter { /** - * In some scenario, we may nee to add and remove ServiceConfig or ReferenceConfig dynamically. + * In some scenario, we may need to add and remove ServiceConfig or ReferenceConfig dynamically. * * @param config the config instance to remove. * @return diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigMode.java b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigMode.java index 634a9077e8..5ca32398be 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigMode.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigMode.java @@ -32,12 +32,12 @@ public enum ConfigMode { OVERRIDE, /** - * Override mode: accept last config, override previous config + * Override mode: accept last config, override previous config regardless of whether the attribute of previous config is absent or not */ OVERRIDE_ALL, /** - * Override mode: accept last config, override previous config + * Override mode: accept last config, override previous config only when the attribute of previous config is absent */ OVERRIDE_IF_ABSENT, diff --git a/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java b/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java index e4a3757b95..284c00c2e1 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java @@ -16,6 +16,7 @@ */ package org.apache.dubbo.config.context; +import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.ConfigCenterConfig; import org.apache.dubbo.config.ConsumerConfig; @@ -306,6 +307,38 @@ public class ConfigManagerTest { configManager.addConfig(applicationConfig1); configManager.addConfig(applicationConfig2); assertEquals(applicationConfig1, configManager.getApplicationOrElseThrow()); + + // test OVERRIDE_ALL mode + System.setProperty(DUBBO_CONFIG_MODE, ConfigMode.OVERRIDE_ALL.name()); + ApplicationModel.reset(); + configManager = ApplicationModel.defaultModel().getApplicationConfigManager(); + Assertions.assertEquals(ConfigMode.OVERRIDE_ALL, configManager.getConfigMode()); + + ApplicationConfig applicationConfig11 = new ApplicationConfig("app11"); + ApplicationConfig applicationConfig22 = new ApplicationConfig("app22"); + applicationConfig11.setParameters(CollectionUtils.toStringMap("k1", "v1", "k2", "v2")); + applicationConfig22.setParameters(CollectionUtils.toStringMap("k1", "v11", "k2", "v22", "k3", "v3")); + configManager.addConfig(applicationConfig11); + configManager.addConfig(applicationConfig22); + assertEquals(applicationConfig11, configManager.getApplicationOrElseThrow()); + assertEquals(applicationConfig11.getName(), "app22"); + assertEquals(applicationConfig11.getParameters(), CollectionUtils.toStringMap("k1", "v11", "k2", "v22", "k3", "v3")); + + // test OVERRIDE_IF_ABSENT mode + System.setProperty(DUBBO_CONFIG_MODE, ConfigMode.OVERRIDE_IF_ABSENT.name()); + ApplicationModel.reset(); + configManager = ApplicationModel.defaultModel().getApplicationConfigManager(); + Assertions.assertEquals(ConfigMode.OVERRIDE_IF_ABSENT, configManager.getConfigMode()); + + ApplicationConfig applicationConfig33 = new ApplicationConfig("app33"); + ApplicationConfig applicationConfig44 = new ApplicationConfig("app44"); + applicationConfig33.setParameters(CollectionUtils.toStringMap("k1", "v1", "k2", "v2")); + applicationConfig44.setParameters(CollectionUtils.toStringMap("k1", "v11", "k2", "v22", "k3", "v3")); + configManager.addConfig(applicationConfig33); + configManager.addConfig(applicationConfig44); + assertEquals(applicationConfig33, configManager.getApplicationOrElseThrow()); + assertEquals(applicationConfig33.getName(), "app33"); + assertEquals(applicationConfig33.getParameters(), CollectionUtils.toStringMap("k1", "v1", "k2", "v2", "k3", "v3")); } finally { System.clearProperty(DUBBO_CONFIG_MODE); } @@ -319,12 +352,25 @@ public class ConfigManagerTest { Optional registryConfigOptional = configManager.getConfig(RegistryConfig.class, registryConfig.getId()); Assertions.assertEquals(registryConfigOptional.get(), registryConfig); - ProtocolConfig protocolConfig = new ProtocolConfig("dubbo"); configManager.addProtocol(protocolConfig); Optional protocolConfigOptional = configManager.getConfig(ProtocolConfig.class, protocolConfig.getName()); Assertions.assertEquals(protocolConfigOptional.get(), protocolConfig); + // test multi config has same name(dubbo) + ProtocolConfig protocolConfig2 = new ProtocolConfig("dubbo"); + protocolConfig2.setPort(9103); + configManager.addProtocol(protocolConfig2); + try { + configManager.getConfig(ProtocolConfig.class, protocolConfig.getName()); + Assertions.fail(); + } catch (Exception e) { + Assertions.assertTrue(e instanceof IllegalStateException); + Assertions.assertEquals(e.getMessage(), "Found more than one config by name: dubbo, instances: " + + "[, ]. " + + "Please remove redundant configs or get config by id."); + } + ModuleConfig moduleConfig = new ModuleConfig(); moduleConfig.setId("moduleID_1"); moduleConfigManager.setModule(moduleConfig); From 659249d07dc71c9fcbf9bf5caede2a6893e38d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=81=BC=E5=8D=8E?= <43363120+BurningCN@users.noreply.github.com> Date: Wed, 27 Jul 2022 17:20:07 +0800 Subject: [PATCH 09/13] Fix the problem of partial setXXX method injection of spi class (#10354) * Fix the problem of partial setXXX method injection of spi class * Update ExtensionLoader.java * Add check --- .../dubbo/common/config/Environment.java | 1 + .../common/config/ModuleEnvironment.java | 4 ++++ .../common/extension/ExtensionLoader.java | 24 ++++++++++++++++++- .../config/context/ModuleConfigManager.java | 5 +++- .../dubbo/rpc/model/ApplicationModel.java | 3 +++ .../dubbo/rpc/model/FrameworkModel.java | 1 - .../apache/dubbo/rpc/model/ModuleModel.java | 12 ++++++---- .../apache/dubbo/rpc/model/ScopeModel.java | 2 +- .../org.apache.dubbo.common.context.ModuleExt | 1 + .../extension/ExtensionDirectorTest.java | 24 ++++++++----------- .../extension/SpringExtensionInjector.java | 16 +------------ 11 files changed, 55 insertions(+), 38 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java index 36c6b2e1a9..c7c22df0a9 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java @@ -112,6 +112,7 @@ public class Environment extends LifecycleAdapter implements ApplicationExt { * @deprecated only for ut */ @Deprecated + @DisableInject public void setLocalMigrationRule(String localMigrationRule) { this.localMigrationRule = localMigrationRule; } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/ModuleEnvironment.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/ModuleEnvironment.java index cb6a820ab6..f98765962c 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/ModuleEnvironment.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/ModuleEnvironment.java @@ -132,21 +132,25 @@ public class ModuleEnvironment extends Environment implements ModuleExt { } @Override + @DisableInject public void setLocalMigrationRule(String localMigrationRule) { applicationDelegate.setLocalMigrationRule(localMigrationRule); } @Override + @DisableInject public void setExternalConfigMap(Map externalConfiguration) { applicationDelegate.setExternalConfigMap(externalConfiguration); } @Override + @DisableInject public void setAppExternalConfigMap(Map appExternalConfiguration) { applicationDelegate.setAppExternalConfigMap(appExternalConfiguration); } @Override + @DisableInject public void setAppConfigMap(Map appConfiguration) { applicationDelegate.setAppConfigMap(appConfiguration); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java index 2c0d955b8c..2d84934b30 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java @@ -41,6 +41,7 @@ import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.ModuleModel; import org.apache.dubbo.rpc.model.ScopeModel; import org.apache.dubbo.rpc.model.ScopeModelAccessor; +import org.apache.dubbo.rpc.model.ScopeModelAware; import java.io.BufferedReader; import java.io.IOException; @@ -134,6 +135,8 @@ public class ExtensionLoader { private static SoftReference>> urlListMapCache = new SoftReference<>(new ConcurrentHashMap<>()); + private static List ignoredInjectMethodsDesc = getIgnoredInjectMethodsDesc(); + /** * Record all unacceptable exceptions when using SPI */ @@ -187,6 +190,13 @@ public class ExtensionLoader { return asList(strategies); } + private static List getIgnoredInjectMethodsDesc() { + List ignoreInjectMethodsDesc = new ArrayList<>(); + Arrays.stream(ScopeModelAware.class.getMethods()).map(ReflectUtils::getDesc).forEach(ignoreInjectMethodsDesc::add); + Arrays.stream(ExtensionAccessorAware.class.getMethods()).map(ReflectUtils::getDesc).forEach(ignoreInjectMethodsDesc::add); + return ignoreInjectMethodsDesc; + } + ExtensionLoader(Class type, ExtensionDirector extensionDirector, ScopeModel scopeModel) { this.type = type; this.extensionDirector = extensionDirector; @@ -835,11 +845,23 @@ public class ExtensionLoader { continue; } /** - * Check {@link DisableInject} to see if we need auto injection for this property + * Check {@link DisableInject} to see if we need auto-injection for this property */ if (method.isAnnotationPresent(DisableInject.class)) { continue; } + + // When spiXXX implements ScopeModelAware, ExtensionAccessorAware, + // the setXXX of ScopeModelAware and ExtensionAccessorAware does not need to be injected + if (method.getDeclaringClass() == ScopeModelAware.class) { + continue; + } + if (instance instanceof ScopeModelAware || instance instanceof ExtensionAccessorAware) { + if (ignoredInjectMethodsDesc.contains(ReflectUtils.getDesc(method))) { + continue; + } + } + Class pt = method.getParameterTypes()[0]; if (ReflectUtils.isPrimitives(pt)) { continue; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ModuleConfigManager.java b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ModuleConfigManager.java index a935a881f5..b05f24f155 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ModuleConfigManager.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ModuleConfigManager.java @@ -16,6 +16,7 @@ */ package org.apache.dubbo.config.context; +import org.apache.dubbo.common.context.ModuleExt; import org.apache.dubbo.common.extension.DisableInject; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; @@ -50,10 +51,12 @@ import static org.apache.dubbo.config.AbstractConfig.getTagName; /** * Manage configs of module */ -public class ModuleConfigManager extends AbstractConfigManager { +public class ModuleConfigManager extends AbstractConfigManager implements ModuleExt { private static final Logger logger = LoggerFactory.getLogger(ModuleConfigManager.class); + public static final String NAME = "moduleConfig"; + private Map serviceConfigCache = new ConcurrentHashMap<>(); private final ConfigManager applicationConfigManager; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java index f8086268e2..446d3d16fc 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java @@ -203,6 +203,9 @@ public class ApplicationModel extends ScopeModel { LOGGER.info(getDesc() + " is created"); } initialize(); + Assert.notNull(getApplicationServiceRepository(), "ApplicationServiceRepository can not be null"); + Assert.notNull(getApplicationConfigManager(), "ApplicationConfigManager can not be null"); + Assert.assertTrue(getApplicationConfigManager().isInitialized(), "ApplicationConfigManager can not be initialized"); } @Override diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java index a57eeefc6e..65baff1750 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java @@ -123,7 +123,6 @@ public class FrameworkModel extends ScopeModel { // notify destroy and clean framework resources // see org.apache.dubbo.config.deploy.FrameworkModelCleaner notifyDestroy(); - checkApplicationDestroy(); if (LOGGER.isInfoEnabled()) { LOGGER.info(getDesc() + " is destroyed"); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleModel.java index ce8df358bb..f94a18f2a9 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleModel.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleModel.java @@ -61,9 +61,9 @@ public class ModuleModel extends ScopeModel { } initialize(); - Assert.notNull(serviceRepository, "ModuleServiceRepository can not be null"); - Assert.notNull(moduleConfigManager, "ModuleConfigManager can not be null"); - Assert.assertTrue(moduleConfigManager.isInitialized(), "ModuleConfigManager can not be initialized"); + Assert.notNull(getServiceRepository(), "ModuleServiceRepository can not be null"); + Assert.notNull(getConfigManager(), "ModuleConfigManager can not be null"); + Assert.assertTrue(getConfigManager().isInitialized(), "ModuleConfigManager can not be initialized"); // notify application check state ApplicationDeployer applicationDeployer = applicationModel.getDeployer(); @@ -76,8 +76,6 @@ public class ModuleModel extends ScopeModel { protected void initialize() { super.initialize(); this.serviceRepository = new ModuleServiceRepository(this); - this.moduleConfigManager = new ModuleConfigManager(this); - this.moduleConfigManager.initialize(); initModuleExt(); @@ -158,6 +156,10 @@ public class ModuleModel extends ScopeModel { } public ModuleConfigManager getConfigManager() { + if (moduleConfigManager == null) { + moduleConfigManager = (ModuleConfigManager) this.getExtensionLoader(ModuleExt.class) + .getExtension(ModuleConfigManager.NAME); + } return moduleConfigManager; } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java index 6e2258a4dd..b3f016cf93 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java @@ -242,7 +242,7 @@ public abstract class ScopeModel implements ExtensionAccessor { } /** - * @return the describe string of this scope model + * @return to describe string of this scope model */ public String getDesc() { if (this.desc == null) { diff --git a/dubbo-common/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.context.ModuleExt b/dubbo-common/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.context.ModuleExt index a4b5a9842f..825e88b806 100644 --- a/dubbo-common/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.context.ModuleExt +++ b/dubbo-common/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.context.ModuleExt @@ -1 +1,2 @@ moduleEnvironment=org.apache.dubbo.common.config.ModuleEnvironment +moduleConfig=org.apache.dubbo.config.context.ModuleConfigManager diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionDirectorTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionDirectorTest.java index 0ef945d5ea..7db538524c 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionDirectorTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionDirectorTest.java @@ -37,10 +37,6 @@ public class ExtensionDirectorTest { String testAppSrvName = "testAppSrv"; String testMdSrvName = "testMdSrv"; - String testAppProviderName = "testAppProvider"; - String testModuleProviderName = "testModuleProvider"; - String testFrameworkProviderName = "testFrameworkProvider"; - @Test public void testInheritanceAndScope() { @@ -144,16 +140,16 @@ public class ExtensionDirectorTest { @Test public void testModelDataIsolation() { -//Model Tree -//├─frameworkModel1 -//│ ├─applicationModel11 -//│ │ ├─moduleModel111 -//│ │ └─moduleModel112 -//│ └─applicationModel12 -//│ └─moduleModel121 -//└─frameworkModel2 -// └─applicationModel21 -// └─moduleModel211 + //Model Tree + //├─frameworkModel1 + //│ ├─applicationModel11 + //│ │ ├─moduleModel111 + //│ │ └─moduleModel112 + //│ └─applicationModel12 + //│ └─moduleModel121 + //└─frameworkModel2 + // └─applicationModel21 + // └─moduleModel211 FrameworkModel frameworkModel1 = new FrameworkModel(); ApplicationModel applicationModel11 = new ApplicationModel(frameworkModel1); diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/extension/SpringExtensionInjector.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/extension/SpringExtensionInjector.java index cd0b81b1b6..bf297803b6 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/extension/SpringExtensionInjector.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/extension/SpringExtensionInjector.java @@ -16,7 +16,6 @@ */ package org.apache.dubbo.config.spring.extension; -import org.apache.dubbo.common.context.Lifecycle; import org.apache.dubbo.common.extension.ExtensionAccessor; import org.apache.dubbo.common.extension.ExtensionInjector; import org.apache.dubbo.common.extension.SPI; @@ -29,7 +28,7 @@ import java.util.Arrays; /** * SpringExtensionInjector */ -public class SpringExtensionInjector implements ExtensionInjector, Lifecycle { +public class SpringExtensionInjector implements ExtensionInjector { private ApplicationContext context; @@ -91,18 +90,5 @@ public class SpringExtensionInjector implements ExtensionInjector, Lifecycle { Arrays.toString(beanNamesForType)); } return beanFactory.getBean(beanNamesForType[0], type); - } - - @Override - public void initialize() throws IllegalStateException { - } - - @Override - public void start() throws IllegalStateException { - // no op - } - - @Override - public void destroy() { } } From 6443767caf1f37800532900c5d4512461868b4ce Mon Sep 17 00:00:00 2001 From: "Owen.Cai" <89424516@qq.com> Date: Wed, 27 Jul 2022 17:31:13 +0800 Subject: [PATCH 10/13] unexport and delete config (#10369) * unexport and delete config * fix no id null bug * fix code bug --- .../config/context/AbstractConfigManager.java | 12 ++++++++- .../config/context/ModuleConfigManager.java | 26 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java b/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java index 81c8b068cb..2078bd9c29 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java @@ -223,6 +223,13 @@ public abstract class AbstractConfigManager extends LifecycleAdapter { return config; } + protected boolean removeIfAbsent(C config, Map configsMap) { + if(config.getId() != null) { + return configsMap.remove(config.getId(), config); + } + return configsMap.values().removeIf(c -> config == c); + } + protected boolean isUniqueConfig(AbstractConfig config) { if (uniqueConfigTypes.contains(config.getClass())) { return true; @@ -651,7 +658,10 @@ public abstract class AbstractConfigManager extends LifecycleAdapter { Map configs = configsCache.get(getTagName(config.getClass())); if (CollectionUtils.isNotEmptyMap(configs)) { - return configs.values().removeIf(c -> config == c); + // lock by config type + synchronized (configs) { + return removeIfAbsent(config, configs); + } } return false; } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ModuleConfigManager.java b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ModuleConfigManager.java index b05f24f155..c7af4f2454 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ModuleConfigManager.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ModuleConfigManager.java @@ -202,6 +202,17 @@ public class ModuleConfigManager extends AbstractConfigManager implements Module return Optional.empty(); } + @Override + protected boolean removeIfAbsent(C config, Map configsMap) { + if(super.removeIfAbsent(config, configsMap)) { + if (config instanceof ReferenceConfigBase || config instanceof ServiceConfigBase) { + removeInterfaceConfig((AbstractInterfaceConfig) config); + } + return true; + } + return false; + } + /** * check duplicated ReferenceConfig/ServiceConfig * @@ -250,6 +261,21 @@ public class ModuleConfigManager extends AbstractConfigManager implements Module return prevConfig; } + private void removeInterfaceConfig(AbstractInterfaceConfig config) { + String uniqueServiceName; + Map configCache; + if (config instanceof ReferenceConfigBase) { + return; + } else if (config instanceof ServiceConfigBase) { + ServiceConfigBase serviceConfig = (ServiceConfigBase) config; + uniqueServiceName = serviceConfig.getUniqueServiceName(); + configCache = serviceConfigCache; + } else { + throw new IllegalArgumentException("Illegal type of parameter 'config' : " + config.getClass().getName()); + } + configCache.remove(uniqueServiceName, config); + } + @Override public void loadConfigs() { // load dubbo.providers.xxx From 0b21e93dc881952f47800f31aa9963795ff1df69 Mon Sep 17 00:00:00 2001 From: "Owen.Cai" <89424516@qq.com> Date: Wed, 27 Jul 2022 17:42:00 +0800 Subject: [PATCH 11/13] all param no export to meta (#10372) --- .../src/main/java/org/apache/dubbo/metadata/MetadataInfo.java | 1 + 1 file changed, 1 insertion(+) diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java index e2822e8965..b1d852c96f 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java @@ -643,6 +643,7 @@ public class MetadataInfo implements Serializable { this.params = params; } + @Transient public Map getAllParams() { if (consumerParams != null) { Map allParams = new HashMap<>((int) ((params.size() + consumerParams.size()) / 0.75f + 1)); From 7da45152d04eea0ceb721c5a4576cb3119453fb3 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Thu, 28 Jul 2022 11:25:58 +0800 Subject: [PATCH 12/13] Fix pom revision (#10376) --- .../dubbo-demo-native-consumer/pom.xml | 2 +- .../dubbo-demo-native-provider/pom.xml | 2 +- dubbo-native-plugin/pom.xml | 2 +- .../dubbo-spring-boot-actuator/pom.xml | 18 +++++++++--------- .../dubbo-spring-boot-autoconfigure/pom.xml | 10 +++++----- .../actuator/pom.xml | 12 ++++++------ .../autoconfigure/pom.xml | 8 ++++---- .../dubbo-spring-boot-starter/pom.xml | 4 ++-- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml index efac1f4205..f70c8ddd83 100644 --- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml @@ -105,7 +105,7 @@ org.apache.dubbo dubbo-native-plugin - ${revision} + ${project.version} process-sources diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml index f9b5b202a8..07fa6292d7 100644 --- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml @@ -101,7 +101,7 @@ org.apache.dubbo dubbo-native-plugin - ${revision} + ${project.version} process-sources diff --git a/dubbo-native-plugin/pom.xml b/dubbo-native-plugin/pom.xml index bfcc5f7518..1410c737d0 100644 --- a/dubbo-native-plugin/pom.xml +++ b/dubbo-native-plugin/pom.xml @@ -57,7 +57,7 @@ org.apache.dubbo dubbo - ${revision} + ${project.version} diff --git a/dubbo-spring-boot/dubbo-spring-boot-actuator/pom.xml b/dubbo-spring-boot/dubbo-spring-boot-actuator/pom.xml index b39fee024e..355b032de6 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-actuator/pom.xml +++ b/dubbo-spring-boot/dubbo-spring-boot-actuator/pom.xml @@ -35,7 +35,7 @@ org.apache.dubbo dubbo-spring-boot-actuator-compatible - ${revision} + ${project.version} @@ -74,48 +74,48 @@ org.apache.dubbo dubbo-spring-boot-autoconfigure - ${revision} + ${project.version} org.apache.dubbo dubbo - ${revision} + ${project.version} org.apache.dubbo dubbo-common - ${revision} + ${project.version} true org.apache.dubbo dubbo-config-spring - ${revision} + ${project.version} true org.apache.dubbo dubbo-remoting-netty4 - ${revision} + ${project.version} true org.apache.dubbo dubbo-serialization-hessian2 - ${revision} + ${project.version} true org.apache.dubbo dubbo-rpc-dubbo - ${revision} + ${project.version} true @@ -141,4 +141,4 @@ - \ No newline at end of file + diff --git a/dubbo-spring-boot/dubbo-spring-boot-autoconfigure/pom.xml b/dubbo-spring-boot/dubbo-spring-boot-autoconfigure/pom.xml index 30ddd03b35..392ecb89e4 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-autoconfigure/pom.xml +++ b/dubbo-spring-boot/dubbo-spring-boot-autoconfigure/pom.xml @@ -37,7 +37,7 @@ org.apache.dubbo dubbo-spring-boot-autoconfigure-compatible - ${revision} + ${project.version} @@ -64,20 +64,20 @@ org.apache.dubbo dubbo - ${revision} + ${project.version} org.apache.dubbo dubbo-common - ${revision} + ${project.version} true org.apache.dubbo dubbo-config-spring - ${revision} + ${project.version} true @@ -96,4 +96,4 @@ - \ No newline at end of file + diff --git a/dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/pom.xml b/dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/pom.xml index a1a84ec476..66f157f0b5 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/pom.xml +++ b/dubbo-spring-boot/dubbo-spring-boot-compatible/actuator/pom.xml @@ -66,33 +66,33 @@ org.apache.dubbo dubbo-spring-boot-autoconfigure-compatible - ${revision} + ${project.version} org.apache.dubbo dubbo - ${revision} + ${project.version} org.apache.dubbo dubbo-common - ${revision} + ${project.version} true org.apache.dubbo dubbo-config-spring - ${revision} + ${project.version} true org.apache.dubbo dubbo-rpc-dubbo - ${revision} + ${project.version} test @@ -111,4 +111,4 @@ - \ No newline at end of file + diff --git a/dubbo-spring-boot/dubbo-spring-boot-compatible/autoconfigure/pom.xml b/dubbo-spring-boot/dubbo-spring-boot-compatible/autoconfigure/pom.xml index dc940e5c44..da3174cc7d 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-compatible/autoconfigure/pom.xml +++ b/dubbo-spring-boot/dubbo-spring-boot-compatible/autoconfigure/pom.xml @@ -67,21 +67,21 @@ org.apache.dubbo dubbo-common - ${revision} + ${project.version} true org.apache.dubbo dubbo-config-spring - ${revision} + ${project.version} true org.apache.dubbo dubbo - ${revision} + ${project.version} @@ -99,4 +99,4 @@ - \ No newline at end of file + diff --git a/dubbo-spring-boot/dubbo-spring-boot-starter/pom.xml b/dubbo-spring-boot/dubbo-spring-boot-starter/pom.xml index cb1ce7ac7f..b510c64bc6 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-starter/pom.xml +++ b/dubbo-spring-boot/dubbo-spring-boot-starter/pom.xml @@ -55,8 +55,8 @@ org.apache.dubbo dubbo-spring-boot-autoconfigure - ${revision} + ${project.version} - \ No newline at end of file + From 196374dca3f778d1767e3e84f85907e4241a2fe1 Mon Sep 17 00:00:00 2001 From: chenziqiang666 <50438510+chenziqiang666@users.noreply.github.com> Date: Thu, 28 Jul 2022 11:28:14 +0800 Subject: [PATCH 13/13] Expand on the common tools and methods of JSON (#10370) * extend JsonUtils * add license --- .../org/apache/dubbo/common/json/JSON.java | 22 ++ .../common/json/impl/AbstractJSONImpl.java | 238 ++++++++++++++++++ .../dubbo/common/json/impl/FastJsonImpl.java | 3 +- .../dubbo/common/json/impl/GsonImpl.java | 3 +- 4 files changed, 262 insertions(+), 4 deletions(-) create mode 100644 dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/AbstractJSONImpl.java 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 5d6094c2b8..c4210c60cb 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 @@ -18,6 +18,7 @@ package org.apache.dubbo.common.json; import java.lang.reflect.Type; import java.util.List; +import java.util.Map; public interface JSON { boolean isSupport(); @@ -27,4 +28,25 @@ public interface JSON { List toJavaList(String json, Class clazz); String toJson(Object obj); + + List getList(Map obj, String key); + + List> getListOfObjects(Map obj, String key); + + List getListOfStrings(Map obj, String key); + + Map getObject(Map obj, String key); + + Double getNumberAsDouble(Map obj, String key); + + Integer getNumberAsInteger(Map obj, String key); + + Long getNumberAsLong(Map obj, String key); + + String getString(Map obj, String key); + + List> checkObjectList(List rawList); + + List checkStringList(List rawList); + } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/AbstractJSONImpl.java b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/AbstractJSONImpl.java new file mode 100644 index 0000000000..1d5fccb4b7 --- /dev/null +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/AbstractJSONImpl.java @@ -0,0 +1,238 @@ +/* + * 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 org.apache.dubbo.common.json.impl; + +import org.apache.dubbo.common.json.JSON; + +import java.util.List; +import java.util.Map; + +public abstract class AbstractJSONImpl implements JSON { + + @Override + public List getList(Map obj, String key) { + assert obj != null; + assert key != null; + if (!obj.containsKey(key)) { + return null; + } + Object value = obj.get(key); + if (!(value instanceof List)) { + throw new ClassCastException( + String.format("value '%s' for key '%s' in '%s' is not List", value, key, obj)); + } + return (List) value; + } + + /** + * Gets a list from an object for the given key, and verifies all entries are objects. If the key + * is not present, this returns null. If the value is not a List or an entry is not an object, + * throws an exception. + */ + @Override + public List> getListOfObjects(Map obj, String key) { + assert obj != null; + List list = getList(obj, key); + if (list == null) { + return null; + } + return checkObjectList(list); + } + + /** + * Gets a list from an object for the given key, and verifies all entries are strings. If the key + * is not present, this returns null. If the value is not a List or an entry is not a string, + * throws an exception. + */ + @Override + public List getListOfStrings(Map obj, String key) { + assert obj != null; + List list = getList(obj, key); + if (list == null) { + return null; + } + return checkStringList(list); + } + + /** + * Gets an object from an object for the given key. If the key is not present, this returns null. + * If the value is not a Map, throws an exception. + */ + @SuppressWarnings("unchecked") + @Override + public Map getObject(Map obj, String key) { + assert obj != null; + assert key != null; + if (!obj.containsKey(key)) { + return null; + } + Object value = obj.get(key); + if (!(value instanceof Map)) { + throw new ClassCastException( + String.format("value '%s' for key '%s' in '%s' is not object", value, key, obj)); + } + return (Map) value; + } + + /** + * Gets a number from an object for the given key. If the key is not present, this returns null. + * If the value does not represent a double, throws an exception. + */ + @Override + public Double getNumberAsDouble(Map obj, String key) { + assert obj != null; + assert key != null; + if (!obj.containsKey(key)) { + return null; + } + Object value = obj.get(key); + if (value instanceof Double) { + return (Double) value; + } + if (value instanceof String) { + try { + return Double.parseDouble((String) value); + } catch (NumberFormatException e) { + throw new IllegalArgumentException( + String.format("value '%s' for key '%s' is not a double", value, key)); + } + } + throw new IllegalArgumentException( + String.format("value '%s' for key '%s' in '%s' is not a number", value, key, obj)); + } + + /** + * Gets a number from an object for the given key, casted to an integer. If the key is not + * present, this returns null. If the value does not represent an integer, throws an exception. + */ + @Override + public Integer getNumberAsInteger(Map obj, String key) { + assert obj != null; + assert key != null; + if (!obj.containsKey(key)) { + return null; + } + Object value = obj.get(key); + if (value instanceof Double) { + Double d = (Double) value; + int i = d.intValue(); + if (i != d) { + throw new ClassCastException("Number expected to be integer: " + d); + } + return i; + } + if (value instanceof String) { + try { + return Integer.parseInt((String) value); + } catch (NumberFormatException e) { + throw new IllegalArgumentException( + String.format("value '%s' for key '%s' is not an integer", value, key)); + } + } + throw new IllegalArgumentException( + String.format("value '%s' for key '%s' is not an integer", value, key)); + } + + /** + * Gets a number from an object for the given key, casted to an long. If the key is not + * present, this returns null. If the value does not represent a long integer, throws an + * exception. + */ + @Override + public Long getNumberAsLong(Map obj, String key) { + assert obj != null; + assert key != null; + if (!obj.containsKey(key)) { + return null; + } + Object value = obj.get(key); + if (value instanceof Double) { + Double d = (Double) value; + long l = d.longValue(); + if (l != d) { + throw new ClassCastException("Number expected to be long: " + d); + } + return l; + } + if (value instanceof String) { + try { + return Long.parseLong((String) value); + } catch (NumberFormatException e) { + throw new IllegalArgumentException( + String.format("value '%s' for key '%s' is not a long integer", value, key)); + } + } + throw new IllegalArgumentException( + String.format("value '%s' for key '%s' is not a long integer", value, key)); + } + + /** + * Gets a string from an object for the given key. If the key is not present, this returns null. + * If the value is not a String, throws an exception. + */ + @Override + public String getString(Map obj, String key) { + assert obj != null; + assert key != null; + if (!obj.containsKey(key)) { + return null; + } + Object value = obj.get(key); + if (!(value instanceof String)) { + throw new ClassCastException( + String.format("value '%s' for key '%s' in '%s' is not String", value, key, obj)); + } + return (String) value; + } + + /** + * Casts a list of unchecked JSON values to a list of checked objects in Java type. + * If the given list contains a value that is not a Map, throws an exception. + */ + @SuppressWarnings("unchecked") + @Override + public List> checkObjectList(List rawList) { + assert rawList != null; + for (int i = 0; i < rawList.size(); i++) { + if (!(rawList.get(i) instanceof Map)) { + throw new ClassCastException( + String.format("value %s for idx %d in %s is not object", rawList.get(i), i, rawList)); + } + } + return (List>) rawList; + } + + + /** + * Casts a list of unchecked JSON values to a list of String. If the given list + * contains a value that is not a String, throws an exception. + */ + @SuppressWarnings("unchecked") + @Override + public List checkStringList(List rawList) { + assert rawList != null; + for (int i = 0; i < rawList.size(); i++) { + if (!(rawList.get(i) instanceof String)) { + throw new ClassCastException( + String.format( + "value '%s' for idx %d in '%s' is not string", rawList.get(i), i, rawList)); + } + } + return (List) rawList; + } + +} 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 b05fd7cd99..fff944e8aa 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 @@ -16,13 +16,12 @@ */ package org.apache.dubbo.common.json.impl; -import org.apache.dubbo.common.json.JSON; import org.apache.dubbo.common.utils.ClassUtils; import java.lang.reflect.Type; import java.util.List; -public class FastJsonImpl implements JSON { +public class FastJsonImpl extends AbstractJSONImpl { @Override public boolean isSupport() { 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 f202793e13..cbd76fe1b3 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 @@ -16,7 +16,6 @@ */ package org.apache.dubbo.common.json.impl; -import org.apache.dubbo.common.json.JSON; import org.apache.dubbo.common.utils.ClassUtils; import com.google.gson.Gson; @@ -25,7 +24,7 @@ import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type; import java.util.List; -public class GsonImpl implements JSON { +public class GsonImpl extends AbstractJSONImpl { // weak reference of com.google.gson.Gson, prevent throw exception when init private volatile Object gsonCache = null;