diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java index a1ea6682918..c4561dfe4f6 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java @@ -476,15 +476,21 @@ protected void destroyInvokers() { } private boolean addValidInvoker(Invoker invoker) { + boolean result; synchronized (this.validInvokers) { - return this.validInvokers.add(invoker); + result = this.validInvokers.add(invoker); } + MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary())); + return result; } private boolean removeValidInvoker(Invoker invoker) { + boolean result; synchronized (this.validInvokers) { - return this.validInvokers.remove(invoker); + result = this.validInvokers.remove(invoker); } + MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary())); + return result; } protected abstract List> doList(SingleRouterChain singleRouterChain, diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/StaticDirectory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/StaticDirectory.java index 8a17dc0fc01..36e3d3eb59b 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/StaticDirectory.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/StaticDirectory.java @@ -36,6 +36,7 @@ */ public class StaticDirectory extends AbstractDirectory { private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(StaticDirectory.class); + private final Class interfaceClass; public StaticDirectory(List> invokers) { this(null, invokers, null); @@ -55,11 +56,12 @@ public StaticDirectory(URL url, List> invokers, RouterChain router throw new IllegalArgumentException("invokers == null"); } this.setInvokers(new BitList<>(invokers)); + this.interfaceClass = invokers.get(0).getInterface(); } @Override public Class getInterface() { - return getInvokers().get(0).getInterface(); + return interfaceClass; } @Override 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 5f000daa8a4..be0f96d2474 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 @@ -73,6 +73,7 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Pattern; +import java.util.stream.Collectors; import static java.util.Arrays.asList; import static java.util.ServiceLoader.load; @@ -346,7 +347,9 @@ public List getActivateExtension(URL url, String[] values, String group) { checkDestroyed(); // solve the bug of using @SPI's wrapper method to report a null pointer exception. Map, T> activateExtensionsMap = new TreeMap<>(activateComparator); - List names = values == null ? new ArrayList<>(0) : asList(values); + List names = values == null ? + new ArrayList<>(0) : + Arrays.stream(values).map(StringUtils::trim).collect(Collectors.toList()); Set namesSet = new HashSet<>(names); if (!namesSet.contains(REMOVE_VALUE_PREFIX + DEFAULT_KEY)) { if (cachedActivateGroups.size() == 0) { diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractReferenceConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractReferenceConfig.java index e659b10b6f7..058f1d1622f 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractReferenceConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractReferenceConfig.java @@ -21,6 +21,8 @@ import org.apache.dubbo.rpc.model.ModuleModel; import org.apache.dubbo.rpc.support.ProtocolUtils; +import java.beans.Transient; + import static org.apache.dubbo.common.constants.CommonConstants.INVOKER_LISTENER_KEY; import static org.apache.dubbo.common.constants.CommonConstants.REFERENCE_FILTER_KEY; import static org.apache.dubbo.common.constants.CommonConstants.REFER_ASYNC_KEY; @@ -184,6 +186,7 @@ public void setGeneric(String generic) { } @Override + @Transient protected boolean isNeedCheckMethod() { return StringUtils.isEmpty(getGeneric()); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/ModuleConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/ModuleConfig.java index 511c6bbfb79..ef6eaf870da 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/ModuleConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ModuleConfig.java @@ -22,6 +22,7 @@ import org.apache.dubbo.rpc.model.ModuleModel; import org.apache.dubbo.rpc.model.ScopeModel; +import java.beans.Transient; import java.util.ArrayList; import java.util.List; @@ -135,11 +136,13 @@ protected void checkScopeModel(ScopeModel scopeModel) { } @Override + @Transient public ModuleModel getScopeModel() { return (ModuleModel) super.getScopeModel(); } @Override + @Transient protected ScopeModel getDefaultModel() { return ApplicationModel.defaultModel().getDefaultModule(); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java b/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java index bfeacacba5b..4b41ea2786d 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java @@ -150,6 +150,7 @@ public List getPrefixes() { } @Override + @Transient public Map getMetaData() { return getMetaData(null); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/ServiceConfigBase.java b/dubbo-common/src/main/java/org/apache/dubbo/config/ServiceConfigBase.java index 0db03d0208d..265779ed3f7 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/ServiceConfigBase.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ServiceConfigBase.java @@ -180,6 +180,7 @@ protected void preProcessRefresh() { } @Override + @Transient public Map getMetaData() { return getMetaData(null); } diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionLoaderTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionLoaderTest.java index 4f8f1474f10..2e2b2a0884c 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionLoaderTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/extension/ExtensionLoaderTest.java @@ -221,7 +221,7 @@ void test_getExtension_withWrapperAnnotation() { } @Test - void test_getActivateExtension_WithWrapper() { + void test_getActivateExtension_WithWrapper1() { URL url = URL.valueOf("test://localhost/test"); List list = getExtensionLoader(ActivateExt1.class) .getActivateExtension(url, new String[]{}, "order"); @@ -596,7 +596,7 @@ void testLoadActivateExtension() { } @Test - void testLoadDefaultActivateExtension() { + void testLoadDefaultActivateExtension1() { // test default URL url = URL.valueOf("test://localhost/test?ext=order1,default"); List list = getExtensionLoader(ActivateExt1.class) @@ -620,6 +620,31 @@ void testLoadDefaultActivateExtension() { assertSame(list.get(1).getClass(), OrderActivateExtImpl1.class); } + @Test + void testLoadDefaultActivateExtension2() { + // test default + URL url = URL.valueOf("test://localhost/test?ext=order1 , default"); + List list = getExtensionLoader(ActivateExt1.class) + .getActivateExtension(url, "ext", "default_group"); + Assertions.assertEquals(2, list.size()); + assertSame(list.get(0).getClass(), OrderActivateExtImpl1.class); + assertSame(list.get(1).getClass(), ActivateExt1Impl1.class); + + url = URL.valueOf("test://localhost/test?ext=default, order1"); + list = getExtensionLoader(ActivateExt1.class) + .getActivateExtension(url, "ext", "default_group"); + Assertions.assertEquals(2, list.size()); + assertSame(list.get(0).getClass(), ActivateExt1Impl1.class); + assertSame(list.get(1).getClass(), OrderActivateExtImpl1.class); + + url = URL.valueOf("test://localhost/test?ext=order1"); + list = getExtensionLoader(ActivateExt1.class) + .getActivateExtension(url, "ext", "default_group"); + Assertions.assertEquals(2, list.size()); + assertSame(list.get(0).getClass(), ActivateExt1Impl1.class); + assertSame(list.get(1).getClass(), OrderActivateExtImpl1.class); + } + @Test void testInjectExtension() { // register bean for test ScopeBeanExtensionInjector diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invocation.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invocation.java index 2eda40f4958..85e5cfcfe52 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invocation.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invocation.java @@ -17,14 +17,15 @@ package com.alibaba.dubbo.rpc; +import org.apache.dubbo.rpc.model.ServiceModel; + +import java.beans.Transient; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; -import org.apache.dubbo.rpc.model.ServiceModel; - @Deprecated public interface Invocation extends org.apache.dubbo.rpc.Invocation { @@ -184,6 +185,7 @@ public String getAttachment(String key, String defaultValue) { } @Override + @Transient public Invoker getInvoker() { return new Invoker.CompatibleInvoker(delegate.getInvoker()); } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/RpcInvocation.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/RpcInvocation.java index 90352949274..d1cf40600d3 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/RpcInvocation.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/RpcInvocation.java @@ -17,6 +17,10 @@ package com.alibaba.dubbo.rpc; +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.URL; + +import java.beans.Transient; import java.io.Serializable; import java.lang.reflect.Method; import java.util.Arrays; @@ -24,9 +28,6 @@ import java.util.List; import java.util.Map; -import com.alibaba.dubbo.common.Constants; -import com.alibaba.dubbo.common.URL; - public class RpcInvocation implements Invocation, Serializable { private static final long serialVersionUID = -4355285085441097045L; @@ -101,6 +102,7 @@ public RpcInvocation(String methodName, Class[] parameterTypes, Object[] argu this.invoker = invoker; } + @Transient public Invoker getInvoker() { return invoker; } diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ConfigValidationUtils.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ConfigValidationUtils.java index 70380568efa..4e9c20d415d 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ConfigValidationUtils.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ConfigValidationUtils.java @@ -670,8 +670,9 @@ public static void checkMultiExtension(ScopeModel scopeModel, List> typ if (isNotEmpty(value)) { String[] values = value.split("\\s*[,]+\\s*"); for (String v : values) { + v = StringUtils.trim(v); if (v.startsWith(REMOVE_VALUE_PREFIX)) { - v = v.substring(1); + continue; } if (DEFAULT_KEY.equals(v)) { continue; diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java index 0a811bbae55..1a986a58849 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java @@ -207,8 +207,25 @@ void checkMultiExtension1() { @Test void checkMultiExtension2() { + try { + ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default,-world"); + } catch (Throwable t) { + Assertions.fail(t); + } + } + @Test + void checkMultiExtension3() { Assertions.assertThrows(IllegalStateException.class, - () -> ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default,-world")); + () -> ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default , world")); + } + + @Test + void checkMultiExtension4() { + try { + ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default , -world "); + } catch (Throwable t) { + Assertions.fail(t); + } } @Test 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 e86b1e5e49f..ef128333bdd 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 @@ -224,7 +224,7 @@ org.graalvm.buildtools native-maven-plugin - 0.9.22 + 0.9.23 ${project.build.outputDirectory} 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 3649d381e2b..1f2fc06b5b8 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 @@ -222,7 +222,7 @@ org.graalvm.buildtools native-maven-plugin - 0.9.22 + 0.9.23 ${project.build.outputDirectory} diff --git a/dubbo-demo/dubbo-demo-spring-boot/pom.xml b/dubbo-demo/dubbo-demo-spring-boot/pom.xml index 230e3fc196a..6a5f84e7721 100644 --- a/dubbo-demo/dubbo-demo-spring-boot/pom.xml +++ b/dubbo-demo/dubbo-demo-spring-boot/pom.xml @@ -38,7 +38,7 @@ true 2.7.12 2.7.12 - 1.11.0 + 1.11.1 diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 7f917cb9b42..658f5457a0e 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -114,7 +114,7 @@ 3.5.5 0.18.1 4.0.66 - 3.23.2 + 3.23.3 1.3.2 3.1.0 9.4.51.v20230217 @@ -133,14 +133,14 @@ 3.12.0 1.8.0 0.1.35 - 1.11.0 + 1.11.1 1.26.0 2.16.4 - 1.1.1 + 1.1.2 3.3 0.16.0 1.0.4 - 3.5.6 + 3.5.7 2.2.21 3.14.9 @@ -150,7 +150,7 @@ 8.5.87 0.7.5 2.2.3 - 1.55.1 + 1.56.0 0.8.1 1.2.2 diff --git a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/AuthenticationExceptionTranslatorFilter.java b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/AuthenticationExceptionTranslatorFilter.java index 7885250782f..00dadabf596 100644 --- a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/AuthenticationExceptionTranslatorFilter.java +++ b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/AuthenticationExceptionTranslatorFilter.java @@ -24,12 +24,16 @@ import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; + import org.springframework.security.access.AccessDeniedException; import org.springframework.security.core.AuthenticationException; + import static org.apache.dubbo.rpc.RpcException.AUTHORIZATION_EXCEPTION; +import static org.apache.dubbo.spring.security.utils.SecurityNames.CORE_JACKSON_2_MODULE_CLASS_NAME; +import static org.apache.dubbo.spring.security.utils.SecurityNames.OBJECT_MAPPER_CLASS_NAME; import static org.apache.dubbo.spring.security.utils.SecurityNames.SECURITY_CONTEXT_HOLDER_CLASS_NAME; -@Activate(group = CommonConstants.PROVIDER, order =Integer.MAX_VALUE,onClass = SECURITY_CONTEXT_HOLDER_CLASS_NAME) +@Activate(group = CommonConstants.PROVIDER, order = Integer.MAX_VALUE, onClass = {SECURITY_CONTEXT_HOLDER_CLASS_NAME, CORE_JACKSON_2_MODULE_CLASS_NAME, OBJECT_MAPPER_CLASS_NAME}) public class AuthenticationExceptionTranslatorFilter implements Filter, Filter.Listener { diff --git a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/ContextHolderAuthenticationPrepareFilter.java b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/ContextHolderAuthenticationPrepareFilter.java index e2a8fe0bc68..6617f4be858 100644 --- a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/ContextHolderAuthenticationPrepareFilter.java +++ b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/ContextHolderAuthenticationPrepareFilter.java @@ -27,13 +27,17 @@ import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.spring.security.jackson.ObjectMapperCodec; import org.apache.dubbo.spring.security.utils.SecurityNames; + import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; + +import static org.apache.dubbo.spring.security.utils.SecurityNames.CORE_JACKSON_2_MODULE_CLASS_NAME; +import static org.apache.dubbo.spring.security.utils.SecurityNames.OBJECT_MAPPER_CLASS_NAME; import static org.apache.dubbo.spring.security.utils.SecurityNames.SECURITY_CONTEXT_HOLDER_CLASS_NAME; -@Activate(group = CommonConstants.CONSUMER, order = -10000,onClass = SECURITY_CONTEXT_HOLDER_CLASS_NAME) -public class ContextHolderAuthenticationPrepareFilter implements ClusterFilter{ +@Activate(group = CommonConstants.CONSUMER, order = -10000, onClass = {SECURITY_CONTEXT_HOLDER_CLASS_NAME, CORE_JACKSON_2_MODULE_CLASS_NAME, OBJECT_MAPPER_CLASS_NAME}) +public class ContextHolderAuthenticationPrepareFilter implements ClusterFilter { private final ObjectMapperCodec mapper; diff --git a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/ContextHolderAuthenticationResolverFilter.java b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/ContextHolderAuthenticationResolverFilter.java index acd5026409a..9f2567185ac 100644 --- a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/ContextHolderAuthenticationResolverFilter.java +++ b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/filter/ContextHolderAuthenticationResolverFilter.java @@ -27,11 +27,15 @@ import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.spring.security.jackson.ObjectMapperCodec; import org.apache.dubbo.spring.security.utils.SecurityNames; + import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; + +import static org.apache.dubbo.spring.security.utils.SecurityNames.CORE_JACKSON_2_MODULE_CLASS_NAME; +import static org.apache.dubbo.spring.security.utils.SecurityNames.OBJECT_MAPPER_CLASS_NAME; import static org.apache.dubbo.spring.security.utils.SecurityNames.SECURITY_CONTEXT_HOLDER_CLASS_NAME; -@Activate(group = CommonConstants.PROVIDER, order = -10000,onClass = SECURITY_CONTEXT_HOLDER_CLASS_NAME) +@Activate(group = CommonConstants.PROVIDER, order = -10000, onClass = {SECURITY_CONTEXT_HOLDER_CLASS_NAME, CORE_JACKSON_2_MODULE_CLASS_NAME, OBJECT_MAPPER_CLASS_NAME}) public class ContextHolderAuthenticationResolverFilter implements Filter { private final ObjectMapperCodec mapper; diff --git a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/model/SecurityScopeModelInitializer.java b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/model/SecurityScopeModelInitializer.java index 9679334f6f0..286adedb1db 100644 --- a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/model/SecurityScopeModelInitializer.java +++ b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/model/SecurityScopeModelInitializer.java @@ -25,10 +25,14 @@ import org.apache.dubbo.rpc.model.ScopeModelInitializer; import org.apache.dubbo.spring.security.jackson.ObjectMapperCodec; import org.apache.dubbo.spring.security.jackson.ObjectMapperCodecCustomer; + import java.util.Set; + +import static org.apache.dubbo.spring.security.utils.SecurityNames.CORE_JACKSON_2_MODULE_CLASS_NAME; +import static org.apache.dubbo.spring.security.utils.SecurityNames.OBJECT_MAPPER_CLASS_NAME; import static org.apache.dubbo.spring.security.utils.SecurityNames.SECURITY_CONTEXT_HOLDER_CLASS_NAME; -@Activate(onClass = SECURITY_CONTEXT_HOLDER_CLASS_NAME) +@Activate(onClass = {SECURITY_CONTEXT_HOLDER_CLASS_NAME, CORE_JACKSON_2_MODULE_CLASS_NAME, OBJECT_MAPPER_CLASS_NAME}) public class SecurityScopeModelInitializer implements ScopeModelInitializer { @Override diff --git a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/utils/SecurityNames.java b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/utils/SecurityNames.java index 010d8d4f17b..97e167095ba 100644 --- a/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/utils/SecurityNames.java +++ b/dubbo-plugin/dubbo-spring-security/src/main/java/org/apache/dubbo/spring/security/utils/SecurityNames.java @@ -22,6 +22,8 @@ final public class SecurityNames { public static final String SECURITY_AUTHENTICATION_CONTEXT_KEY = "security_authentication_context"; public static final String SECURITY_CONTEXT_HOLDER_CLASS_NAME = "org.springframework.security.core.context.SecurityContextHolder"; + public static final String CORE_JACKSON_2_MODULE_CLASS_NAME = "org.springframework.security.jackson2.CoreJackson2Module"; + public static final String OBJECT_MAPPER_CLASS_NAME = "com.fasterxml.jackson.databind.ObjectMapper"; private SecurityNames() {} diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceInstance.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceInstance.java index f1546815f81..9f9aaaa8600 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceInstance.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceInstance.java @@ -103,6 +103,7 @@ default boolean isHealthy() { void setApplicationModel(ApplicationModel applicationModel); + @Transient ApplicationModel getApplicationModel(); @Transient diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java index 1cb4177a905..b40fa05e8a8 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java @@ -16,16 +16,17 @@ */ package org.apache.dubbo.rpc; -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; -import java.util.stream.Stream; - import org.apache.dubbo.common.Experimental; import org.apache.dubbo.rpc.model.ModuleModel; import org.apache.dubbo.rpc.model.ScopeModelUtil; import org.apache.dubbo.rpc.model.ServiceModel; +import java.beans.Transient; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.stream.Stream; + /** * Invocation. (API, Prototype, NonThreadSafe) * @@ -148,6 +149,7 @@ default Object getObjectAttachmentWithoutConvert(String key) { * @return invoker. * @transient */ + @Transient Invoker getInvoker(); void setServiceModel(ServiceModel serviceModel); diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java index 971b4f74025..70cf0b35344 100644 --- a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java +++ b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java @@ -94,7 +94,6 @@ public Result doInvoke(Invocation invocation) throws Throwable { if (exporter == null) { throw new RpcException("Service [" + key + "] not found."); } - RpcContext.getServiceContext().setRemoteAddress(LOCALHOST_VALUE, 0); // Solve local exposure, the server opens the token, and the client call fails. Invoker invoker = exporter.getInvoker(); URL serverURL = invoker.getUrl(); @@ -122,16 +121,24 @@ public Result doInvoke(Invocation invocation) throws Throwable { // use consumer executor ExecutorService executor = executorRepository.createExecutorIfAbsent(ExecutorUtil.setThreadName(getUrl(), SERVER_THREAD_POOL_NAME)); CompletableFuture appResponseFuture = CompletableFuture.supplyAsync(() -> { - Result result = invoker.invoke(copiedInvocation); - if (result.hasException()) { - AppResponse appResponse = new AppResponse(result.getException()); - appResponse.setObjectAttachments(new HashMap<>(result.getObjectAttachments())); - return appResponse; - } else { - rebuildValue(invocation, desc, result); - AppResponse appResponse = new AppResponse(result.getValue()); - appResponse.setObjectAttachments(new HashMap<>(result.getObjectAttachments())); - return appResponse; + // clear thread local before child invocation, prevent context pollution + InternalThreadLocalMap originTL = InternalThreadLocalMap.getAndRemove(); + try { + RpcContext.getServiceContext().setRemoteAddress(LOCALHOST_VALUE, 0); + RpcContext.getServiceContext().setRemoteApplicationName(getUrl().getApplication()); + Result result = invoker.invoke(copiedInvocation); + if (result.hasException()) { + AppResponse appResponse = new AppResponse(result.getException()); + appResponse.setObjectAttachments(new HashMap<>(result.getObjectAttachments())); + return appResponse; + } else { + rebuildValue(invocation, desc, result); + AppResponse appResponse = new AppResponse(result.getValue()); + appResponse.setObjectAttachments(new HashMap<>(result.getObjectAttachments())); + return appResponse; + } + } finally { + InternalThreadLocalMap.set(originTL); } }, executor); // save for 2.6.x compatibility, for example, TraceFilter in Zipkin uses com.alibaba.xxx.FutureAdapter @@ -144,6 +151,8 @@ public Result doInvoke(Invocation invocation) throws Throwable { // clear thread local before child invocation, prevent context pollution InternalThreadLocalMap originTL = InternalThreadLocalMap.getAndRemove(); try { + RpcContext.getServiceContext().setRemoteAddress(LOCALHOST_VALUE, 0); + RpcContext.getServiceContext().setRemoteApplicationName(getUrl().getApplication()); result = invoker.invoke(copiedInvocation); } finally { InternalThreadLocalMap.set(originTL); diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoService.java b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoService.java index c9d2e63d499..9a09ed96171 100644 --- a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoService.java +++ b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoService.java @@ -40,4 +40,8 @@ public interface DemoService { Type enumlength(Type... types); String getAsyncResult(); + + String getApplication(); + + String getRemoteAddress(); } diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoServiceImpl.java b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoServiceImpl.java index c59847b2988..b4d2314a6d7 100644 --- a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoServiceImpl.java +++ b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoServiceImpl.java @@ -80,4 +80,13 @@ public String getAsyncResult() { return "DONE"; } + @Override + public String getApplication() { + return RpcContext.getServiceContext().getRemoteApplicationName(); + } + + @Override + public String getRemoteAddress() { + return RpcContext.getServiceContext().getRemoteAddressString(); + } } diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java index 5d4103a8408..3ef342e8ea2 100644 --- a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java +++ b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java @@ -19,10 +19,13 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.ExtensionLoader; +import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.rpc.Exporter; +import org.apache.dubbo.rpc.FutureContext; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Protocol; import org.apache.dubbo.rpc.ProxyFactory; +import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; @@ -32,7 +35,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.concurrent.ExecutionException; +import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY; import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY; import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY; @@ -129,7 +134,7 @@ void testIsInjvmRefer() { } @Test - void testLocalProtocolAsync() { + void testLocalProtocolAsync() throws ExecutionException, InterruptedException { DemoService service = new DemoServiceImpl(); URL url = URL.valueOf("injvm://127.0.0.1/TestService") .addParameter(ASYNC_KEY, true) @@ -141,6 +146,39 @@ void testLocalProtocolAsync() { exporters.add(exporter); service = proxy.getProxy(protocol.refer(DemoService.class, url)); assertNull(service.getAsyncResult()); + assertEquals("DONE", FutureContext.getContext().getCompletableFuture().get()); + } + + @Test + void testApplication() { + DemoService service = new DemoServiceImpl(); + URL url = URL.valueOf("injvm://127.0.0.1/TestService") + .addParameter(INTERFACE_KEY, DemoService.class.getName()).addParameter("application", "consumer") + .addParameter(APPLICATION_KEY, "test-app") + .setScopeModel(ApplicationModel.defaultModel().getDefaultModule()); + Invoker invoker = proxy.getInvoker(service, DemoService.class, url); + assertTrue(invoker.isAvailable()); + Exporter exporter = protocol.export(invoker); + exporters.add(exporter); + service = proxy.getProxy(protocol.refer(DemoService.class, url)); + assertEquals("test-app", service.getApplication()); + assertTrue(StringUtils.isEmpty(RpcContext.getServiceContext().getRemoteApplicationName())); + } + + @Test + void testRemoteAddress() { + DemoService service = new DemoServiceImpl(); + URL url = URL.valueOf("injvm://127.0.0.1/TestService") + .addParameter(INTERFACE_KEY, DemoService.class.getName()).addParameter("application", "consumer") + .addParameter(APPLICATION_KEY, "test-app") + .setScopeModel(ApplicationModel.defaultModel().getDefaultModule()); + Invoker invoker = proxy.getInvoker(service, DemoService.class, url); + assertTrue(invoker.isAvailable()); + Exporter exporter = protocol.export(invoker); + exporters.add(exporter); + service = proxy.getProxy(protocol.refer(DemoService.class, url)); + assertEquals("127.0.0.1:0", service.getRemoteAddress()); + assertNull(RpcContext.getServiceContext().getRemoteAddress()); } } diff --git a/dubbo-spring-boot/dubbo-spring-boot-starters/observability/pom.xml b/dubbo-spring-boot/dubbo-spring-boot-starters/observability/pom.xml index 17343de5082..77065023c93 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-starters/observability/pom.xml +++ b/dubbo-spring-boot/dubbo-spring-boot-starters/observability/pom.xml @@ -38,8 +38,8 @@ - 1.11.0 - 1.1.1 + 1.11.1 + 1.1.2 1.27.0 2.16.4 0.16.0