Quellcode durchsuchen

Fix NPE bug and improve default fallback in Dubbo 2.7.x adapter

- Fix NPE bug in consumer filter (when non-biz error occurred)
- Improve default fallback in Dubbo 2.7.x adapter: convert the BlockException to a simple RuntimeException (with necessary message)
- Polish code and comments

Signed-off-by: Eric Zhao <sczyh16@gmail.com>
master
Eric Zhao Jason Joo vor 4 Jahren
Ursprung
Commit
5905874dd8
9 geänderte Dateien mit 59 neuen und 82 gelöschten Zeilen
  1. +4
    -4
      sentinel-adapter/sentinel-apache-dubbo-adapter/README.md
  2. +1
    -2
      sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/BaseSentinelDubboFilter.java
  3. +20
    -15
      sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilter.java
  4. +3
    -2
      sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilter.java
  5. +0
    -12
      sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/config/DubboAdapterGlobalConfig.java
  6. +2
    -2
      sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DefaultDubboFallback.java
  7. +2
    -8
      sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallbackRegistry.java
  8. +19
    -31
      sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilterTest.java
  9. +8
    -6
      sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallbackRegistryTest.java

+ 4
- 4
sentinel-adapter/sentinel-apache-dubbo-adapter/README.md Datei anzeigen

@@ -1,4 +1,4 @@
# Sentinel Apache Dubbo Adapter
# Sentinel Apache Dubbo Adapter (for 2.7.x+)


