Sfoglia il codice sorgente

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 4 anni fa
parent
commit
5905874dd8
9 ha cambiato i file con 59 aggiunte e 82 eliminazioni
  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 Vedi File

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

> 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 Dubbo services and methods will become protected resources in Sentinel,
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:

@@ -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.

- 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



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

@@ -21,11 +21,10 @@ import org.apache.dubbo.rpc.Invocation;
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
*/

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 Vedi File

@@ -19,11 +19,13 @@ import com.alibaba.csp.sentinel.*;
import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboAdapterGlobalConfig;
import com.alibaba.csp.sentinel.log.RecordLog;
import com.alibaba.csp.sentinel.slots.block.BlockException;

import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.support.RpcUtils;

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

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 Eric Zhao
* @author Lin Liang
*/
@Activate(group = CONSUMER)
public class SentinelDubboConsumerFilter extends BaseSentinelDubboFilter {
@@ -64,7 +67,6 @@ public class SentinelDubboConsumerFilter extends BaseSentinelDubboFilter {
} else {
return asyncInvoke(invoker, invocation);
}

}

private Result syncInvoke(Invoker<?> invoker, Invocation invocation) {
@@ -75,7 +77,8 @@ public class SentinelDubboConsumerFilter extends BaseSentinelDubboFilter {
String methodResourceName = getMethodName(invoker, invocation, prefix);
try {
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);
if (result.hasException()) {
Tracer.traceEntry(result.getException(), interfaceEntry);
@@ -98,24 +101,27 @@ public class SentinelDubboConsumerFilter extends BaseSentinelDubboFilter {
}
}


private Result asyncInvoke(Invoker<?> invoker, Invocation invocation) {
LinkedList<EntryHolder> queue = new LinkedList<>();
String prefix = DubboAdapterGlobalConfig.getDubboConsumerResNamePrefixKey();
String interfaceResourceName = getInterfaceName(invoker, prefix);
String methodResourceName = getMethodName(invoker, invocation, prefix);
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.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;
@@ -127,10 +133,9 @@ public class SentinelDubboConsumerFilter extends BaseSentinelDubboFilter {
}
}

class EntryHolder {
static class EntryHolder {

final private Entry entry;

final private 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 Vedi File

@@ -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.log.RecordLog;
import com.alibaba.csp.sentinel.slots.block.BlockException;

import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
@@ -74,7 +75,8 @@ public class SentinelDubboProviderFilter extends BaseSentinelDubboFilter {
// at entrance of invocation chain only (for inbound traffic).
ContextUtil.enter(methodResourceName, origin);
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);
if (result.hasException()) {
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 Vedi File

@@ -43,13 +43,11 @@ public final class DubboAdapterGlobalConfig {
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 TRACE_BIZ_EXCEPTION_ENABLED = "csp.sentinel.dubbo.trace.biz.exception.enabled";

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


public static boolean isUsePrefix() {
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));
}

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() {
return consumerFallback;
}


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

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

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.Invocation;
import org.apache.dubbo.rpc.Invoker;
@@ -30,6 +30,6 @@ public class DefaultDubboFallback implements DubboFallback {
@Override
public Result handle(Invoker<?> invoker, Invocation invocation, BlockException ex) {
// 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 Vedi File

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

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

/**
* <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
* @deprecated use {@link DubboAdapterGlobalConfig} instead since 1.8.0.
*/
@Deprecated
public final class DubboFallbackRegistry {

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

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

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

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



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

@@ -19,6 +19,7 @@ import com.alibaba.csp.sentinel.BaseTest;
import com.alibaba.csp.sentinel.DubboTestUtil;
import com.alibaba.csp.sentinel.Entry;
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.DubboFallbackRegistry;
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.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;

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

private SentinelDubboConsumerFilter consumerFilter = new SentinelDubboConsumerFilter();

private final SentinelDubboConsumerFilter consumerFilter = new SentinelDubboConsumerFilter();

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


@Test
public void testInterfaceLevelFollowControlAsync() throws InterruptedException {

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


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


@Test
public void testMethodFlowControlAsync() {

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


}


@Test
public void testInvokeAsync() {

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


/**
* Simply verify invocation structure in memory:
* EntranceNode(defaultContextName)
@@ -231,7 +226,8 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
Context context = ContextUtil.getContext();
assertNotNull(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
String resourceName = consumerFilter.getMethodName(invoker, invocation, null);
assertEquals(com.alibaba.csp.sentinel.Constants.CONTEXT_DEFAULT_NAME, context.getName());
@@ -269,7 +265,8 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
// Verify clusterNode
ClusterNode methodClusterNode = methodNode.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
Map<String, StatisticNode> methodOriginCountMap = methodClusterNode.getOriginCountMap();
@@ -284,7 +281,8 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
assertNotNull(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
String resourceName = consumerFilter.getMethodName(invoker, invocation, null);
assertEquals(com.alibaba.csp.sentinel.Constants.CONTEXT_DEFAULT_NAME, context.getName());
@@ -319,7 +317,8 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
// Verify clusterNode
ClusterNode methodClusterNode = methodNode.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
Map<String, StatisticNode> methodOriginCountMap = methodClusterNode.getOriginCountMap();
@@ -329,7 +328,6 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
assertEquals(0, interfaceOriginCountMap.size());
}


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


private DefaultNode getNode(String resourceName, DefaultNode root) {

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


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

private void initDegradeRule(String 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<>();
degradeRules.add(degradeRule);
degradeRule.setTimeWindow(1);
DegradeRuleManager.loadRules(degradeRules);
}


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) {
result = exception ? new AppResponse(new Exception("error")) : new AppResponse("normal");
} 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);
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 Vedi File

@@ -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.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.SentinelRpcException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;

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

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

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

@Test
@@ -46,15 +46,17 @@ public class DubboFallbackRegistryTest {
// Test for default fallback.
BlockException ex = new FlowException("xxx");
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
public void testCustomFallback() {
BlockException ex = new FlowException("xxx");
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()
.handle(null, null, ex);
Assert.assertFalse("The invocation should not fail", result.hasException());


Loading…
Annulla
Salva