Skip to content

Commit 8ba0875

Browse files
wuwen5taz
authored andcommitted
Support private blockHandler/fallback method for @SentinelResource annotation (alibaba#2163)
1 parent 9e11a06 commit 8ba0875

File tree

3 files changed

+76
-27
lines changed

3 files changed

+76
-27
lines changed

sentinel-extension/sentinel-annotation-aspectj/src/main/java/com/alibaba/csp/sentinel/annotation/aspectj/AbstractSentinelAspectSupport.java

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,7 @@ protected Object handleFallback(ProceedingJoinPoint pjp, String fallback, String
102102
args[args.length - 1] = ex;
103103
}
104104

105-
try {
106-
if (isStatic(fallbackMethod)) {
107-
return fallbackMethod.invoke(null, args);
108-
}
109-
return fallbackMethod.invoke(pjp.getTarget(), args);
110-
} catch (InvocationTargetException e) {
111-
// throw the actual exception
112-
throw e.getTargetException();
113-
}
105+
return invoke(pjp, fallbackMethod, args);
114106
}
115107
// If fallback is absent, we'll try the defaultFallback if provided.
116108
return handleDefaultFallback(pjp, defaultFallback, fallbackClass, ex);
@@ -123,15 +115,7 @@ protected Object handleDefaultFallback(ProceedingJoinPoint pjp, String defaultFa
123115
if (fallbackMethod != null) {
124116
// Construct args.
125117
Object[] args = fallbackMethod.getParameterTypes().length == 0 ? new Object[0] : new Object[] {ex};
126-
try {
127-
if (isStatic(fallbackMethod)) {
128-
return fallbackMethod.invoke(null, args);
129-
}
130-
return fallbackMethod.invoke(pjp.getTarget(), args);
131-
} catch (InvocationTargetException e) {
132-
// throw the actual exception
133-
throw e.getTargetException();
134-
}
118+
return invoke(pjp, fallbackMethod, args);
135119
}
136120

137121
// If no any fallback is present, then directly throw the exception.
@@ -149,21 +133,44 @@ protected Object handleBlockException(ProceedingJoinPoint pjp, SentinelResource
149133
// Construct args.
150134
Object[] args = Arrays.copyOf(originArgs, originArgs.length + 1);
151135
args[args.length - 1] = ex;
152-
try {
153-
if (isStatic(blockHandlerMethod)) {
154-
return blockHandlerMethod.invoke(null, args);
155-
}
156-
return blockHandlerMethod.invoke(pjp.getTarget(), args);
157-
} catch (InvocationTargetException e) {
158-
// throw the actual exception
159-
throw e.getTargetException();
160-
}
136+
return invoke(pjp, blockHandlerMethod, args);
161137
}
162138

163139
// If no block handler is present, then go to fallback.
164140
return handleFallback(pjp, annotation, ex);
165141
}
166142

143+
private Object invoke(ProceedingJoinPoint pjp, Method method, Object[] args) throws Throwable {
144+
try {
145+
if (!method.isAccessible()) {
146+
makeAccessible(method);
147+
}
148+
if (isStatic(method)) {
149+
return method.invoke(null, args);
150+
}
151+
return method.invoke(pjp.getTarget(), args);
152+
} catch (InvocationTargetException e) {
153+
// throw the actual exception
154+
throw e.getTargetException();
155+
}
156+
}
157+
158+
/**
159+
* Make the given method accessible, explicitly setting it accessible if
160+
* necessary. The {@code setAccessible(true)} method is only called
161+
* when actually necessary, to avoid unnecessary conflicts with a JVM
162+
* SecurityManager (if active).
163+
* @param method the method to make accessible
164+
* @see java.lang.reflect.Method#setAccessible
165+
*/
166+
private static void makeAccessible(Method method) {
167+
boolean isNotPublic = !Modifier.isPublic(method.getModifiers()) ||
168+
!Modifier.isPublic(method.getDeclaringClass().getModifiers());
169+
if (isNotPublic && !method.isAccessible()) {
170+
method.setAccessible(true);
171+
}
172+
}
173+
167174
private Method extractFallbackMethod(ProceedingJoinPoint pjp, String fallbackName, Class<?>[] locationClass) {
168175
if (StringUtil.isBlank(fallbackName)) {
169176
return null;

sentinel-extension/sentinel-annotation-aspectj/src/test/java/com/alibaba/csp/sentinel/annotation/aspectj/integration/SentinelAnnotationIntegrationTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,28 @@ public void testClassLevelDefaultFallbackWithSingleParam() {
208208
assertThat(cn1.blockQps()).isZero();
209209
}
210210

211+
@Test
212+
public void testFallBackPrivateMethod() throws Exception {
213+
String resourceName = "apiFooWithFallback";
214+
ClusterNode cn = ClusterBuilderSlot.getClusterNode(resourceName);
215+
216+
try {
217+
fooService.fooWithPrivateFallback(5758);
218+
fail("should not reach here");
219+
} catch (Exception ex) {
220+
// Should not be traced.
221+
assertThat(cn.exceptionQps()).isZero();
222+
}
223+
224+
assertThat(fooService.fooWithPrivateFallback(5763)).isEqualTo("EEE...");
225+
226+
// Test for blockHandler
227+
FlowRuleManager.loadRules(Collections.singletonList(
228+
new FlowRule(resourceName).setCount(0)
229+
));
230+
assertThat(fooService.fooWithPrivateFallback(2221)).isEqualTo("Oops, 2221");
231+
}
232+
211233
@Before
212234
public void setUp() throws Exception {
213235
FlowRuleManager.loadRules(new ArrayList<FlowRule>());

sentinel-extension/sentinel-annotation-aspectj/src/test/java/com/alibaba/csp/sentinel/annotation/aspectj/integration/service/FooService.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,31 @@ public String baz(String name) {
7676
return "cheers, " + name;
7777
}
7878

79+
@SentinelResource(value = "apiFooWithFallback", blockHandler = "fooBlockHandlerPrivate", fallback = "fooFallbackFuncPrivate",
80+
exceptionsToTrace = {IllegalArgumentException.class})
81+
public String fooWithPrivateFallback(int i) throws Exception {
82+
if (i == 5758) {
83+
throw new IllegalAccessException();
84+
}
85+
if (i == 5763) {
86+
throw new IllegalArgumentException();
87+
}
88+
return "Hello for " + i;
89+
}
90+
7991
public String fooBlockHandler(int i, BlockException ex) {
8092
return "Oops, " + i;
8193
}
8294

8395
public String fooFallbackFunc(int i) {
8496
return "eee...";
8597
}
98+
99+
private String fooFallbackFuncPrivate(int i) {
100+
return "EEE...";
101+
}
102+
103+
private String fooBlockHandlerPrivate(int i, BlockException ex) {
104+
return "Oops, " + i;
105+
}
86106
}

0 commit comments

Comments
 (0)