From 568e2df296ae7ef7f5df80b3e4f043f0fbef895c Mon Sep 17 00:00:00 2001 From: dowenliu-xyz Date: Wed, 29 May 2024 20:26:30 +0800 Subject: [PATCH] Fix reflection exceptions caused by having identically named fallback/blockHandler with different parameter types (#3395) --- .../aop/controller/DemoController.java | 8 ++- .../annotation/aop/service/TestService.java | 2 + .../aop/service/TestServiceImpl.java | 17 +++++- .../AbstractSentinelAspectSupport.java | 23 ++++---- .../aspectj/ResourceMetadataRegistry.java | 52 +++++++++++++++++++ .../aspectj/ResourceMetadataRegistryTest.java | 27 +++++----- .../AbstractSentinelInterceptorSupport.java | 23 ++++---- .../interceptor/ResourceMetadataRegistry.java | 52 +++++++++++++++++++ .../ResourceMetadataRegistryTest.java | 27 +++++----- 9 files changed, 180 insertions(+), 51 deletions(-) diff --git a/sentinel-demo/sentinel-demo-annotation-spring-aop/src/main/java/com/alibaba/csp/sentinel/demo/annotation/aop/controller/DemoController.java b/sentinel-demo/sentinel-demo-annotation-spring-aop/src/main/java/com/alibaba/csp/sentinel/demo/annotation/aop/controller/DemoController.java index d2ba5a86..f06d8fc4 100644 --- a/sentinel-demo/sentinel-demo-annotation-spring-aop/src/main/java/com/alibaba/csp/sentinel/demo/annotation/aop/controller/DemoController.java +++ b/sentinel-demo/sentinel-demo-annotation-spring-aop/src/main/java/com/alibaba/csp/sentinel/demo/annotation/aop/controller/DemoController.java @@ -33,7 +33,7 @@ public class DemoController { private TestService service; @GetMapping("/foo") - public String apiFoo(@RequestParam(required = false) Long t) throws Exception { + public String apiFoo(@RequestParam(required = false) Long t) { if (t == null) { t = System.currentTimeMillis(); } @@ -41,6 +41,12 @@ public class DemoController { return service.hello(t); } + @GetMapping("/bar") + public String apiBar(@RequestParam(required = false) String t) { + service.test(); + return service.hello(t); + } + @GetMapping("/baz/{name}") public String apiBaz(@PathVariable("name") String name) { return service.helloAnother(name); diff --git a/sentinel-demo/sentinel-demo-annotation-spring-aop/src/main/java/com/alibaba/csp/sentinel/demo/annotation/aop/service/TestService.java b/sentinel-demo/sentinel-demo-annotation-spring-aop/src/main/java/com/alibaba/csp/sentinel/demo/annotation/aop/service/TestService.java index 03952122..5b83876e 100644 --- a/sentinel-demo/sentinel-demo-annotation-spring-aop/src/main/java/com/alibaba/csp/sentinel/demo/annotation/aop/service/TestService.java +++ b/sentinel-demo/sentinel-demo-annotation-spring-aop/src/main/java/com/alibaba/csp/sentinel/demo/annotation/aop/service/TestService.java @@ -24,5 +24,7 @@ public interface TestService { String hello(long s); + String hello(String s); + String helloAnother(String name); } diff --git a/sentinel-demo/sentinel-demo-annotation-spring-aop/src/main/java/com/alibaba/csp/sentinel/demo/annotation/aop/service/TestServiceImpl.java b/sentinel-demo/sentinel-demo-annotation-spring-aop/src/main/java/com/alibaba/csp/sentinel/demo/annotation/aop/service/TestServiceImpl.java index 9c793be7..d7c4172b 100644 --- a/sentinel-demo/sentinel-demo-annotation-spring-aop/src/main/java/com/alibaba/csp/sentinel/demo/annotation/aop/service/TestServiceImpl.java +++ b/sentinel-demo/sentinel-demo-annotation-spring-aop/src/main/java/com/alibaba/csp/sentinel/demo/annotation/aop/service/TestServiceImpl.java @@ -16,8 +16,6 @@ package com.alibaba.csp.sentinel.demo.annotation.aop.service; import com.alibaba.csp.sentinel.annotation.SentinelResource; -import com.alibaba.csp.sentinel.slots.block.BlockException; - import org.springframework.stereotype.Service; /** @@ -41,6 +39,15 @@ public class TestServiceImpl implements TestService { return String.format("Hello at %d", s); } + @Override + @SentinelResource(value = "helloStr", fallback = "helloFallback") + public String hello(String s) { + if (s == null || s.trim().isEmpty()) { + throw new IllegalArgumentException("unknown"); + } + return String.format("Hello, %s", s); + } + @Override @SentinelResource(value = "helloAnother", defaultFallback = "defaultFallback", exceptionsToIgnore = {IllegalStateException.class}) @@ -60,6 +67,12 @@ public class TestServiceImpl implements TestService { return "Oops, error occurred at " + s; } + private String helloFallback(String ignored, Throwable e) { + // Do some log here. + e.printStackTrace(); + return "Hello, stranger"; + } + public String defaultFallback() { System.out.println("Go to default fallback"); return "default_fallback"; diff --git a/sentinel-extension/sentinel-annotation-aspectj/src/main/java/com/alibaba/csp/sentinel/annotation/aspectj/AbstractSentinelAspectSupport.java b/sentinel-extension/sentinel-annotation-aspectj/src/main/java/com/alibaba/csp/sentinel/annotation/aspectj/AbstractSentinelAspectSupport.java index b0c38e2e..e121df71 100644 --- a/sentinel-extension/sentinel-annotation-aspectj/src/main/java/com/alibaba/csp/sentinel/annotation/aspectj/AbstractSentinelAspectSupport.java +++ b/sentinel-extension/sentinel-annotation-aspectj/src/main/java/com/alibaba/csp/sentinel/annotation/aspectj/AbstractSentinelAspectSupport.java @@ -34,6 +34,7 @@ import java.util.Arrays; * * @author Eric Zhao * @author zhaoyuguang + * @author dowenliu-xyz(hawkdowen@hotmail.com) */ public abstract class AbstractSentinelAspectSupport { @@ -177,12 +178,13 @@ public abstract class AbstractSentinelAspectSupport { } boolean mustStatic = locationClass != null && locationClass.length >= 1; Class clazz = mustStatic ? locationClass[0] : pjp.getTarget().getClass(); - MethodWrapper m = ResourceMetadataRegistry.lookupFallback(clazz, fallbackName); + Method originMethod = resolveMethod(pjp); + MethodWrapper m = ResourceMetadataRegistry.lookupFallback(clazz, fallbackName, originMethod.getParameterTypes()); if (m == null) { // First time, resolve the fallback. - Method method = resolveFallbackInternal(pjp, fallbackName, clazz, mustStatic); + Method method = resolveFallbackInternal(originMethod, fallbackName, clazz, mustStatic); // Cache the method instance. - ResourceMetadataRegistry.updateFallbackFor(clazz, fallbackName, method); + ResourceMetadataRegistry.updateFallbackFor(clazz, fallbackName, originMethod.getParameterTypes(), method); return method; } if (!m.isPresent()) { @@ -232,9 +234,7 @@ public abstract class AbstractSentinelAspectSupport { return m.getMethod(); } - private Method resolveFallbackInternal(ProceedingJoinPoint pjp, /*@NonNull*/ String name, Class clazz, - boolean mustStatic) { - Method originMethod = resolveMethod(pjp); + private Method resolveFallbackInternal(Method originMethod, String name, Class clazz, boolean mustStatic) { // Fallback function allows two kinds of parameter list. Class[] defaultParamTypes = originMethod.getParameterTypes(); Class[] paramTypesWithException = Arrays.copyOf(defaultParamTypes, defaultParamTypes.length + 1); @@ -261,12 +261,13 @@ public abstract class AbstractSentinelAspectSupport { // By default current class. clazz = pjp.getTarget().getClass(); } - MethodWrapper m = ResourceMetadataRegistry.lookupBlockHandler(clazz, name); + Method originMethod = resolveMethod(pjp); + MethodWrapper m = ResourceMetadataRegistry.lookupBlockHandler(clazz, name, originMethod.getParameterTypes()); if (m == null) { // First time, resolve the block handler. - Method method = resolveBlockHandlerInternal(pjp, name, clazz, mustStatic); + Method method = resolveBlockHandlerInternal(originMethod, name, clazz, mustStatic); // Cache the method instance. - ResourceMetadataRegistry.updateBlockHandlerFor(clazz, name, method); + ResourceMetadataRegistry.updateBlockHandlerFor(clazz, name, originMethod.getParameterTypes(), method); return method; } if (!m.isPresent()) { @@ -275,9 +276,7 @@ public abstract class AbstractSentinelAspectSupport { return m.getMethod(); } - private Method resolveBlockHandlerInternal(ProceedingJoinPoint pjp, /*@NonNull*/ String name, Class clazz, - boolean mustStatic) { - Method originMethod = resolveMethod(pjp); + private Method resolveBlockHandlerInternal(Method originMethod, String name, Class clazz, boolean mustStatic) { Class[] originList = originMethod.getParameterTypes(); Class[] parameterTypes = Arrays.copyOf(originList, originList.length + 1); parameterTypes[parameterTypes.length - 1] = BlockException.class; diff --git a/sentinel-extension/sentinel-annotation-aspectj/src/main/java/com/alibaba/csp/sentinel/annotation/aspectj/ResourceMetadataRegistry.java b/sentinel-extension/sentinel-annotation-aspectj/src/main/java/com/alibaba/csp/sentinel/annotation/aspectj/ResourceMetadataRegistry.java index c4988130..e810fafc 100644 --- a/sentinel-extension/sentinel-annotation-aspectj/src/main/java/com/alibaba/csp/sentinel/annotation/aspectj/ResourceMetadataRegistry.java +++ b/sentinel-extension/sentinel-annotation-aspectj/src/main/java/com/alibaba/csp/sentinel/annotation/aspectj/ResourceMetadataRegistry.java @@ -16,8 +16,10 @@ package com.alibaba.csp.sentinel.annotation.aspectj; import java.lang.reflect.Method; +import java.util.Arrays; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; import com.alibaba.csp.sentinel.util.StringUtil; @@ -25,6 +27,7 @@ import com.alibaba.csp.sentinel.util.StringUtil; * Registry for resource configuration metadata (e.g. fallback method) * * @author Eric Zhao + * @author dowenliu-xyz(hawkdowen@hotmail.com) */ final class ResourceMetadataRegistry { @@ -32,18 +35,38 @@ final class ResourceMetadataRegistry { private static final Map DEFAULT_FALLBACK_MAP = new ConcurrentHashMap<>(); private static final Map BLOCK_HANDLER_MAP = new ConcurrentHashMap<>(); + /** + * @deprecated use {@link #lookupFallback(Class, String, Class[])} + */ + @Deprecated static MethodWrapper lookupFallback(Class clazz, String name) { return FALLBACK_MAP.get(getKey(clazz, name)); } + static MethodWrapper lookupFallback(Class clazz, String name, Class[] parameterTypes) { + return FALLBACK_MAP.get(getKey(clazz, name, parameterTypes)); + } + static MethodWrapper lookupDefaultFallback(Class clazz, String name) { return DEFAULT_FALLBACK_MAP.get(getKey(clazz, name)); } + /** + * @deprecated use {@link #lookupBlockHandler(Class, String, Class[])} + */ + @Deprecated static MethodWrapper lookupBlockHandler(Class clazz, String name) { return BLOCK_HANDLER_MAP.get(getKey(clazz, name)); } + static MethodWrapper lookupBlockHandler(Class clazz, String name, Class[] parameterTypes) { + return BLOCK_HANDLER_MAP.get(getKey(clazz, name, parameterTypes)); + } + + /** + * @deprecated use {@link #updateFallbackFor(Class, String, Class[], Method)} + */ + @Deprecated static void updateFallbackFor(Class clazz, String name, Method method) { if (clazz == null || StringUtil.isBlank(name)) { throw new IllegalArgumentException("Bad argument"); @@ -51,6 +74,13 @@ final class ResourceMetadataRegistry { FALLBACK_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method)); } + static void updateFallbackFor(Class clazz, String handlerName, Class[] parameterTypes, Method handlerMethod) { + if (clazz == null || StringUtil.isBlank(handlerName)) { + throw new IllegalArgumentException("Bad argument"); + } + FALLBACK_MAP.put(getKey(clazz, handlerName, parameterTypes), MethodWrapper.wrap(handlerMethod)); + } + static void updateDefaultFallbackFor(Class clazz, String name, Method method) { if (clazz == null || StringUtil.isBlank(name)) { throw new IllegalArgumentException("Bad argument"); @@ -58,6 +88,11 @@ final class ResourceMetadataRegistry { DEFAULT_FALLBACK_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method)); } + + /** + * @deprecated use {@link #updateBlockHandlerFor(Class, String, Class[], Method)} + */ + @Deprecated static void updateBlockHandlerFor(Class clazz, String name, Method method) { if (clazz == null || StringUtil.isBlank(name)) { throw new IllegalArgumentException("Bad argument"); @@ -65,10 +100,27 @@ final class ResourceMetadataRegistry { BLOCK_HANDLER_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method)); } + static void updateBlockHandlerFor(Class clazz, String handlerName, Class[] parameterTypes, + Method handlerMethod) { + if (clazz == null || StringUtil.isBlank(handlerName)) { + throw new IllegalArgumentException("Bad argument"); + } + BLOCK_HANDLER_MAP.put(getKey(clazz, handlerName, parameterTypes), MethodWrapper.wrap(handlerMethod)); + } + private static String getKey(Class clazz, String name) { return String.format("%s:%s", clazz.getCanonicalName(), name); } + private static String getKey(Class clazz, String name, Class[] parameterTypes) { + return String.format( + "%s:%s;%s", + clazz.getCanonicalName(), + name, + Arrays.stream(parameterTypes).map(Class::getCanonicalName).collect(Collectors.joining(",")) + ); + } + /** * Only for internal test. */ diff --git a/sentinel-extension/sentinel-annotation-aspectj/src/test/java/com/alibaba/csp/sentinel/annotation/aspectj/ResourceMetadataRegistryTest.java b/sentinel-extension/sentinel-annotation-aspectj/src/test/java/com/alibaba/csp/sentinel/annotation/aspectj/ResourceMetadataRegistryTest.java index eac25b91..117fc621 100644 --- a/sentinel-extension/sentinel-annotation-aspectj/src/test/java/com/alibaba/csp/sentinel/annotation/aspectj/ResourceMetadataRegistryTest.java +++ b/sentinel-extension/sentinel-annotation-aspectj/src/test/java/com/alibaba/csp/sentinel/annotation/aspectj/ResourceMetadataRegistryTest.java @@ -26,6 +26,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Eric Zhao + * @author dowenliu-xyz(hawkdowen@hotmail.com) */ public class ResourceMetadataRegistryTest { @@ -45,14 +46,15 @@ public class ResourceMetadataRegistryTest { public void testUpdateThenLookupFallback() { Class clazz = FooService.class; String methodName = "someMethodFallback"; + Class[] parameterTypes = new Class[]{String.class, int.class}; Method method = clazz.getMethods()[0]; - assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName)).isNull(); + assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes)).isNull(); - ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, null); - assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName).isPresent()).isFalse(); + ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, parameterTypes, null); + assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes).isPresent()).isFalse(); - ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, method); - MethodWrapper wrapper = ResourceMetadataRegistry.lookupFallback(clazz, methodName); + ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, parameterTypes, method); + MethodWrapper wrapper = ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes); assertThat(wrapper.isPresent()).isTrue(); assertThat(wrapper.getMethod()).isSameAs(method); } @@ -61,25 +63,26 @@ public class ResourceMetadataRegistryTest { public void testUpdateThenLookupBlockHandler() { Class clazz = FooService.class; String methodName = "someMethodBlockHand;er"; + Class[] parameterTypes = new Class[]{String.class, int.class}; Method method = clazz.getMethods()[1]; - assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName)).isNull(); + assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes)).isNull(); - ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, null); - assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName).isPresent()).isFalse(); + ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, parameterTypes, null); + assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes).isPresent()).isFalse(); - ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, method); - MethodWrapper wrapper = ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName); + ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, parameterTypes, method); + MethodWrapper wrapper = ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes); assertThat(wrapper.isPresent()).isTrue(); assertThat(wrapper.getMethod()).isSameAs(method); } @Test(expected = IllegalArgumentException.class) public void testUpdateBlockHandlerBadArgument() { - ResourceMetadataRegistry.updateBlockHandlerFor(null, "sxs", String.class.getMethods()[0]); + ResourceMetadataRegistry.updateBlockHandlerFor(null, "sxs", new Class[]{}, String.class.getMethods()[0]); } @Test(expected = IllegalArgumentException.class) public void testUpdateFallbackBadArgument() { - ResourceMetadataRegistry.updateBlockHandlerFor(String.class, "", String.class.getMethods()[0]); + ResourceMetadataRegistry.updateBlockHandlerFor(String.class, "", new Class[0], String.class.getMethods()[0]); } } diff --git a/sentinel-extension/sentinel-annotation-cdi-interceptor/src/main/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/AbstractSentinelInterceptorSupport.java b/sentinel-extension/sentinel-annotation-cdi-interceptor/src/main/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/AbstractSentinelInterceptorSupport.java index 8d7b9332..517c7010 100644 --- a/sentinel-extension/sentinel-annotation-cdi-interceptor/src/main/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/AbstractSentinelInterceptorSupport.java +++ b/sentinel-extension/sentinel-annotation-cdi-interceptor/src/main/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/AbstractSentinelInterceptorSupport.java @@ -34,6 +34,7 @@ import java.util.Arrays; * * @author Eric Zhao * @author seasidesky + * @author dowenliu-xyz(hawkdowen@hotmail.com) */ public abstract class AbstractSentinelInterceptorSupport { @@ -170,12 +171,13 @@ public abstract class AbstractSentinelInterceptorSupport { } boolean mustStatic = locationClass != null && locationClass.length >= 1; Class clazz = mustStatic ? locationClass[0] : ctx.getTarget().getClass(); - MethodWrapper m = ResourceMetadataRegistry.lookupFallback(clazz, fallbackName); + Method originMethod = resolveMethod(ctx); + MethodWrapper m = ResourceMetadataRegistry.lookupFallback(clazz, fallbackName, originMethod.getParameterTypes()); if (m == null) { // First time, resolve the fallback. - Method method = resolveFallbackInternal(ctx, fallbackName, clazz, mustStatic); + Method method = resolveFallbackInternal(originMethod, fallbackName, clazz, mustStatic); // Cache the method instance. - ResourceMetadataRegistry.updateFallbackFor(clazz, fallbackName, method); + ResourceMetadataRegistry.updateFallbackFor(clazz, fallbackName, originMethod.getParameterTypes(), method); return method; } if (!m.isPresent()) { @@ -225,9 +227,7 @@ public abstract class AbstractSentinelInterceptorSupport { return m.getMethod(); } - private Method resolveFallbackInternal(InvocationContext ctx, /*@NonNull*/ String name, Class clazz, - boolean mustStatic) { - Method originMethod = resolveMethod(ctx); + private Method resolveFallbackInternal(Method originMethod, String name, Class clazz, boolean mustStatic) { // Fallback function allows two kinds of parameter list. Class[] defaultParamTypes = originMethod.getParameterTypes(); Class[] paramTypesWithException = Arrays.copyOf(defaultParamTypes, defaultParamTypes.length + 1); @@ -254,12 +254,13 @@ public abstract class AbstractSentinelInterceptorSupport { // By default current class. clazz = ctx.getTarget().getClass(); } - MethodWrapper m = ResourceMetadataRegistry.lookupBlockHandler(clazz, name); + Method originMethod = resolveMethod(ctx); + MethodWrapper m = ResourceMetadataRegistry.lookupBlockHandler(clazz, name, originMethod.getParameterTypes()); if (m == null) { // First time, resolve the block handler. - Method method = resolveBlockHandlerInternal(ctx, name, clazz, mustStatic); + Method method = resolveBlockHandlerInternal(originMethod, name, clazz, mustStatic); // Cache the method instance. - ResourceMetadataRegistry.updateBlockHandlerFor(clazz, name, method); + ResourceMetadataRegistry.updateBlockHandlerFor(clazz, name, originMethod.getParameterTypes(), method); return method; } if (!m.isPresent()) { @@ -268,9 +269,7 @@ public abstract class AbstractSentinelInterceptorSupport { return m.getMethod(); } - private Method resolveBlockHandlerInternal(InvocationContext ctx, /*@NonNull*/ String name, Class clazz, - boolean mustStatic) { - Method originMethod = resolveMethod(ctx); + private Method resolveBlockHandlerInternal(Method originMethod, String name, Class clazz, boolean mustStatic) { Class[] originList = originMethod.getParameterTypes(); Class[] parameterTypes = Arrays.copyOf(originList, originList.length + 1); parameterTypes[parameterTypes.length - 1] = BlockException.class; diff --git a/sentinel-extension/sentinel-annotation-cdi-interceptor/src/main/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/ResourceMetadataRegistry.java b/sentinel-extension/sentinel-annotation-cdi-interceptor/src/main/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/ResourceMetadataRegistry.java index f0b29b2a..eb29331d 100644 --- a/sentinel-extension/sentinel-annotation-cdi-interceptor/src/main/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/ResourceMetadataRegistry.java +++ b/sentinel-extension/sentinel-annotation-cdi-interceptor/src/main/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/ResourceMetadataRegistry.java @@ -18,13 +18,16 @@ package com.alibaba.csp.sentinel.annotation.cdi.interceptor; import com.alibaba.csp.sentinel.util.StringUtil; import java.lang.reflect.Method; +import java.util.Arrays; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; /** * Registry for resource configuration metadata (e.g. fallback method) * * @author Eric Zhao + * @author dowenliu-xyz(hawkdowen@hotmail.com) */ final class ResourceMetadataRegistry { @@ -32,18 +35,38 @@ final class ResourceMetadataRegistry { private static final Map DEFAULT_FALLBACK_MAP = new ConcurrentHashMap<>(); private static final Map BLOCK_HANDLER_MAP = new ConcurrentHashMap<>(); + /** + * @deprecated use {@link #lookupFallback(Class, String, Class[])} + */ + @Deprecated static MethodWrapper lookupFallback(Class clazz, String name) { return FALLBACK_MAP.get(getKey(clazz, name)); } + static MethodWrapper lookupFallback(Class clazz, String name, Class[] parameterTypes) { + return FALLBACK_MAP.get(getKey(clazz, name, parameterTypes)); + } + static MethodWrapper lookupDefaultFallback(Class clazz, String name) { return DEFAULT_FALLBACK_MAP.get(getKey(clazz, name)); } + /** + * @deprecated use {@link #lookupBlockHandler(Class, String, Class[])} + */ + @Deprecated static MethodWrapper lookupBlockHandler(Class clazz, String name) { return BLOCK_HANDLER_MAP.get(getKey(clazz, name)); } + static MethodWrapper lookupBlockHandler(Class clazz, String name, Class[] parameterTypes) { + return BLOCK_HANDLER_MAP.get(getKey(clazz, name, parameterTypes)); + } + + /** + * @deprecated use {@link #updateFallbackFor(Class, String, Class[], Method)} + */ + @Deprecated static void updateFallbackFor(Class clazz, String name, Method method) { if (clazz == null || StringUtil.isBlank(name)) { throw new IllegalArgumentException("Bad argument"); @@ -51,6 +74,13 @@ final class ResourceMetadataRegistry { FALLBACK_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method)); } + static void updateFallbackFor(Class clazz, String handlerName, Class[] parameterTypes, Method handlerMethod) { + if (clazz == null || StringUtil.isBlank(handlerName)) { + throw new IllegalArgumentException("Bad argument"); + } + FALLBACK_MAP.put(getKey(clazz, handlerName, parameterTypes), MethodWrapper.wrap(handlerMethod)); + } + static void updateDefaultFallbackFor(Class clazz, String name, Method method) { if (clazz == null || StringUtil.isBlank(name)) { throw new IllegalArgumentException("Bad argument"); @@ -58,6 +88,11 @@ final class ResourceMetadataRegistry { DEFAULT_FALLBACK_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method)); } + + /** + * @deprecated use {@link #updateBlockHandlerFor(Class, String, Class[], Method)} + */ + @Deprecated static void updateBlockHandlerFor(Class clazz, String name, Method method) { if (clazz == null || StringUtil.isBlank(name)) { throw new IllegalArgumentException("Bad argument"); @@ -65,10 +100,27 @@ final class ResourceMetadataRegistry { BLOCK_HANDLER_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method)); } + static void updateBlockHandlerFor(Class clazz, String handlerName, Class[] parameterTypes, + Method handlerMethod) { + if (clazz == null || StringUtil.isBlank(handlerName)) { + throw new IllegalArgumentException("Bad argument"); + } + BLOCK_HANDLER_MAP.put(getKey(clazz, handlerName, parameterTypes), MethodWrapper.wrap(handlerMethod)); + } + private static String getKey(Class clazz, String name) { return String.format("%s:%s", clazz.getCanonicalName(), name); } + private static String getKey(Class clazz, String name, Class[] parameterTypes) { + return String.format( + "%s:%s;%s", + clazz.getCanonicalName(), + name, + Arrays.stream(parameterTypes).map(Class::getCanonicalName).collect(Collectors.joining(",")) + ); + } + /** * Only for internal test. */ diff --git a/sentinel-extension/sentinel-annotation-cdi-interceptor/src/test/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/ResourceMetadataRegistryTest.java b/sentinel-extension/sentinel-annotation-cdi-interceptor/src/test/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/ResourceMetadataRegistryTest.java index a8225170..1b7427dd 100644 --- a/sentinel-extension/sentinel-annotation-cdi-interceptor/src/test/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/ResourceMetadataRegistryTest.java +++ b/sentinel-extension/sentinel-annotation-cdi-interceptor/src/test/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/ResourceMetadataRegistryTest.java @@ -27,6 +27,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Eric Zhao + * @author dowenliu-xyz(hawkdowen@hotmail.com) */ public class ResourceMetadataRegistryTest { @@ -46,14 +47,15 @@ public class ResourceMetadataRegistryTest { public void testUpdateThenLookupFallback() { Class clazz = FooService.class; String methodName = "someMethodFallback"; + Class[] parameterTypes = new Class[] {String.class}; Method method = clazz.getMethods()[0]; - assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName)).isNull(); + assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes)).isNull(); - ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, null); - assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName).isPresent()).isFalse(); + ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, parameterTypes, null); + assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes).isPresent()).isFalse(); - ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, method); - MethodWrapper wrapper = ResourceMetadataRegistry.lookupFallback(clazz, methodName); + ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, parameterTypes, method); + MethodWrapper wrapper = ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes); assertThat(wrapper.isPresent()).isTrue(); assertThat(wrapper.getMethod()).isSameAs(method); } @@ -62,25 +64,26 @@ public class ResourceMetadataRegistryTest { public void testUpdateThenLookupBlockHandler() { Class clazz = FooService.class; String methodName = "someMethodBlockHand;er"; + Class[] parameterTypes = new Class[] {String.class}; Method method = clazz.getMethods()[1]; - assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName)).isNull(); + assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes)).isNull(); - ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, null); - assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName).isPresent()).isFalse(); + ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, parameterTypes, null); + assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes).isPresent()).isFalse(); - ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, method); - MethodWrapper wrapper = ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName); + ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, parameterTypes, method); + MethodWrapper wrapper = ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes); assertThat(wrapper.isPresent()).isTrue(); assertThat(wrapper.getMethod()).isSameAs(method); } @Test(expected = IllegalArgumentException.class) public void testUpdateBlockHandlerBadArgument() { - ResourceMetadataRegistry.updateBlockHandlerFor(null, "sxs", String.class.getMethods()[0]); + ResourceMetadataRegistry.updateBlockHandlerFor(null, "sxs", new Class[0], String.class.getMethods()[0]); } @Test(expected = IllegalArgumentException.class) public void testUpdateFallbackBadArgument() { - ResourceMetadataRegistry.updateBlockHandlerFor(String.class, "", String.class.getMethods()[0]); + ResourceMetadataRegistry.updateBlockHandlerFor(String.class, "", new Class[0], String.class.getMethods()[0]); } }