diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/BaseSentinelDubboFilter.java b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/BaseSentinelDubboFilter.java index bc2101ff..d6c964a9 100644 --- a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/BaseSentinelDubboFilter.java +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/BaseSentinelDubboFilter.java @@ -16,13 +16,9 @@ package com.alibaba.csp.sentinel.adapter.dubbo; -import com.alibaba.csp.sentinel.Entry; -import com.alibaba.csp.sentinel.Tracer; -import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboConfig; -import com.alibaba.csp.sentinel.context.ContextUtil; -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.constants.CommonConstants; -import org.apache.dubbo.rpc.*; +import org.apache.dubbo.rpc.Filter; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; /** * Base Class of the {@link SentinelDubboProviderFilter} and {@link SentinelDubboConsumerFilter}. @@ -30,52 +26,25 @@ import org.apache.dubbo.rpc.*; * @author Zechao Zheng */ -public abstract class BaseSentinelDubboFilter extends ListenableFilter { - public BaseSentinelDubboFilter() { - this.listener = new SentinelDubboListener(); - } +public abstract class BaseSentinelDubboFilter implements Filter { - static class SentinelDubboListener implements Listener { - public void onResponse(Result appResponse, Invoker invoker, Invocation invocation) { - onSuccess(appResponse, invoker); - } + /** + * Get method name of dubbo rpc + * + * @param invoker + * @param invocation + * @return + */ + abstract String getMethodName(Invoker invoker, Invocation invocation); - //for compatible dubbo 2.7.5 rename onResponse to onMessage - public void onMessage(Result appResponse, Invoker invoker, Invocation invocation) { - onSuccess(appResponse, invoker); - } + /** + * Get interface name of dubbo rpc + * + * @param invoker + * @return + */ + abstract String getInterfaceName(Invoker invoker); - private void onSuccess(Result appResponse, Invoker invoker) { - if (DubboConfig.getDubboBizExceptionTraceEnabled()) { - traceAndExit(appResponse.getException(), invoker.getUrl()); - } else { - traceAndExit(null, invoker.getUrl()); - } - } - @Override - public void onError(Throwable t, Invoker invoker, Invocation invocation) { - traceAndExit(t, invoker.getUrl()); - } - - } - - static void traceAndExit(Throwable throwable, URL url) { - Entry interfaceEntry = (Entry) RpcContext.getContext().get(DubboUtils.DUBBO_INTERFACE_ENTRY_KEY); - Entry methodEntry = (Entry) RpcContext.getContext().get(DubboUtils.DUBBO_METHOD_ENTRY_KEY); - if (methodEntry != null) { - Tracer.traceEntry(throwable, methodEntry); - methodEntry.exit(); - RpcContext.getContext().remove(DubboUtils.DUBBO_METHOD_ENTRY_KEY); - } - if (interfaceEntry != null) { - Tracer.traceEntry(throwable, interfaceEntry); - interfaceEntry.exit(); - RpcContext.getContext().remove(DubboUtils.DUBBO_INTERFACE_ENTRY_KEY); - } - if (CommonConstants.PROVIDER_SIDE.equals(url.getParameter(CommonConstants.SIDE_KEY))) { - ContextUtil.exit(); - } - } } diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboUtils.java b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboUtils.java index d2c325fa..c2a720d2 100644 --- a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboUtils.java +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboUtils.java @@ -26,8 +26,6 @@ import org.apache.dubbo.rpc.Invoker; public final class DubboUtils { public static final String SENTINEL_DUBBO_APPLICATION_KEY = "dubboApplication"; - public static final String DUBBO_METHOD_ENTRY_KEY = "dubboMethodEntry"; - public static final String DUBBO_INTERFACE_ENTRY_KEY = "dubboInterfaceEntry"; public static String getApplication(Invocation invocation, String defaultValue) { if (invocation == null || invocation.getAttachments() == null) { @@ -69,6 +67,13 @@ public final class DubboUtils { return getResourceName(invoker, invocation, DubboConfig.getDubboInterfaceGroupAndVersionEnabled()); } } + + + public static String getInterfaceName(Invoker invoker) { + return DubboConfig.getDubboInterfaceGroupAndVersionEnabled() ? invoker.getUrl().getColonSeparatedKey() + : invoker.getInterface().getName(); + } + private DubboUtils() { } } diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilter.java b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilter.java index ffa9fba9..3d0e2d4c 100644 --- a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilter.java +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilter.java @@ -19,6 +19,7 @@ import com.alibaba.csp.sentinel.Entry; import com.alibaba.csp.sentinel.EntryType; import com.alibaba.csp.sentinel.ResourceTypeConstants; import com.alibaba.csp.sentinel.SphU; +import com.alibaba.csp.sentinel.Tracer; import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboConfig; import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DubboFallbackRegistry; import com.alibaba.csp.sentinel.log.RecordLog; @@ -28,10 +29,12 @@ import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.InvokeMode; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; -import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.support.RpcUtils; +import java.util.LinkedList; +import java.util.function.BiConsumer; + import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER; /** @@ -52,33 +55,85 @@ public class SentinelDubboConsumerFilter extends BaseSentinelDubboFilter { RecordLog.info("Sentinel Apache Dubbo consumer filter initialized"); } + @Override + String getMethodName(Invoker invoker, Invocation invocation) { + return DubboUtils.getResourceName(invoker, invocation, DubboConfig.getDubboConsumerPrefix()); + } + + @Override + String getInterfaceName(Invoker invoker) { + return DubboUtils.getInterfaceName(invoker); + } + @Override public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { + InvokeMode invokeMode = RpcUtils.getInvokeMode(invoker.getUrl(), invocation); + if (InvokeMode.SYNC == invokeMode) { + return syncInvoke(invoker, invocation); + } else { + return asyncInvoke(invoker, invocation); + } + + } + + private Result syncInvoke(Invoker invoker, Invocation invocation) { Entry interfaceEntry = null; Entry methodEntry = null; - RpcContext rpcContext = RpcContext.getContext(); + String methodResourceName = getMethodName(invoker, invocation); + String interfaceResourceName = getInterfaceName(invoker); try { - String methodResourceName = DubboUtils.getResourceName(invoker, invocation, DubboConfig.getDubboConsumerPrefix()); - String interfaceResourceName = DubboConfig.getDubboInterfaceGroupAndVersionEnabled() ? invoker.getUrl().getColonSeparatedKey() - : invoker.getInterface().getName(); - InvokeMode invokeMode = RpcUtils.getInvokeMode(invoker.getUrl(), invocation); - - if (InvokeMode.SYNC == invokeMode) { - interfaceEntry = SphU.entry(interfaceResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT); - rpcContext.set(DubboUtils.DUBBO_INTERFACE_ENTRY_KEY, interfaceEntry); - methodEntry = SphU.entry(methodResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT, invocation.getArguments()); - } else { - // should generate the AsyncEntry when the invoke model in future or async - interfaceEntry = SphU.asyncEntry(interfaceResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT); - rpcContext.set(DubboUtils.DUBBO_INTERFACE_ENTRY_KEY, interfaceEntry); - methodEntry = SphU.asyncEntry(methodResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT, 1, invocation.getArguments()); + interfaceEntry = SphU.entry(interfaceResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT); + methodEntry = SphU.entry(methodResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT, invocation.getArguments()); + Result result = invoker.invoke(invocation); + if (result.hasException()) { + Tracer.traceEntry(result.getException(), interfaceEntry); + Tracer.traceEntry(result.getException(), methodEntry); } - rpcContext.set(DubboUtils.DUBBO_METHOD_ENTRY_KEY, methodEntry); - return invoker.invoke(invocation); + return result; } catch (BlockException e) { return DubboFallbackRegistry.getConsumerFallback().handle(invoker, invocation, e); + } catch (RpcException e) { + Tracer.traceEntry(e, interfaceEntry); + Tracer.traceEntry(e, methodEntry); + throw e; + } finally { + if (methodEntry != null) { + methodEntry.exit(); + } + if (interfaceEntry != null) { + interfaceEntry.exit(); + } } } + + + private Result asyncInvoke(Invoker invoker, Invocation invocation) { + LinkedList queue = new LinkedList<>(); + String methodResourceName = getMethodName(invoker, invocation); + String interfaceResourceName = getInterfaceName(invoker); + try { + queue.push(SphU.asyncEntry(interfaceResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT)); + queue.push(SphU.asyncEntry(methodResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT, 1, invocation.getArguments())); + Result result = invoker.invoke(invocation); + result.whenCompleteWithContext(new BiConsumer() { + @Override + public void accept(Result result, Throwable throwable) { + while (!queue.isEmpty()) { + Entry entry = queue.pop(); + Tracer.traceEntry(result.getException(), entry); + entry.exit(); + } + } + }); + return result; + } catch (BlockException e) { + while (!queue.isEmpty()) { + queue.pop().exit(); + } + return DubboFallbackRegistry.getConsumerFallback().handle(invoker, invocation, e); + } + } + } diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilter.java b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilter.java index c9199786..99cf8094 100644 --- a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilter.java +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilter.java @@ -19,16 +19,17 @@ import com.alibaba.csp.sentinel.Entry; import com.alibaba.csp.sentinel.EntryType; import com.alibaba.csp.sentinel.ResourceTypeConstants; import com.alibaba.csp.sentinel.SphU; +import com.alibaba.csp.sentinel.Tracer; import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboConfig; import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DubboFallbackRegistry; 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.Filter; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; -import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcException; import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER; @@ -52,27 +53,50 @@ public class SentinelDubboProviderFilter extends BaseSentinelDubboFilter { RecordLog.info("Sentinel Apache Dubbo provider filter initialized"); } + @Override + String getMethodName(Invoker invoker, Invocation invocation) { + return DubboUtils.getResourceName(invoker, invocation, DubboConfig.getDubboProviderPrefix()); + } + + @Override + String getInterfaceName(Invoker invoker) { + return DubboUtils.getInterfaceName(invoker); + } + @Override public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { // Get origin caller. String application = DubboUtils.getApplication(invocation, ""); - RpcContext rpcContext = RpcContext.getContext(); Entry interfaceEntry = null; Entry methodEntry = null; + String methodResourceName = getMethodName(invoker, invocation); + String interfaceResourceName = getInterfaceName(invoker); try { - String methodResourceName = DubboUtils.getResourceName(invoker, invocation, DubboConfig.getDubboProviderPrefix()); - String interfaceResourceName = DubboConfig.getDubboInterfaceGroupAndVersionEnabled() ? invoker.getUrl().getColonSeparatedKey() - : invoker.getInterface().getName(); // Only need to create entrance context at provider side, as context will take effect // at entrance of invocation chain only (for inbound traffic). ContextUtil.enter(methodResourceName, application); interfaceEntry = SphU.entry(interfaceResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.IN); - rpcContext.set(DubboUtils.DUBBO_INTERFACE_ENTRY_KEY, interfaceEntry); methodEntry = SphU.entry(methodResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.IN, invocation.getArguments()); - rpcContext.set(DubboUtils.DUBBO_METHOD_ENTRY_KEY, methodEntry); - return invoker.invoke(invocation); + Result result = invoker.invoke(invocation); + if (result.hasException()) { + Tracer.traceEntry(result.getException(), interfaceEntry); + Tracer.traceEntry(result.getException(), methodEntry); + } + return result; } catch (BlockException e) { return DubboFallbackRegistry.getProviderFallback().handle(invoker, invocation, e); + } catch (RpcException e) { + Tracer.traceEntry(e, interfaceEntry); + Tracer.traceEntry(e, methodEntry); + throw e; + } finally { + if (methodEntry != null) { + methodEntry.exit(1, invocation.getArguments()); + } + if (interfaceEntry != null) { + interfaceEntry.exit(); + } + ContextUtil.exit(); } } diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/BaseTest.java b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/BaseTest.java index 7793a656..46948c57 100644 --- a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/BaseTest.java +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/BaseTest.java @@ -16,25 +16,19 @@ package com.alibaba.csp.sentinel; import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboConfig; -import com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService; +import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DefaultDubboFallback; +import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DubboFallbackRegistry; import com.alibaba.csp.sentinel.config.SentinelConfig; import com.alibaba.csp.sentinel.context.ContextUtil; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; import com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot; -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.constants.CommonConstants; -import org.apache.dubbo.rpc.Invocation; -import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.RpcContext; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - /** * Base test class, provide common methods for subClass * The package is same as CtSph, to call CtSph.resetChainMap() method for test @@ -42,46 +36,41 @@ import static org.mockito.Mockito.when; * Note: Only for test. DO NOT USE IN PRODUCTION! * * @author cdfive + * @author lianglin */ public class BaseTest { - protected Invoker invoker; - protected Invocation invocation; - - public void constructInvokerAndInvocation() { - invoker = mock(Invoker.class); - URL url = URL.valueOf("dubbo://127.0.0.1:2181") - .addParameter(CommonConstants.VERSION_KEY, "1.0.0") - .addParameter(CommonConstants.GROUP_KEY, "grp1") - .addParameter(CommonConstants.INTERFACE_KEY, DemoService.class.getName()); - when(invoker.getUrl()).thenReturn(url); - when(invoker.getInterface()).thenReturn(DemoService.class); - - invocation = mock(Invocation.class); - Method method = DemoService.class.getMethods()[0]; - when(invocation.getMethodName()).thenReturn(method.getName()); - when(invocation.getParameterTypes()).thenReturn(method.getParameterTypes()); - - } - /** * Clean up resources for context, clusterNodeMap, processorSlotChainMap */ - protected static void cleanUpAll() { + public void cleanUpAll() { try { - RpcContext.removeContext(); - ClusterBuilderSlot.getClusterNodeMap().clear(); - CtSph.resetChainMap(); - Method method = ContextUtil.class.getDeclaredMethod("resetContextMap"); - method.setAccessible(true); - method.invoke(null, null); - ContextUtil.exit(); - SentinelConfig.setConfig(DubboConfig.DUBBO_INTERFACE_GROUP_VERSION_ENABLED, "true"); - FlowRuleManager.loadRules(new ArrayList<>()); - DegradeRuleManager.loadRules(new ArrayList<>()); + clearDubboContext(); + cleanUpCstContext(); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } + + private void cleanUpCstContext() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + ClusterBuilderSlot.getClusterNodeMap().clear(); + CtSph.resetChainMap(); + Method method = ContextUtil.class.getDeclaredMethod("resetContextMap"); + method.setAccessible(true); + method.invoke(null, null); + ContextUtil.exit(); + FlowRuleManager.loadRules(new ArrayList<>()); + DegradeRuleManager.loadRules(new ArrayList<>()); + } + + private void clearDubboContext() { + SentinelConfig.setConfig("csp.sentinel.dubbo.resource.use.prefix", "false"); + SentinelConfig.setConfig(DubboConfig.DUBBO_PROVIDER_PREFIX, ""); + SentinelConfig.setConfig(DubboConfig.DUBBO_CONSUMER_PREFIX, ""); + SentinelConfig.setConfig(DubboConfig.DUBBO_INTERFACE_GROUP_VERSION_ENABLED, "false"); + DubboFallbackRegistry.setConsumerFallback(new DefaultDubboFallback()); + RpcContext.removeContext(); + + } } \ No newline at end of file diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/DubboTestUtil.java b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/DubboTestUtil.java new file mode 100644 index 00000000..326f216b --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/DubboTestUtil.java @@ -0,0 +1,80 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.csp.sentinel; + +import com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService; +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.constants.CommonConstants; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; + +import java.lang.reflect.Method; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * @author lianglin + */ +public class DubboTestUtil { + + + public static Class DEFAULT_TEST_SERVICE = DemoService.class; + public static Method DEFAULT_TEST_METHOD_ONE = DEFAULT_TEST_SERVICE.getMethods()[0]; + public static Method DEFAULT_TEST_METHOD_TWO = DEFAULT_TEST_SERVICE.getMethods()[1]; + + public static Invoker getMockInvoker(URL url, Class cls) { + Invoker invoker = mock(Invoker.class); + when(invoker.getUrl()).thenReturn(url); + when(invoker.getInterface()).thenReturn(cls); + return invoker; + } + + public static Invoker getDefaultMockInvoker() { + return getMockInvoker(getDefaultTestURL(), DEFAULT_TEST_SERVICE); + } + + public static Invocation getMockInvocation(Method method) { + Invocation invocation = mock(Invocation.class); + when(invocation.getMethodName()).thenReturn(method.getName()); + when(invocation.getParameterTypes()).thenReturn(method.getParameterTypes()); + return invocation; + } + + public static Invocation getDefaultMockInvocationOne() { + Invocation invocation = mock(Invocation.class); + when(invocation.getMethodName()).thenReturn(DEFAULT_TEST_METHOD_ONE.getName()); + when(invocation.getParameterTypes()).thenReturn(DEFAULT_TEST_METHOD_ONE.getParameterTypes()); + return invocation; + } + + public static Invocation getDefaultMockInvocationTwo() { + Invocation invocation = mock(Invocation.class); + when(invocation.getMethodName()).thenReturn(DEFAULT_TEST_METHOD_TWO.getName()); + when(invocation.getParameterTypes()).thenReturn(DEFAULT_TEST_METHOD_TWO.getParameterTypes()); + return invocation; + } + + public static URL getDefaultTestURL() { + URL url = URL.valueOf("dubbo://127.0.0.1:2181") + .addParameter(CommonConstants.VERSION_KEY, "1.0.0") + .addParameter(CommonConstants.GROUP_KEY, "grp1") + .addParameter(CommonConstants.INTERFACE_KEY, DEFAULT_TEST_SERVICE.getName()); + return url; + } + + +} diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboUtilsTest.java b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboUtilsTest.java index ece46fde..4b4eadea 100644 --- a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboUtilsTest.java +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboUtilsTest.java @@ -29,11 +29,10 @@ import org.junit.Test; import java.lang.reflect.Method; import java.util.HashMap; +import static com.alibaba.csp.sentinel.adapter.dubbo.config.DubboConfig.DUBBO_INTERFACE_GROUP_VERSION_ENABLED; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; /** * @author cdfive @@ -45,7 +44,7 @@ public class DubboUtilsTest { SentinelConfig.setConfig("csp.sentinel.dubbo.resource.use.prefix", "true"); SentinelConfig.setConfig(DubboConfig.DUBBO_PROVIDER_PREFIX, ""); SentinelConfig.setConfig(DubboConfig.DUBBO_CONSUMER_PREFIX, ""); - SentinelConfig.setConfig(DubboConfig.DUBBO_INTERFACE_GROUP_VERSION_ENABLED, "false"); + SentinelConfig.setConfig(DUBBO_INTERFACE_GROUP_VERSION_ENABLED, "false"); } @@ -54,7 +53,7 @@ public class DubboUtilsTest { SentinelConfig.setConfig("csp.sentinel.dubbo.resource.use.prefix", "false"); SentinelConfig.setConfig(DubboConfig.DUBBO_PROVIDER_PREFIX, ""); SentinelConfig.setConfig(DubboConfig.DUBBO_CONSUMER_PREFIX, ""); - SentinelConfig.setConfig(DubboConfig.DUBBO_INTERFACE_GROUP_VERSION_ENABLED, "false"); + SentinelConfig.setConfig(DUBBO_INTERFACE_GROUP_VERSION_ENABLED, "false"); } @@ -146,4 +145,23 @@ public class DubboUtilsTest { assertEquals("my:dubbo:consumer:com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName); } + + @Test + public void testGetInterfaceName() { + + URL url = URL.valueOf("dubbo://127.0.0.1:2181") + .addParameter(CommonConstants.VERSION_KEY, "1.0.0") + .addParameter(CommonConstants.GROUP_KEY, "grp1") + .addParameter(CommonConstants.INTERFACE_KEY, DemoService.class.getName()); + Invoker invoker = mock(Invoker.class); + when(invoker.getUrl()).thenReturn(url); + when(invoker.getInterface()).thenReturn(DemoService.class); + + SentinelConfig.setConfig(DUBBO_INTERFACE_GROUP_VERSION_ENABLED, "false"); + assertEquals("com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService", DubboUtils.getInterfaceName(invoker)); + + SentinelConfig.setConfig(DUBBO_INTERFACE_GROUP_VERSION_ENABLED, "true"); + assertEquals("com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:1.0.0:grp1", DubboUtils.getInterfaceName(invoker)); + + } } \ No newline at end of file diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilterTest.java b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilterTest.java index ea69ab8b..4608b2a5 100644 --- a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilterTest.java +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilterTest.java @@ -16,13 +16,11 @@ package com.alibaba.csp.sentinel.adapter.dubbo; 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.DubboConfig; -import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DefaultDubboFallback; 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.provider.DemoService; import com.alibaba.csp.sentinel.context.Context; import com.alibaba.csp.sentinel.context.ContextUtil; import com.alibaba.csp.sentinel.node.ClusterNode; @@ -36,8 +34,10 @@ 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.AppResponse; import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.InvokeMode; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcContext; @@ -46,7 +46,6 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -56,105 +55,80 @@ import java.util.Set; import static com.alibaba.csp.sentinel.slots.block.RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO; import static org.apache.dubbo.rpc.Constants.ASYNC_KEY; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; /** * @author cdfive + * @author lianglin */ public class SentinelDubboConsumerFilterTest extends BaseTest { - private SentinelDubboConsumerFilter filter = new SentinelDubboConsumerFilter(); + private SentinelDubboConsumerFilter consumerFilter = new SentinelDubboConsumerFilter(); @Before public void setUp() { cleanUpAll(); initFallback(); - constructInvokerAndInvocation(); } @After - public void cleanUp() { + public void destroy() { cleanUpAll(); - DubboFallbackRegistry.setConsumerFallback(new DefaultDubboFallback()); } - public void initFlowRule(String resource) { - FlowRule flowRule = new FlowRule(resource); - flowRule.setCount(1); - flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS); - List flowRules = new ArrayList<>(); - flowRules.add(flowRule); - FlowRuleManager.loadRules(flowRules); - } - - public void initDegradeRule(String resource) { - DegradeRule degradeRule = new DegradeRule(resource) - .setCount(0.5) - .setGrade(DEGRADE_GRADE_EXCEPTION_RATIO); - List degradeRules = new ArrayList<>(); - degradeRules.add(degradeRule); - degradeRule.setTimeWindow(1); - DegradeRuleManager.loadRules(degradeRules); - } - - - public 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; - } - }); - } @Test public void testInterfaceLevelFollowControlAsync() throws InterruptedException { + + Invoker invoker = DubboTestUtil.getDefaultMockInvoker(); + Invocation invocation = DubboTestUtil.getDefaultMockInvocationOne(); + when(invocation.getAttachment(ASYNC_KEY)).thenReturn(Boolean.TRUE.toString()); - initFlowRule(invoker.getUrl().getColonSeparatedKey()); - Result result1 = responseBack(requestGo(false, invocation)); + initFlowRule(DubboUtils.getInterfaceName(invoker)); + + Result result1 = invokeDubboRpc(false, invoker, invocation); assertEquals("normal", result1.getValue()); + // should fallback because the qps > 1 - Result result2 = responseBack(requestGo(false, invocation)); + Result result2 = invokeDubboRpc(false, invoker, invocation); assertEquals("fallback", result2.getValue()); + // sleeping 1000 ms to reset qps Thread.sleep(1000); - Result result3 = responseBack(requestGo(false, invocation)); + Result result3 = invokeDubboRpc(false, invoker, invocation); assertEquals("normal", result3.getValue()); - verifyInvocationStructureForCallFinish(); + verifyInvocationStructureForCallFinish(invoker, invocation); } @Test public void testDegradeAsync() throws InterruptedException { + + Invocation invocation = DubboTestUtil.getDefaultMockInvocationOne(); + Invoker invoker = DubboTestUtil.getDefaultMockInvoker(); + when(invocation.getAttachment(ASYNC_KEY)).thenReturn(Boolean.TRUE.toString()); + initDegradeRule(DubboUtils.getInterfaceName(invoker)); - initDegradeRule(invoker.getUrl().getColonSeparatedKey()); - Result result = requestGo(false, invocation); - verifyInvocationStructureForAsyncCall(invoker, invocation); - responseBack(result); + Result result = invokeDubboRpc(false, invoker, invocation); + verifyInvocationStructureForCallFinish(invoker, invocation); assertEquals("normal", result.getValue()); + + // inc the clusterNode's exception to trigger the fallback for (int i = 0; i < 5; i++) { - responseBack(requestGo(true, invocation)); - verifyInvocationStructureForCallFinish(); + invokeDubboRpc(true, invoker, invocation); + verifyInvocationStructureForCallFinish(invoker, invocation); } - Result result2 = responseBack(requestGo(false, invocation)); + + Result result2 = invokeDubboRpc(false, invoker, invocation); assertEquals("fallback", result2.getValue()); + // sleeping 1000 ms to reset exception Thread.sleep(1000); - - Result result3 = responseBack(requestGo(false, invocation)); + Result result3 = invokeDubboRpc(false, invoker, invocation); assertEquals("normal", result3.getValue()); Context context = ContextUtil.getContext(); @@ -164,22 +138,26 @@ public class SentinelDubboConsumerFilterTest extends BaseTest { @Test public void testDegradeSync() throws InterruptedException { - initDegradeRule(invoker.getUrl().getColonSeparatedKey()); - Result result = requestGo(false, invocation); - verifyInvocationStructure(invoker, invocation); - responseBack(result); + Invocation invocation = DubboTestUtil.getDefaultMockInvocationOne(); + Invoker invoker = DubboTestUtil.getDefaultMockInvoker(); + initDegradeRule(DubboUtils.getInterfaceName(invoker)); + + Result result = invokeDubboRpc(false, invoker, invocation); + verifyInvocationStructureForCallFinish(invoker, invocation); assertEquals("normal", result.getValue()); + // inc the clusterNode's exception to trigger the fallback for (int i = 0; i < 5; i++) { - responseBack(requestGo(true, invocation)); - verifyInvocationStructureForCallFinish(); + invokeDubboRpc(true, invoker, invocation); + verifyInvocationStructureForCallFinish(invoker, invocation); } - Result result2 = responseBack(requestGo(false, invocation)); + + Result result2 = invokeDubboRpc(false, invoker, invocation); assertEquals("fallback", result2.getValue()); + // sleeping 1000 ms to reset exception Thread.sleep(1000); - - Result result3 = responseBack(requestGo(false, invocation)); + Result result3 = invokeDubboRpc(false, invoker, invocation); assertEquals("normal", result3.getValue()); Context context = ContextUtil.getContext(); @@ -189,62 +167,43 @@ public class SentinelDubboConsumerFilterTest extends BaseTest { @Test public void testMethodFlowControlAsync() { - when(invocation.getAttachment(ASYNC_KEY)).thenReturn(Boolean.TRUE.toString()); - initFlowRule(DubboUtils.getResourceName(invoker, invocation, DubboConfig.getDubboConsumerPrefix())); - responseBack(requestGo(false, invocation)); - responseBack(requestGo(false, invocation)); + Invocation invocation = DubboTestUtil.getDefaultMockInvocationOne(); + Invoker invoker = DubboTestUtil.getDefaultMockInvoker(); - Invocation invocation2 = mock(Invocation.class); - Method method = DemoService.class.getMethods()[1]; - when(invocation2.getMethodName()).thenReturn(method.getName()); - when(invocation2.getParameterTypes()).thenReturn(method.getParameterTypes()); - Result result2 = responseBack(requestGo(false, invocation2)); - verifyInvocationStructureForCallFinish(); + when(invocation.getAttachment(ASYNC_KEY)).thenReturn(Boolean.TRUE.toString()); + initFlowRule(consumerFilter.getMethodName(invoker, invocation)); + invokeDubboRpc(false, invoker, invocation); + invokeDubboRpc(false, invoker, invocation); + + Invocation invocation2 = DubboTestUtil.getDefaultMockInvocationTwo(); + Result result2 = invokeDubboRpc(false, invoker, invocation2); + verifyInvocationStructureForCallFinish(invoker, invocation2); assertEquals("normal", result2.getValue()); // the method of invocation should be blocked - Result fallback = requestGo(false, invocation); - assertNotNull(RpcContext.getContext().get(DubboUtils.DUBBO_INTERFACE_ENTRY_KEY)); - assertNull(RpcContext.getContext().get(DubboUtils.DUBBO_METHOD_ENTRY_KEY)); - responseBack(fallback); + Result fallback = invokeDubboRpc(false, invoker, invocation); assertEquals("fallback", fallback.getValue()); - verifyInvocationStructureForCallFinish(); - + verifyInvocationStructureForCallFinish(invoker, invocation); - } - - public Result requestGo(boolean exception, Invocation currentInvocation) { - AsyncRpcResult result = null; - if (exception) { - result = AsyncRpcResult.newDefaultAsyncResult(new Exception("error"), currentInvocation); - } else { - result = AsyncRpcResult.newDefaultAsyncResult("normal", currentInvocation); - } - when(invoker.invoke(currentInvocation)).thenReturn(result); - return filter.invoke(invoker, currentInvocation); - } - - public Result responseBack(Result result) { - filter.listener().onMessage(result, invoker, invocation); - return result; } @Test - public void testInvokeAsync() throws InterruptedException { + public void testInvokeAsync() { - when(invocation.getAttachment(ASYNC_KEY)).thenReturn(Boolean.TRUE.toString()); + Invocation invocation = DubboTestUtil.getDefaultMockInvocationOne(); + Invoker invoker = DubboTestUtil.getDefaultMockInvoker(); + when(invocation.getAttachment(ASYNC_KEY)).thenReturn(Boolean.TRUE.toString()); final Result result = mock(Result.class); when(result.hasException()).thenReturn(false); when(invoker.invoke(invocation)).thenAnswer(invocationOnMock -> { verifyInvocationStructureForAsyncCall(invoker, invocation); - return result; + return result; }); - - filter.invoke(invoker, invocation); + consumerFilter.invoke(invoker, invocation); verify(invoker).invoke(invocation); Context context = ContextUtil.getContext(); @@ -254,6 +213,9 @@ public class SentinelDubboConsumerFilterTest extends BaseTest { @Test public void testInvokeSync() { + Invocation invocation = DubboTestUtil.getDefaultMockInvocationOne(); + Invoker invoker = DubboTestUtil.getDefaultMockInvoker(); + final Result result = mock(Result.class); when(result.hasException()).thenReturn(false); when(result.getException()).thenReturn(new Exception()); @@ -262,14 +224,14 @@ public class SentinelDubboConsumerFilterTest extends BaseTest { return result; }); - filter.invoke(invoker, invocation); + consumerFilter.invoke(invoker, invocation); verify(invoker).invoke(invocation); - filter.listener().onMessage(result, invoker, invocation); Context context = ContextUtil.getContext(); assertNull(context); } + /** * Simply verify invocation structure in memory: * EntranceNode(defaultContextName) @@ -282,7 +244,7 @@ public class SentinelDubboConsumerFilterTest extends BaseTest { // 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 // If consumer is on the top of Dubbo RPC invocation chain, use default context - String resourceName = DubboUtils.getResourceName(invoker, invocation, true); + String resourceName = consumerFilter.getMethodName(invoker, invocation); assertEquals(com.alibaba.csp.sentinel.Constants.CONTEXT_DEFAULT_NAME, context.getName()); assertEquals("", context.getOrigin()); @@ -295,10 +257,10 @@ public class SentinelDubboConsumerFilterTest extends BaseTest { // As SphU.entry(interfaceName, EntryType.OUT); Set childList = entranceNode.getChildList(); assertEquals(1, childList.size()); - DefaultNode interfaceNode = getNode(invoker.getUrl().getColonSeparatedKey(), entranceNode); + DefaultNode interfaceNode = getNode(DubboUtils.getInterfaceName(invoker), entranceNode); ResourceWrapper interfaceResource = interfaceNode.getId(); - assertEquals(invoker.getUrl().getColonSeparatedKey(), interfaceResource.getName()); + assertEquals(DubboUtils.getInterfaceName(invoker), interfaceResource.getName()); assertSame(EntryType.OUT, interfaceResource.getEntryType()); // As SphU.entry(resourceName, EntryType.OUT); @@ -335,7 +297,7 @@ public class SentinelDubboConsumerFilterTest extends BaseTest { // 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 // If consumer is on the top of Dubbo RPC invocation chain, use default context - String resourceName = DubboUtils.getResourceName(invoker, invocation, true); + String resourceName = consumerFilter.getMethodName(invoker, invocation); assertEquals(com.alibaba.csp.sentinel.Constants.CONTEXT_DEFAULT_NAME, context.getName()); assertEquals("", context.getOrigin()); @@ -347,9 +309,9 @@ public class SentinelDubboConsumerFilterTest extends BaseTest { // As SphU.entry(interfaceName, EntryType.OUT); Set childList = entranceNode.getChildList(); assertEquals(2, childList.size()); - DefaultNode interfaceNode = getNode(invoker.getUrl().getColonSeparatedKey(), entranceNode); + DefaultNode interfaceNode = getNode(DubboUtils.getInterfaceName(invoker), entranceNode); ResourceWrapper interfaceResource = interfaceNode.getId(); - assertEquals(invoker.getUrl().getColonSeparatedKey(), interfaceResource.getName()); + assertEquals(DubboUtils.getInterfaceName(invoker), interfaceResource.getName()); assertSame(EntryType.OUT, interfaceResource.getEntryType()); // As SphU.entry(resourceName, EntryType.OUT); @@ -379,17 +341,16 @@ public class SentinelDubboConsumerFilterTest extends BaseTest { } - private void verifyInvocationStructureForCallFinish() { + private void verifyInvocationStructureForCallFinish(Invoker invoker, Invocation invocation) { Context context = ContextUtil.getContext(); assertNull(context); - Entry interfaceEntry = (Entry) RpcContext.getContext().get(DubboUtils.DUBBO_INTERFACE_ENTRY_KEY); - Entry methodEntry = (Entry) RpcContext.getContext().get(DubboUtils.DUBBO_METHOD_ENTRY_KEY); - assertNull(interfaceEntry); - assertNull(methodEntry); + String methodResourceName = consumerFilter.getMethodName(invoker, invocation); + Entry[] entries = (Entry[]) RpcContext.getContext().get(methodResourceName); + assertNull(entries); } - public DefaultNode getNode(String resourceName, DefaultNode root) { + private DefaultNode getNode(String resourceName, DefaultNode root) { Queue queue = new LinkedList<>(); queue.offer(root); @@ -405,4 +366,52 @@ public class SentinelDubboConsumerFilterTest extends BaseTest { return null; } + + private void initFlowRule(String resource) { + FlowRule flowRule = new FlowRule(resource); + flowRule.setCount(1); + flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS); + List flowRules = new ArrayList<>(); + flowRules.add(flowRule); + FlowRuleManager.loadRules(flowRules); + } + + private void initDegradeRule(String resource) { + DegradeRule degradeRule = new DegradeRule(resource) + .setCount(0.5) + .setGrade(DEGRADE_GRADE_EXCEPTION_RATIO); + List 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; + } + }); + } + + private Result invokeDubboRpc(boolean exception, Invoker invoker, Invocation invocation) { + Result result = null; + InvokeMode invokeMode = RpcUtils.getInvokeMode(invoker.getUrl(), invocation); + 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); + } + when(invoker.invoke(invocation)).thenReturn(result); + return consumerFilter.invoke(invoker, invocation); + } + + + + } diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilterTest.java b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilterTest.java index ed97800a..6a984373 100644 --- a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilterTest.java +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilterTest.java @@ -16,6 +16,7 @@ package com.alibaba.csp.sentinel.adapter.dubbo; 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.provider.DemoService; @@ -35,52 +36,49 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -import java.lang.reflect.Method; import java.util.Map; import java.util.Set; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; /** * @author cdfive + * @author lianglin */ public class SentinelDubboProviderFilterTest extends BaseTest { + private SentinelDubboProviderFilter filter = new SentinelDubboProviderFilter(); + @Before public void setUp() { - constructInvokerAndInvocation(); cleanUpAll(); } @After - public void cleanUp() { + public void destroy() { cleanUpAll(); } @Test public void testInvoke() { + final String originApplication = "consumerA"; - URL url = invoker.getUrl() - .addParameter(CommonConstants.SIDE_KEY, CommonConstants.PROVIDER_SIDE); - when(invoker.getUrl()).thenReturn(url); + URL url = DubboTestUtil.getDefaultTestURL(); + url = url.addParameter(CommonConstants.SIDE_KEY, CommonConstants.PROVIDER_SIDE); + Invoker invoker = DubboTestUtil.getMockInvoker(url, DemoService.class); + Invocation invocation = DubboTestUtil.getMockInvocation(DemoService.class.getMethods()[0]); when(invocation.getAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, "")) .thenReturn(originApplication); final Result result = mock(Result.class); when(result.hasException()).thenReturn(false); when(result.getException()).thenReturn(new Exception()); + when(invoker.invoke(invocation)).thenAnswer(invocationOnMock -> { verifyInvocationStructure(originApplication, invoker, invocation); return result; @@ -89,29 +87,28 @@ public class SentinelDubboProviderFilterTest extends BaseTest { filter.invoke(invoker, invocation); verify(invoker).invoke(invocation); - filter.listener().onMessage(result, invoker, invocation); Context context = ContextUtil.getContext(); assertNull(context); } /** * Simply verify invocation structure in memory: - * EntranceNode(resourceName) + * EntranceNode(methodResourceName) * --InterfaceNode(interfaceName) - * ----MethodNode(resourceName) + * ----MethodNode(methodResourceName) */ private void verifyInvocationStructure(String originApplication, Invoker invoker, Invocation invocation) { Context context = ContextUtil.getContext(); assertNotNull(context); // As ContextUtil.enter(resourceName, application) in SentinelDubboProviderFilter - String resourceName = DubboUtils.getResourceName(invoker, invocation, true); - assertEquals(resourceName, context.getName()); + String methodResourceName = filter.getMethodName(invoker, invocation); + assertEquals(methodResourceName, context.getName()); assertEquals(originApplication, context.getOrigin()); DefaultNode entranceNode = context.getEntranceNode(); ResourceWrapper entranceResource = entranceNode.getId(); - assertEquals(resourceName, entranceResource.getName()); + assertEquals(methodResourceName, entranceResource.getName()); assertSame(EntryType.IN, entranceResource.getEntryType()); // As SphU.entry(interfaceName, EntryType.IN); @@ -120,7 +117,7 @@ public class SentinelDubboProviderFilterTest extends BaseTest { DefaultNode interfaceNode = (DefaultNode) childList.iterator().next(); ResourceWrapper interfaceResource = interfaceNode.getId(); - assertEquals(invoker.getUrl().getColonSeparatedKey(), interfaceResource.getName()); + assertEquals(filter.getInterfaceName(invoker), interfaceResource.getName()); assertSame(EntryType.IN, interfaceResource.getEntryType()); // As SphU.entry(resourceName, EntryType.IN, 1, invocation.getArguments()); @@ -128,7 +125,7 @@ public class SentinelDubboProviderFilterTest extends BaseTest { assertEquals(1, childList.size()); DefaultNode methodNode = (DefaultNode) childList.iterator().next(); ResourceWrapper methodResource = methodNode.getId(); - assertEquals(resourceName, methodResource.getName()); + assertEquals(methodResourceName, methodResource.getName()); assertSame(EntryType.IN, methodResource.getEntryType()); // Verify curEntry @@ -151,4 +148,6 @@ public class SentinelDubboProviderFilterTest extends BaseTest { assertEquals(1, interfaceOriginCountMap.size()); assertTrue(interfaceOriginCountMap.containsKey(originApplication)); } + + }