Browse Source

Polish document and code of Sentinel annotation CDI extension

Signed-off-by: Eric Zhao <sczyh16@gmail.com>
master
Eric Zhao 4 years ago
parent
commit
ba3469b0ac
4 changed files with 32 additions and 23 deletions
  1. +13
    -14
      sentinel-extension/sentinel-annotation-cdi-interceptor/README.md
  2. +14
    -3
      sentinel-extension/sentinel-annotation-cdi-interceptor/src/main/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/AbstractSentinelInterceptorSupport.java
  3. +4
    -6
      sentinel-extension/sentinel-annotation-cdi-interceptor/src/main/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/SentinelResourceBinding.java
  4. +1
    -0
      sentinel-extension/sentinel-annotation-cdi-interceptor/src/main/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/SentinelResourceInterceptor.java

+ 13
- 14
sentinel-extension/sentinel-annotation-cdi-interceptor/README.md View File

@@ -1,26 +1,28 @@
# Sentinel Annotation cdi interceptor
# Sentinel Annotation CDI extension


This extension is an implementation using cdi interceptor for Sentinel annotations. [JSR 318: Enterprise JavaBeansTM 3.1/Interceptors 1.2](https://jcp.org/en/jsr/detail?id=318) define the javax interceptor and [CDI](http://www.cdi-spec.org/) related specifications extends the Java Interceptors specification and allows interceptor bindings to be applied to CDI stereotypes.
This extension is an implementation using CDI interceptor for Sentinel annotations. [JSR 318: Enterprise JavaBeansTM 3.1/Interceptors 1.2](https://jcp.org/en/jsr/detail?id=318) define the javax interceptor and [CDI](http://www.cdi-spec.org/) related specifications extends the Java Interceptors specification and allows interceptor bindings to be applied to CDI stereotypes.


[CDI](http://www.cdi-spec.org/) is an abbreviation for Contexts and Dependency Injection, the related JSRs are : [JSR 365: Contexts and Dependency Injection for JavaTM 2.0](https://jcp.org/en/jsr/detail?id=365), [JSR 346: Contexts and Dependency Injection for JavaTM EE 1.1](https://jcp.org/en/jsr/detail?id=346), [JSR 299: Contexts and Dependency Injection for the JavaTM EE platform](https://jcp.org/en/jsr/detail?id=299) [CDI](http://www.cdi-spec.org/) is an abbreviation for Contexts and Dependency Injection, the related JSRs are : [JSR 365: Contexts and Dependency Injection for JavaTM 2.0](https://jcp.org/en/jsr/detail?id=365), [JSR 346: Contexts and Dependency Injection for JavaTM EE 1.1](https://jcp.org/en/jsr/detail?id=346), [JSR 299: Contexts and Dependency Injection for the JavaTM EE platform](https://jcp.org/en/jsr/detail?id=299)


## Annotation ## Annotation


The `@SentinelResourceBinding` is modified from `@SentinelResource` by adding `@InterceptorBinding` for CDI specification, and in order to interceptor all kinds of `@SentinelResourceBinding` with different attributes in one interceptor, `@SentinelResourceBinding`'s all attribute is annotated by `@Nonbinding`
The `@SentinelResourceBinding` is modified from `@SentinelResource` by adding `@InterceptorBinding` for CDI specification,
and in order to intercept all kinds of `@SentinelResourceBinding` with different attributes in one interceptor,
all attributes of `@SentinelResourceBinding` are annotated with `@Nonbinding`.


The `@SentinelResource` annotation indicates a resource definition, including:
The `@SentinelResourceBinding` annotation indicates a resource definition, including:


- `value`: Resource name, required (cannot be empty) - `value`: Resource name, required (cannot be empty)
- `entryType`: Resource entry type (inbound or outbound), `EntryType.OUT` by default
- `fallback` (refactored since 1.6.0): Fallback method when exceptions caught (including `BlockException`, but except the exceptions defined in `exceptionsToIgnore`). The fallback method should be located in the same class with original method by default. If you want to use method in other classes, you can set the `fallbackClass` with corresponding `Class` (Note the method in other classes must be *static*). The method signature requirement:
- `entryType`: Traffic type (inbound or outbound), `EntryType.OUT` by default
- `fallback`: Fallback method when exceptions caught (including `BlockException`, but except the exceptions defined in `exceptionsToIgnore`). The fallback method should be located in the same class with original method by default. If you want to use method in other classes, you can set the `fallbackClass` with corresponding `Class` (Note the method in other classes must be *static*). The method signature requirement:
- The return type should match the origin method; - The return type should match the origin method;
- The parameter list should match the origin method, and an additional `Throwable` parameter can be provided to get the actual exception. - The parameter list should match the origin method, and an additional `Throwable` parameter can be provided to get the actual exception.
- `defaultFallback` (since 1.6.0): The default fallback method when exceptions caught (including `BlockException`, but except the exceptions defined in `exceptionsToIgnore`). Its intended to be a universal common fallback method. The method should be located in the same class with original method by default. If you want to use method in other classes, you can set the `fallbackClass` with corresponding `Class` (Note the method in other classes must be *static*). The default fallback method signature requirement:
- `defaultFallback`: The default fallback method when exceptions caught (including `BlockException`, but except the exceptions defined in `exceptionsToIgnore`). Its intended to be a universal common fallback method. The method should be located in the same class with original method by default. If you want to use method in other classes, you can set the `fallbackClass` with corresponding `Class` (Note the method in other classes must be *static*). The default fallback method signature requirement:
- The return type should match the origin method; - The return type should match the origin method;
- parameter list should be empty, and an additional `Throwable` parameter can be provided to get the actual exception. - parameter list should be empty, and an additional `Throwable` parameter can be provided to get the actual exception.
- `blockHandler`: Handler method that handles `BlockException` when blocked. The parameter list of the method should match original method, with the last additional parameter type `BlockException`. The return type should be same as the original method. The `blockHandler` method should be located in the same class with original method by default. If you want to use method in other classes, you can set the `blockHandlerClass` with corresponding `Class` (Note the method in other classes must be *static*). - `blockHandler`: Handler method that handles `BlockException` when blocked. The parameter list of the method should match original method, with the last additional parameter type `BlockException`. The return type should be same as the original method. The `blockHandler` method should be located in the same class with original method by default. If you want to use method in other classes, you can set the `blockHandlerClass` with corresponding `Class` (Note the method in other classes must be *static*).
- `exceptionsToIgnore` (since 1.6.0): List of business exception classes that should not be traced and caught in fallback.
- `exceptionsToTrace` (since 1.5.1): List of business exception classes to trace and record. In most cases, using `exceptionsToIgnore` is better. If both `exceptionsToTrace` and `exceptionsToIgnore` are present, only `exceptionsToIgnore` will be activated.
- `exceptionsToIgnore`: List of business exception classes that should not be traced and caught in fallback.
- `exceptionsToTrace`: List of business exception classes to trace and record. In most cases, using `exceptionsToIgnore` is better. If both `exceptionsToTrace` and `exceptionsToIgnore` are present, only `exceptionsToIgnore` will be activated.


For example: For example:


@@ -42,7 +44,8 @@ public String defaultFallback(Throwable t) {


## Configuration ## Configuration


according to [9.4. Interceptor enablement and ordering](https://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#enabled_interceptors) to enable interceptor, it should be configured in resources/META-INF/beans.xml :
According to [9.4. Interceptor enablement and ordering](https://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#enabled_interceptors), to enable the interceptor,
we may add configuration in `resources/META-INF/beans.xml` like this:


``` ```
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
@@ -54,7 +57,3 @@ according to [9.4. Interceptor enablement and ordering](https://docs.jboss.org/c
</interceptors> </interceptors>
</beans> </beans>
``` ```





+ 14
- 3
sentinel-extension/sentinel-annotation-cdi-interceptor/src/main/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/AbstractSentinelInterceptorSupport.java View File

@@ -16,21 +16,24 @@
package com.alibaba.csp.sentinel.annotation.cdi.interceptor; package com.alibaba.csp.sentinel.annotation.cdi.interceptor;


import com.alibaba.csp.sentinel.Tracer; import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.log.RecordLog; import com.alibaba.csp.sentinel.log.RecordLog;
import com.alibaba.csp.sentinel.slots.block.BlockException; import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.util.MethodUtil; import com.alibaba.csp.sentinel.util.MethodUtil;
import com.alibaba.csp.sentinel.util.StringUtil; import com.alibaba.csp.sentinel.util.StringUtil;


import javax.interceptor.InvocationContext; import javax.interceptor.InvocationContext;

import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.Arrays; import java.util.Arrays;


/** /**
* Some common functions for Sentinel annotation aspect.
* Some common functions for Sentinel annotation CDI extension.
* *
* @author Eric Zhao * @author Eric Zhao
* @author seasidesky
*/ */
public abstract class AbstractSentinelInterceptorSupport { public abstract class AbstractSentinelInterceptorSupport {


@@ -184,7 +187,15 @@ public abstract class AbstractSentinelInterceptorSupport {
private Method extractDefaultFallbackMethod(InvocationContext ctx, String defaultFallback, private Method extractDefaultFallbackMethod(InvocationContext ctx, String defaultFallback,
Class<?>[] locationClass) { Class<?>[] locationClass) {
if (StringUtil.isBlank(defaultFallback)) { if (StringUtil.isBlank(defaultFallback)) {
return null;
SentinelResource annotationClass = ctx.getTarget().getClass().getAnnotation(SentinelResource.class);
if (annotationClass != null && StringUtil.isNotBlank(annotationClass.defaultFallback())) {
defaultFallback = annotationClass.defaultFallback();
if (locationClass == null || locationClass.length < 1) {
locationClass = annotationClass.fallbackClass();
}
} else {
return null;
}
} }
boolean mustStatic = locationClass != null && locationClass.length >= 1; boolean mustStatic = locationClass != null && locationClass.length >= 1;
Class<?> clazz = mustStatic ? locationClass[0] : ctx.getTarget().getClass(); Class<?> clazz = mustStatic ? locationClass[0] : ctx.getTarget().getClass();
@@ -302,7 +313,7 @@ public abstract class AbstractSentinelInterceptorSupport {
Class<?> targetClass = ctx.getTarget().getClass(); Class<?> targetClass = ctx.getTarget().getClass();


Method method = getDeclaredMethodFor(targetClass, ctx.getMethod().getName(), Method method = getDeclaredMethodFor(targetClass, ctx.getMethod().getName(),
ctx.getMethod().getParameterTypes());
ctx.getMethod().getParameterTypes());
if (method == null) { if (method == null) {
throw new IllegalStateException("Cannot resolve target method: " + ctx.getMethod().getName()); throw new IllegalStateException("Cannot resolve target method: " + ctx.getMethod().getName());
} }


+ 4
- 6
sentinel-extension/sentinel-annotation-cdi-interceptor/src/main/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/SentinelResourceBinding.java View File

@@ -19,15 +19,18 @@ import com.alibaba.csp.sentinel.EntryType;


import javax.enterprise.util.Nonbinding; import javax.enterprise.util.Nonbinding;
import javax.interceptor.InterceptorBinding; import javax.interceptor.InterceptorBinding;

import java.lang.annotation.*; import java.lang.annotation.*;


/** /**
* The annotation indicates a definition of Sentinel resource. * The annotation indicates a definition of Sentinel resource.
* *
* @author Eric Zhao * @author Eric Zhao
* @author seasidesky
* @since 1.8.0
*/ */
@InterceptorBinding @InterceptorBinding
@Target({ ElementType.METHOD, ElementType.TYPE })
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Inherited @Inherited
public @interface SentinelResourceBinding { public @interface SentinelResourceBinding {
@@ -46,7 +49,6 @@ public @interface SentinelResourceBinding {


/** /**
* @return the classification (type) of the resource * @return the classification (type) of the resource
* @since 1.7.0
*/ */
@Nonbinding @Nonbinding
int resourceType() default 0; int resourceType() default 0;
@@ -80,7 +82,6 @@ public @interface SentinelResourceBinding {
* with the original method. * with the original method.
* *
* @return name of the default fallback method, empty by default * @return name of the default fallback method, empty by default
* @since 1.6.0
*/ */
@Nonbinding @Nonbinding
String defaultFallback() default ""; String defaultFallback() default "";
@@ -92,14 +93,12 @@ public @interface SentinelResourceBinding {
* must be static. * must be static.
* *
* @return the class where the fallback method is located (only single class) * @return the class where the fallback method is located (only single class)
* @since 1.6.0
*/ */
@Nonbinding @Nonbinding
Class<?>[] fallbackClass() default {}; Class<?>[] fallbackClass() default {};


/** /**
* @return the list of exception classes to trace, {@link Throwable} by default * @return the list of exception classes to trace, {@link Throwable} by default
* @since 1.5.1
*/ */
@Nonbinding @Nonbinding
Class<? extends Throwable>[] exceptionsToTrace() default {Throwable.class}; Class<? extends Throwable>[] exceptionsToTrace() default {Throwable.class};
@@ -110,7 +109,6 @@ public @interface SentinelResourceBinding {
* will be of higher precedence. * will be of higher precedence.
* *
* @return the list of exception classes to ignore, empty by default * @return the list of exception classes to ignore, empty by default
* @since 1.6.0
*/ */
@Nonbinding @Nonbinding
Class<? extends Throwable>[] exceptionsToIgnore() default {}; Class<? extends Throwable>[] exceptionsToIgnore() default {};


+ 1
- 0
sentinel-extension/sentinel-annotation-cdi-interceptor/src/main/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/SentinelResourceInterceptor.java View File

@@ -27,6 +27,7 @@ import javax.interceptor.InvocationContext;


/** /**
* @author sea * @author sea
* @since 1.8.0
*/ */
@Interceptor @Interceptor
@SentinelResourceBinding @SentinelResourceBinding


Loading…
Cancel
Save