> Note: 中文文档请见[此处](https://github.com/alibaba/Sentinel/wiki/主流框架的适配#dubbo)。 > Note: 中文文档请见[此处](https://github.com/alibaba/Sentinel/wiki/主流框架的适配#dubbo)。


@@ -21,7 +21,7 @@ To use Sentinel Dubbo Adapter, you can simply add the following dependency to yo
The Sentinel filters are **enabled by default**. Once you add the dependency, The Sentinel filters are **enabled by default**. Once you add the dependency,
the Dubbo services and methods will become protected resources in Sentinel, the Dubbo services and methods will become protected resources in Sentinel,
which can leverage Sentinel's flow control and guard ability when rules are configured. which can leverage Sentinel's flow control and guard ability when rules are configured.
Demos can be found in [sentinel-demo-dubbo](https://github.com/alibaba/Sentinel/tree/master/sentinel-demo/sentinel-demo-dubbo).
Demos can be found in [sentinel-demo-apache-dubbo](https://github.com/alibaba/Sentinel/tree/master/sentinel-demo/sentinel-demo-apache-dubbo).


If you don't want the filters enabled, you can manually disable them. For example: If you don't want the filters enabled, you can manually disable them. For example:


@@ -37,8 +37,8 @@ For more details of Dubbo filter, see [here](http://dubbo.apache.org/en-us/docs/


The resource for Dubbo services has two granularities: service interface and service method. The resource for Dubbo services has two granularities: service interface and service method.


- Service interface:resourceName format is `interfaceName`,e.g. `com.alibaba.csp.sentinel.demo.dubbo.FooService`
- Service method:resourceName format is `interfaceName:methodSignature`,e.g. `com.alibaba.csp.sentinel.demo.dubbo.FooService:sayHello(java.lang.String)`
- Service interface: resourceName format is `interfaceName`, e.g. `com.alibaba.csp.sentinel.demo.dubbo.FooService`
- Service method: resourceName format is `interfaceName:methodSignature`, e.g. `com.alibaba.csp.sentinel.demo.dubbo.FooService:sayHello(java.lang.String)`


## Flow control based on caller ## Flow control based on caller




+ 1
- 2
sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/BaseSentinelDubboFilter.java Datei anzeigen

@@ -21,11 +21,10 @@ import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Invoker;


/** /**
* Base Class of the {@link SentinelDubboProviderFilter} and {@link SentinelDubboConsumerFilter}.
* Base class of the {@link SentinelDubboProviderFilter} and {@link SentinelDubboConsumerFilter}.
* *
* @author Zechao Zheng * @author Zechao Zheng
*/ */

public abstract class BaseSentinelDubboFilter implements Filter { public abstract class BaseSentinelDubboFilter implements Filter {






+ 20
- 15
sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilter.java Datei anzeigen

@@ -19,11 +19,13 @@ import com.alibaba.csp.sentinel.*;
import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboAdapterGlobalConfig; import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboAdapterGlobalConfig;
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 org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*; import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.support.RpcUtils; import org.apache.dubbo.rpc.support.RpcUtils;


import java.util.LinkedList; import java.util.LinkedList;
import java.util.Optional;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;


import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER; import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
@@ -38,6 +40,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
* *
* @author Carpenter Lee * @author Carpenter Lee
* @author Eric Zhao * @author Eric Zhao
* @author Lin Liang
*/ */
@Activate(group = CONSUMER) @Activate(group = CONSUMER)
public class SentinelDubboConsumerFilter extends BaseSentinelDubboFilter { public class SentinelDubboConsumerFilter extends BaseSentinelDubboFilter {
@@ -64,7 +67,6 @@ public class SentinelDubboConsumerFilter extends BaseSentinelDubboFilter {
} else { } else {
return asyncInvoke(invoker, invocation); return asyncInvoke(invoker, invocation);
} }

} }


private Result syncInvoke(Invoker<?> invoker, Invocation invocation) { private Result syncInvoke(Invoker<?> invoker, Invocation invocation) {
@@ -75,7 +77,8 @@ public class SentinelDubboConsumerFilter extends BaseSentinelDubboFilter {
String methodResourceName = getMethodName(invoker, invocation, prefix); String methodResourceName = getMethodName(invoker, invocation, prefix);
try { try {
interfaceEntry = SphU.entry(interfaceResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT); interfaceEntry = SphU.entry(interfaceResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT);
methodEntry = SphU.entry(methodResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT, invocation.getArguments());
methodEntry = SphU.entry(methodResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT,
invocation.getArguments());
Result result = invoker.invoke(invocation); Result result = invoker.invoke(invocation);
if (result.hasException()) { if (result.hasException()) {
Tracer.traceEntry(result.getException(), interfaceEntry); Tracer.traceEntry(result.getException(), interfaceEntry);
@@ -98,24 +101,27 @@ public class SentinelDubboConsumerFilter extends BaseSentinelDubboFilter {
} }
} }



private Result asyncInvoke(Invoker<?> invoker, Invocation invocation) { private Result asyncInvoke(Invoker<?> invoker, Invocation invocation) {
LinkedList<EntryHolder> queue = new LinkedList<>(); LinkedList<EntryHolder> queue = new LinkedList<>();
String prefix = DubboAdapterGlobalConfig.getDubboConsumerResNamePrefixKey(); String prefix = DubboAdapterGlobalConfig.getDubboConsumerResNamePrefixKey();
String interfaceResourceName = getInterfaceName(invoker, prefix); String interfaceResourceName = getInterfaceName(invoker, prefix);
String methodResourceName = getMethodName(invoker, invocation, prefix); String methodResourceName = getMethodName(invoker, invocation, prefix);
try { try {
queue.push(new EntryHolder(SphU.asyncEntry(interfaceResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT), null));
queue.push(new EntryHolder(SphU.asyncEntry(methodResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT, 1, invocation.getArguments()), invocation.getArguments()));
queue.push(new EntryHolder(
SphU.asyncEntry(interfaceResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT), null));
queue.push(new EntryHolder(
SphU.asyncEntry(methodResourceName, ResourceTypeConstants.COMMON_RPC,
EntryType.OUT, 1, invocation.getArguments()), invocation.getArguments()));
Result result = invoker.invoke(invocation); Result result = invoker.invoke(invocation);
result.whenCompleteWithContext(new BiConsumer<Result, Throwable>() {
@Override
public void accept(Result result, Throwable throwable) {
while (!queue.isEmpty()) {
EntryHolder holder = queue.pop();
Tracer.traceEntry(result.getException(), holder.entry);
exitEntry(holder);
}
result.whenCompleteWithContext((r, throwable) -> {
Throwable error = throwable;
if (error == null) {
error = Optional.ofNullable(r).map(Result::getException).orElse(null);
}
while (!queue.isEmpty()) {
EntryHolder holder = queue.pop();
Tracer.traceEntry(error, holder.entry);
exitEntry(holder);
} }
}); });
return result; return result;
@@ -127,10 +133,9 @@ public class SentinelDubboConsumerFilter extends BaseSentinelDubboFilter {
} }
} }


class EntryHolder {
static class EntryHolder {


final private Entry entry; final private Entry entry;

final private Object[] params; final private Object[] params;


public EntryHolder(Entry entry, Object[] params) { public EntryHolder(Entry entry, Object[] params) {


+ 3
- 2
sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilter.java Datei anzeigen

@@ -20,6 +20,7 @@ import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboAdapterGlobalConfig;
import com.alibaba.csp.sentinel.context.ContextUtil; import com.alibaba.csp.sentinel.context.ContextUtil;
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 org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Invoker;
@@ -74,7 +75,8 @@ public class SentinelDubboProviderFilter extends BaseSentinelDubboFilter {
// at entrance of invocation chain only (for inbound traffic). // at entrance of invocation chain only (for inbound traffic).
ContextUtil.enter(methodResourceName, origin); ContextUtil.enter(methodResourceName, origin);
interfaceEntry = SphU.entry(interfaceResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.IN); interfaceEntry = SphU.entry(interfaceResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.IN);
methodEntry = SphU.entry(methodResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.IN, invocation.getArguments());
methodEntry = SphU.entry(methodResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.IN,
invocation.getArguments());
Result result = invoker.invoke(invocation); Result result = invoker.invoke(invocation);
if (result.hasException()) { if (result.hasException()) {
Tracer.traceEntry(result.getException(), interfaceEntry); Tracer.traceEntry(result.getException(), interfaceEntry);
@@ -98,6 +100,5 @@ public class SentinelDubboProviderFilter extends BaseSentinelDubboFilter {
} }
} }



} }



+ 0
- 12
sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/config/DubboAdapterGlobalConfig.java Datei anzeigen

@@ -43,13 +43,11 @@ public final class DubboAdapterGlobalConfig {
private static final String DEFAULT_DUBBO_CONSUMER_PREFIX = "dubbo:consumer:"; private static final String DEFAULT_DUBBO_CONSUMER_PREFIX = "dubbo:consumer:";


public static final String DUBBO_INTERFACE_GROUP_VERSION_ENABLED = "csp.sentinel.dubbo.interface.group.version.enabled"; public static final String DUBBO_INTERFACE_GROUP_VERSION_ENABLED = "csp.sentinel.dubbo.interface.group.version.enabled";
public static final String TRACE_BIZ_EXCEPTION_ENABLED = "csp.sentinel.dubbo.trace.biz.exception.enabled";


private static volatile DubboFallback consumerFallback = new DefaultDubboFallback(); private static volatile DubboFallback consumerFallback = new DefaultDubboFallback();
private static volatile DubboFallback providerFallback = new DefaultDubboFallback(); private static volatile DubboFallback providerFallback = new DefaultDubboFallback();
private static volatile DubboOriginParser originParser = new DefaultDubboOriginParser(); private static volatile DubboOriginParser originParser = new DefaultDubboOriginParser();



public static boolean isUsePrefix() { public static boolean isUsePrefix() {
return TRUE_STR.equalsIgnoreCase(SentinelConfig.getConfig(DUBBO_RES_NAME_WITH_PREFIX_KEY)); return TRUE_STR.equalsIgnoreCase(SentinelConfig.getConfig(DUBBO_RES_NAME_WITH_PREFIX_KEY));
} }
@@ -74,16 +72,6 @@ public final class DubboAdapterGlobalConfig {
return TRUE_STR.equalsIgnoreCase(SentinelConfig.getConfig(DUBBO_INTERFACE_GROUP_VERSION_ENABLED)); return TRUE_STR.equalsIgnoreCase(SentinelConfig.getConfig(DUBBO_INTERFACE_GROUP_VERSION_ENABLED));
} }


public static Boolean getDubboBizExceptionTraceEnabled() {
String traceBizExceptionEnabled = SentinelConfig.getConfig(TRACE_BIZ_EXCEPTION_ENABLED);
if (StringUtil.isNotBlank(traceBizExceptionEnabled)) {
return TRUE_STR.equalsIgnoreCase(traceBizExceptionEnabled);
}
return true;
}



public static DubboFallback getConsumerFallback() { public static DubboFallback getConsumerFallback() {
return consumerFallback; return consumerFallback;
} }


+ 2
- 2
sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DefaultDubboFallback.java Datei anzeigen

@@ -16,7 +16,7 @@
package com.alibaba.csp.sentinel.adapter.dubbo.fallback; package com.alibaba.csp.sentinel.adapter.dubbo.fallback;


import com.alibaba.csp.sentinel.slots.block.BlockException; import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.SentinelRpcException;
import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.AsyncRpcResult;
import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Invoker;
@@ -30,6 +30,6 @@ public class DefaultDubboFallback implements DubboFallback {
@Override @Override
public Result handle(Invoker<?> invoker, Invocation invocation, BlockException ex) { public Result handle(Invoker<?> invoker, Invocation invocation, BlockException ex) {
// Just wrap the exception. // Just wrap the exception.
return AsyncRpcResult.newDefaultAsyncResult(null, new SentinelRpcException(ex), invocation);
return AsyncRpcResult.newDefaultAsyncResult(ex.toRuntimeException(), invocation);
} }
} }

+ 2
- 8
sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallbackRegistry.java Datei anzeigen

@@ -16,18 +16,14 @@
package com.alibaba.csp.sentinel.adapter.dubbo.fallback; package com.alibaba.csp.sentinel.adapter.dubbo.fallback;


import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboAdapterGlobalConfig; import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboAdapterGlobalConfig;
import com.alibaba.csp.sentinel.util.AssertUtil;


/** /**
* <p>Global fallback registry for Dubbo.</p> * <p>Global fallback registry for Dubbo.</p>
* *
* <p>
* Note: Circuit breaking is mainly designed for consumer. The provider should not
* give fallback result in most circumstances.
* </p>
*
* @author Eric Zhao * @author Eric Zhao
* @deprecated use {@link DubboAdapterGlobalConfig} instead since 1.8.0.
*/ */
@Deprecated
public final class DubboFallbackRegistry { public final class DubboFallbackRegistry {


public static DubboFallback getConsumerFallback() { public static DubboFallback getConsumerFallback() {
@@ -35,7 +31,6 @@ public final class DubboFallbackRegistry {
} }


public static void setConsumerFallback(DubboFallback consumerFallback) { public static void setConsumerFallback(DubboFallback consumerFallback) {
AssertUtil.notNull(consumerFallback, "consumerFallback cannot be null");
DubboAdapterGlobalConfig.setConsumerFallback(consumerFallback); DubboAdapterGlobalConfig.setConsumerFallback(consumerFallback);
} }


@@ -44,7 +39,6 @@ public final class DubboFallbackRegistry {
} }


public static void setProviderFallback(DubboFallback providerFallback) { public static void setProviderFallback(DubboFallback providerFallback) {
AssertUtil.notNull(providerFallback, "providerFallback cannot be null");
DubboAdapterGlobalConfig.setProviderFallback(providerFallback); DubboAdapterGlobalConfig.setProviderFallback(providerFallback);
} }




+ 19
- 31
sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilterTest.java Datei anzeigen

@@ -19,6 +19,7 @@ import com.alibaba.csp.sentinel.BaseTest;
import com.alibaba.csp.sentinel.DubboTestUtil; import com.alibaba.csp.sentinel.DubboTestUtil;
import com.alibaba.csp.sentinel.Entry; import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.EntryType; import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboAdapterGlobalConfig;
import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DubboFallback; import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DubboFallback;
import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DubboFallbackRegistry; import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DubboFallbackRegistry;
import com.alibaba.csp.sentinel.context.Context; import com.alibaba.csp.sentinel.context.Context;
@@ -34,6 +35,7 @@ import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;

import org.apache.dubbo.rpc.*; import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.support.RpcUtils; import org.apache.dubbo.rpc.support.RpcUtils;
import org.junit.After; import org.junit.After;
@@ -53,8 +55,7 @@ import static org.mockito.Mockito.*;
*/ */
public class SentinelDubboConsumerFilterTest extends BaseTest { public class SentinelDubboConsumerFilterTest extends BaseTest {


private SentinelDubboConsumerFilter consumerFilter = new SentinelDubboConsumerFilter();

private final SentinelDubboConsumerFilter consumerFilter = new SentinelDubboConsumerFilter();


@Before @Before
public void setUp() { public void setUp() {
@@ -67,7 +68,6 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
cleanUpAll(); cleanUpAll();
} }



@Test @Test
public void testInterfaceLevelFollowControlAsync() throws InterruptedException { public void testInterfaceLevelFollowControlAsync() throws InterruptedException {


@@ -105,7 +105,6 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
verifyInvocationStructureForCallFinish(invoker, invocation); verifyInvocationStructureForCallFinish(invoker, invocation);
assertEquals("normal", result.getValue()); assertEquals("normal", result.getValue());



// inc the clusterNode's exception to trigger the fallback // inc the clusterNode's exception to trigger the fallback
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
invokeDubboRpc(true, invoker, invocation); invokeDubboRpc(true, invoker, invocation);
@@ -153,7 +152,6 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
assertNull(context); assertNull(context);
} }



@Test @Test
public void testMethodFlowControlAsync() { public void testMethodFlowControlAsync() {


@@ -175,10 +173,8 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
assertEquals("fallback", fallback.getValue()); assertEquals("fallback", fallback.getValue());
verifyInvocationStructureForCallFinish(invoker, invocation); verifyInvocationStructureForCallFinish(invoker, invocation);



} }



@Test @Test
public void testInvokeAsync() { public void testInvokeAsync() {


@@ -190,7 +186,7 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
when(result.hasException()).thenReturn(false); when(result.hasException()).thenReturn(false);
when(invoker.invoke(invocation)).thenAnswer(invocationOnMock -> { when(invoker.invoke(invocation)).thenAnswer(invocationOnMock -> {
verifyInvocationStructureForAsyncCall(invoker, invocation); verifyInvocationStructureForAsyncCall(invoker, invocation);
return result;
return result;
}); });
consumerFilter.invoke(invoker, invocation); consumerFilter.invoke(invoker, invocation);
verify(invoker).invoke(invocation); verify(invoker).invoke(invocation);
@@ -220,7 +216,6 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
assertNull(context); assertNull(context);
} }



/** /**
* Simply verify invocation structure in memory: * Simply verify invocation structure in memory:
* EntranceNode(defaultContextName) * EntranceNode(defaultContextName)
@@ -231,7 +226,8 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
Context context = ContextUtil.getContext(); Context context = ContextUtil.getContext();
assertNotNull(context); assertNotNull(context);
// As not call ContextUtil.enter(resourceName, application) in SentinelDubboConsumerFilter, use default context // As not call ContextUtil.enter(resourceName, application) in SentinelDubboConsumerFilter, use default context
// In actual project, a consumer is usually also a provider, the context will be created by SentinelDubboProviderFilter
// In actual project, a consumer is usually also a provider, the context will be created by
//SentinelDubboProviderFilter
// If consumer is on the top of Dubbo RPC invocation chain, use default context // If consumer is on the top of Dubbo RPC invocation chain, use default context
String resourceName = consumerFilter.getMethodName(invoker, invocation, null); String resourceName = consumerFilter.getMethodName(invoker, invocation, null);
assertEquals(com.alibaba.csp.sentinel.Constants.CONTEXT_DEFAULT_NAME, context.getName()); assertEquals(com.alibaba.csp.sentinel.Constants.CONTEXT_DEFAULT_NAME, context.getName());
@@ -269,7 +265,8 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
// Verify clusterNode // Verify clusterNode
ClusterNode methodClusterNode = methodNode.getClusterNode(); ClusterNode methodClusterNode = methodNode.getClusterNode();
ClusterNode interfaceClusterNode = interfaceNode.getClusterNode(); ClusterNode interfaceClusterNode = interfaceNode.getClusterNode();
assertNotSame(methodClusterNode, interfaceClusterNode);// Different resource->Different ProcessorSlot->Different ClusterNode
assertNotSame(methodClusterNode,
interfaceClusterNode);// Different resource->Different ProcessorSlot->Different ClusterNode


// As context origin is "", the StatisticNode should not be created in originCountMap of ClusterNode // As context origin is "", the StatisticNode should not be created in originCountMap of ClusterNode
Map<String, StatisticNode> methodOriginCountMap = methodClusterNode.getOriginCountMap(); Map<String, StatisticNode> methodOriginCountMap = methodClusterNode.getOriginCountMap();
@@ -284,7 +281,8 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
assertNotNull(context); assertNotNull(context);


// As not call ContextUtil.enter(resourceName, application) in SentinelDubboConsumerFilter, use default context // As not call ContextUtil.enter(resourceName, application) in SentinelDubboConsumerFilter, use default context
// In actual project, a consumer is usually also a provider, the context will be created by SentinelDubboProviderFilter
// In actual project, a consumer is usually also a provider, the context will be created by
//SentinelDubboProviderFilter
// If consumer is on the top of Dubbo RPC invocation chain, use default context // If consumer is on the top of Dubbo RPC invocation chain, use default context
String resourceName = consumerFilter.getMethodName(invoker, invocation, null); String resourceName = consumerFilter.getMethodName(invoker, invocation, null);
assertEquals(com.alibaba.csp.sentinel.Constants.CONTEXT_DEFAULT_NAME, context.getName()); assertEquals(com.alibaba.csp.sentinel.Constants.CONTEXT_DEFAULT_NAME, context.getName());
@@ -319,7 +317,8 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
// Verify clusterNode // Verify clusterNode
ClusterNode methodClusterNode = methodNode.getClusterNode(); ClusterNode methodClusterNode = methodNode.getClusterNode();
ClusterNode interfaceClusterNode = interfaceNode.getClusterNode(); ClusterNode interfaceClusterNode = interfaceNode.getClusterNode();
assertNotSame(methodClusterNode, interfaceClusterNode);// Different resource->Different ProcessorSlot->Different ClusterNode
assertNotSame(methodClusterNode,
interfaceClusterNode);// Different resource->Different ProcessorSlot->Different ClusterNode


// As context origin is "", the StatisticNode should not be created in originCountMap of ClusterNode // As context origin is "", the StatisticNode should not be created in originCountMap of ClusterNode
Map<String, StatisticNode> methodOriginCountMap = methodClusterNode.getOriginCountMap(); Map<String, StatisticNode> methodOriginCountMap = methodClusterNode.getOriginCountMap();
@@ -329,7 +328,6 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
assertEquals(0, interfaceOriginCountMap.size()); assertEquals(0, interfaceOriginCountMap.size());
} }



private void verifyInvocationStructureForCallFinish(Invoker invoker, Invocation invocation) { private void verifyInvocationStructureForCallFinish(Invoker invoker, Invocation invocation) {
Context context = ContextUtil.getContext(); Context context = ContextUtil.getContext();
assertNull(context); assertNull(context);
@@ -338,7 +336,6 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
assertNull(entries); assertNull(entries);
} }



private DefaultNode getNode(String resourceName, DefaultNode root) { private DefaultNode getNode(String resourceName, DefaultNode root) {


Queue<DefaultNode> queue = new LinkedList<>(); Queue<DefaultNode> queue = new LinkedList<>();
@@ -355,7 +352,6 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
return null; return null;
} }



private void initFlowRule(String resource) { private void initFlowRule(String resource) {
FlowRule flowRule = new FlowRule(resource); FlowRule flowRule = new FlowRule(resource);
flowRule.setCount(1); flowRule.setCount(1);
@@ -367,24 +363,18 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {


private void initDegradeRule(String resource) { private void initDegradeRule(String resource) {
DegradeRule degradeRule = new DegradeRule(resource) DegradeRule degradeRule = new DegradeRule(resource)
.setCount(0.5)
.setGrade(DEGRADE_GRADE_EXCEPTION_RATIO);
.setCount(0.5)
.setGrade(DEGRADE_GRADE_EXCEPTION_RATIO);
List<DegradeRule> degradeRules = new ArrayList<>(); List<DegradeRule> degradeRules = new ArrayList<>();
degradeRules.add(degradeRule); degradeRules.add(degradeRule);
degradeRule.setTimeWindow(1); degradeRule.setTimeWindow(1);
DegradeRuleManager.loadRules(degradeRules); DegradeRuleManager.loadRules(degradeRules);
} }



private void initFallback() { private void initFallback() {
DubboFallbackRegistry.setConsumerFallback(new DubboFallback() {
@Override
public Result handle(Invoker<?> invoker, Invocation invocation, BlockException ex) {
boolean async = RpcUtils.isAsync(invoker.getUrl(), invocation);
Result fallbackResult = null;
fallbackResult = AsyncRpcResult.newDefaultAsyncResult("fallback", invocation);
return fallbackResult;
}
DubboAdapterGlobalConfig.setConsumerFallback((invoker, invocation, ex) -> {
// boolean async = RpcUtils.isAsync(invoker.getUrl(), invocation);
return AsyncRpcResult.newDefaultAsyncResult("fallback", invocation);
}); });
} }


@@ -394,13 +384,11 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
if (InvokeMode.SYNC == invokeMode) { if (InvokeMode.SYNC == invokeMode) {
result = exception ? new AppResponse(new Exception("error")) : new AppResponse("normal"); result = exception ? new AppResponse(new Exception("error")) : new AppResponse("normal");
} else { } else {
result = exception ? AsyncRpcResult.newDefaultAsyncResult(new Exception("error"), invocation) : AsyncRpcResult.newDefaultAsyncResult("normal", invocation);
result = exception ? AsyncRpcResult.newDefaultAsyncResult(new Exception("error"), invocation)
: AsyncRpcResult.newDefaultAsyncResult("normal", invocation);
} }
when(invoker.invoke(invocation)).thenReturn(result); when(invoker.invoke(invocation)).thenReturn(result);
return consumerFilter.invoke(invoker, invocation); return consumerFilter.invoke(invoker, invocation);
} }





} }

+ 8
- 6
sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallbackRegistryTest.java Datei anzeigen

@@ -17,8 +17,8 @@ package com.alibaba.csp.sentinel.adapter.dubbo.fallback;


import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboAdapterGlobalConfig; import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboAdapterGlobalConfig;
import com.alibaba.csp.sentinel.slots.block.BlockException; import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.SentinelRpcException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException; import com.alibaba.csp.sentinel.slots.block.flow.FlowException;

import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.AsyncRpcResult;
import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.Result;
import org.junit.After; import org.junit.After;
@@ -33,12 +33,12 @@ public class DubboFallbackRegistryTest {


@Before @Before
public void setUp() { public void setUp() {
DubboFallbackRegistry.setConsumerFallback(new DefaultDubboFallback());
DubboAdapterGlobalConfig.setConsumerFallback(new DefaultDubboFallback());
} }


@After @After
public void tearDown() { public void tearDown() {
DubboFallbackRegistry.setConsumerFallback(new DefaultDubboFallback());
DubboAdapterGlobalConfig.setConsumerFallback(new DefaultDubboFallback());
} }


@Test @Test
@@ -46,15 +46,17 @@ public class DubboFallbackRegistryTest {
// Test for default fallback. // Test for default fallback.
BlockException ex = new FlowException("xxx"); BlockException ex = new FlowException("xxx");
Result result = new DefaultDubboFallback().handle(null, null, ex); Result result = new DefaultDubboFallback().handle(null, null, ex);
Assert.assertTrue("The invocation should not fail",result.hasException());
Assert.assertEquals(SentinelRpcException.class, result.getException().getClass());
Assert.assertTrue("The result should carry exception", result.hasException());
Assert.assertTrue(BlockException.isBlockException(result.getException()));
Assert.assertTrue(result.getException().getMessage().contains(ex.getClass().getSimpleName()));
} }


@Test @Test
public void testCustomFallback() { public void testCustomFallback() {
BlockException ex = new FlowException("xxx"); BlockException ex = new FlowException("xxx");
DubboAdapterGlobalConfig.setConsumerFallback( DubboAdapterGlobalConfig.setConsumerFallback(
(invoker, invocation, e) -> AsyncRpcResult.newDefaultAsyncResult("Error: " + e.getClass().getName(), invocation));
(invoker, invocation, e) -> AsyncRpcResult
.newDefaultAsyncResult("Error: " + e.getClass().getName(), invocation));
Result result = DubboAdapterGlobalConfig.getConsumerFallback() Result result = DubboAdapterGlobalConfig.getConsumerFallback()
.handle(null, null, ex); .handle(null, null, ex);
Assert.assertFalse("The invocation should not fail", result.hasException()); Assert.assertFalse("The invocation should not fail", result.hasException());


Laden…
Abbrechen
Speichern