diff --git a/sentinel-adapter/pom.xml b/sentinel-adapter/pom.xml index 668f9412..c259215f 100755 --- a/sentinel-adapter/pom.xml +++ b/sentinel-adapter/pom.xml @@ -17,6 +17,7 @@ sentinel-web-servlet sentinel-dubbo-adapter + sentinel-apache-dubbo-adapter sentinel-grpc-adapter sentinel-zuul-adapter sentinel-reactor-adapter diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/README.md b/sentinel-adapter/sentinel-apache-dubbo-adapter/README.md new file mode 100755 index 00000000..fe97e9f4 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/README.md @@ -0,0 +1,68 @@ +# Sentinel Apache Dubbo Adapter + +> Note: 中文文档请见[此处](https://github.com/alibaba/Sentinel/wiki/主流框架的适配#dubbo)。 + +Sentinel Dubbo Adapter provides service consumer filter and provider filter +for [Apache Dubbo](https://dubbo.apache.org/en-us/) services. + +**Note: This adapter only supports Apache Dubbo 2.7.x and above.** For legacy `com.alibaba:dubbo` 2.6.x, +please use `sentinel-dubbo-adapter` module instead. + +To use Sentinel Dubbo Adapter, you can simply add the following dependency to your `pom.xml`: + +```xml + + com.alibaba.csp + sentinel-apache-dubbo-adapter + x.y.z + +``` + +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). + +If you don't want the filters enabled, you can manually disable them. For example: + +```xml + + + +``` + +For more details of Dubbo filter, see [here](http://dubbo.apache.org/en-us/docs/dev/impls/filter.html). + +## Dubbo resources + +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)` + +## Flow control based on caller + +In many circumstances, it's also significant to control traffic flow based on the **caller**. +For example, assuming that there are two services A and B, both of them initiate remote call requests to the service provider. +If we want to limit the calls from service B only, we can set the `limitApp` of flow rule as the identifier of service B (e.g. service name). + +Sentinel Dubbo Adapter will automatically resolve the Dubbo consumer's *application name* as the caller's name (`origin`), +and will bring the caller's name when doing resource protection. +If `limitApp` of flow rules is not configured (`default`), flow control will take effects on all callers. +If `limitApp` of a flow rule is configured with a caller, then the corresponding flow rule will only take effect on the specific caller. + +> Note: Dubbo consumer does not provide its Dubbo application name when doing RPC, +so developers should manually put the application name into *attachment* at consumer side, +then extract it at provider side. Sentinel Dubbo Adapter has implemented a filter (`DubboAppContextFilter`) +where consumer can carry application name information to provider automatically. +If the consumer does not use Sentinel Dubbo Adapter but requires flow control based on caller, developers can manually put the application name into attachment with the key `dubboApplication`. + +## Global fallback + +Sentinel Dubbo Adapter supports global fallback configuration. +The global fallback will handle exceptions and give replacement result when blocked by +flow control, degrade or system load protection. You can implement your own `DubboFallback` interface +and then register to `DubboFallbackRegistry`. If no fallback is configured, Sentinel will wrap the `BlockException` +then directly throw it out. + +Besides, we can also leverage [Dubbo mock mechanism](http://dubbo.apache.org/en-us/docs/user/demos/local-mock.html) to provide fallback implementation of degraded Dubbo services. \ No newline at end of file diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/pom.xml b/sentinel-adapter/sentinel-apache-dubbo-adapter/pom.xml new file mode 100644 index 00000000..4f24bf80 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/pom.xml @@ -0,0 +1,50 @@ + + + + sentinel-adapter + com.alibaba.csp + 1.5.1-SNAPSHOT + + 4.0.0 + + sentinel-apache-dubbo-adapter + jar + + + 1.8 + 1.8 + 2.7.1 + + + + + com.alibaba.csp + sentinel-core + + + org.apache.dubbo + dubbo + ${apache.dubbo.version} + provided + + + + junit + junit + test + + + + org.mockito + mockito-core + test + + + com.alibaba + fastjson + test + + + \ No newline at end of file diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboAppContextFilter.java b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboAppContextFilter.java new file mode 100644 index 00000000..97ae51ba --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboAppContextFilter.java @@ -0,0 +1,43 @@ +/* + * 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.adapter.dubbo; + +import org.apache.dubbo.common.Constants; +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; + +/** + * Puts current consumer's application name in the attachment of each invocation. + * + * @author Eric Zhao + */ +@Activate(group = "consumer") +public class DubboAppContextFilter implements Filter { + + @Override + public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { + String application = invoker.getUrl().getParameter(Constants.APPLICATION_KEY); + if (application != null) { + RpcContext.getContext().setAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, application); + } + return invoker.invoke(invocation); + } +} 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 new file mode 100644 index 00000000..03a494f5 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboUtils.java @@ -0,0 +1,54 @@ +/* + * 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.adapter.dubbo; + +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; + +/** + * @author Eric Zhao + */ +public final class DubboUtils { + + public static final String SENTINEL_DUBBO_APPLICATION_KEY = "dubboApplication"; + + public static String getApplication(Invocation invocation, String defaultValue) { + if (invocation == null || invocation.getAttachments() == null) { + throw new IllegalArgumentException("Bad invocation instance"); + } + return invocation.getAttachment(SENTINEL_DUBBO_APPLICATION_KEY, defaultValue); + } + + public static String getResourceName(Invoker invoker, Invocation invocation) { + StringBuilder buf = new StringBuilder(64); + buf.append(invoker.getInterface().getName()) + .append(":") + .append(invocation.getMethodName()) + .append("("); + boolean isFirst = true; + for (Class clazz : invocation.getParameterTypes()) { + if (!isFirst) { + buf.append(","); + } + buf.append(clazz.getName()); + isFirst = false; + } + buf.append(")"); + return buf.toString(); + } + + 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 new file mode 100755 index 00000000..2dcbaa79 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilter.java @@ -0,0 +1,83 @@ +/* + * 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.adapter.dubbo; + +import com.alibaba.csp.sentinel.Entry; +import com.alibaba.csp.sentinel.EntryType; +import com.alibaba.csp.sentinel.SphU; +import com.alibaba.csp.sentinel.Tracer; +import com.alibaba.csp.sentinel.log.RecordLog; +import com.alibaba.csp.sentinel.slots.block.BlockException; + +import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DubboFallbackRegistry; +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.RpcException; + +/** + *

Dubbo service consumer filter for Sentinel. Auto activated by default.

+ * + * If you want to disable the consumer filter, you can configure: + *
+ * <dubbo:consumer filter="-sentinel.dubbo.consumer.filter"/>
+ * 
+ * + * @author Carpenter Lee + * @author Eric Zhao + */ +@Activate(group = "consumer") +public class SentinelDubboConsumerFilter implements Filter { + + public SentinelDubboConsumerFilter() { + RecordLog.info("Sentinel Apache Dubbo consumer filter initialized"); + } + + @Override + public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { + Entry interfaceEntry = null; + Entry methodEntry = null; + try { + String resourceName = DubboUtils.getResourceName(invoker, invocation); + interfaceEntry = SphU.entry(invoker.getInterface().getName(), EntryType.OUT); + methodEntry = SphU.entry(resourceName, EntryType.OUT); + + Result result = invoker.invoke(invocation); + if (result.hasException()) { + Throwable e = result.getException(); + // Record common exception. + Tracer.traceEntry(e, interfaceEntry); + Tracer.traceEntry(e, methodEntry); + } + 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(); + } + } + } +} 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 new file mode 100755 index 00000000..2020832a --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilter.java @@ -0,0 +1,93 @@ +/* + * 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.adapter.dubbo; + +import com.alibaba.csp.sentinel.Entry; +import com.alibaba.csp.sentinel.EntryType; +import com.alibaba.csp.sentinel.SphU; +import com.alibaba.csp.sentinel.Tracer; +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.RpcException; + +/** + *

Apache Dubbo service provider filter that enables integration with Sentinel. Auto activated by default.

+ *

Note: this only works for Apache Dubbo 2.7.x or above version.

+ * + * If you want to disable the provider filter, you can configure: + *
+ * <dubbo:provider filter="-sentinel.dubbo.provider.filter"/>
+ * 
+ * + * @author Carpenter Lee + * @author Eric Zhao + */ +@Activate(group = "provider") +public class SentinelDubboProviderFilter implements Filter { + + public SentinelDubboProviderFilter() { + RecordLog.info("Sentinel Apache Dubbo provider filter initialized"); + } + + @Override + public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { + // Get origin caller. + String application = DubboUtils.getApplication(invocation, ""); + + Entry interfaceEntry = null; + Entry methodEntry = null; + try { + String resourceName = DubboUtils.getResourceName(invoker, invocation); + String interfaceName = 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(resourceName, application); + interfaceEntry = SphU.entry(interfaceName, EntryType.IN); + methodEntry = SphU.entry(resourceName, EntryType.IN, 1, invocation.getArguments()); + + Result result = invoker.invoke(invocation); + if (result.hasException()) { + Throwable e = result.getException(); + // Record common exception. + Tracer.traceEntry(e, interfaceEntry); + Tracer.traceEntry(e, 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/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DefaultDubboFallback.java b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DefaultDubboFallback.java new file mode 100644 index 00000000..8a4659f7 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DefaultDubboFallback.java @@ -0,0 +1,35 @@ +/* + * 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.adapter.dubbo.fallback; + +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.alibaba.csp.sentinel.slots.block.SentinelRpcException; + +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Result; + +/** + * @author Eric Zhao + */ +public class DefaultDubboFallback implements DubboFallback { + + @Override + public Result handle(Invoker invoker, Invocation invocation, BlockException ex) { + // Just wrap and throw the exception. + throw new SentinelRpcException(ex); + } +} diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallback.java b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallback.java new file mode 100644 index 00000000..133232c3 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallback.java @@ -0,0 +1,41 @@ +/* + * 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.adapter.dubbo.fallback; + +import com.alibaba.csp.sentinel.slots.block.BlockException; + +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Result; + +/** + * Fallback handler for Dubbo services. + * + * @author Eric Zhao + */ +@FunctionalInterface +public interface DubboFallback { + + /** + * Handle the block exception and provide fallback result. + * + * @param invoker Dubbo invoker + * @param invocation Dubbo invocation + * @param ex block exception + * @return fallback result + */ + Result handle(Invoker invoker, Invocation invocation, BlockException ex); +} diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallbackRegistry.java b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallbackRegistry.java new file mode 100644 index 00000000..78c3a0b1 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallbackRegistry.java @@ -0,0 +1,54 @@ +/* + * 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.adapter.dubbo.fallback; + +import com.alibaba.csp.sentinel.util.AssertUtil; + +/** + *

Global fallback registry for Dubbo.

+ * + *

+ * Note: Circuit breaking is mainly designed for consumer. The provider should not + * give fallback result in most circumstances. + *

+ * + * @author Eric Zhao + */ +public final class DubboFallbackRegistry { + + private static volatile DubboFallback consumerFallback = new DefaultDubboFallback(); + private static volatile DubboFallback providerFallback = new DefaultDubboFallback(); + + public static DubboFallback getConsumerFallback() { + return consumerFallback; + } + + public static void setConsumerFallback(DubboFallback consumerFallback) { + AssertUtil.notNull(consumerFallback, "consumerFallback cannot be null"); + DubboFallbackRegistry.consumerFallback = consumerFallback; + } + + public static DubboFallback getProviderFallback() { + return providerFallback; + } + + public static void setProviderFallback(DubboFallback providerFallback) { + AssertUtil.notNull(providerFallback, "providerFallback cannot be null"); + DubboFallbackRegistry.providerFallback = providerFallback; + } + + private DubboFallbackRegistry() {} +} diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter new file mode 100755 index 00000000..292a4b25 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter @@ -0,0 +1,3 @@ +sentinel.dubbo.provider.filter=com.alibaba.csp.sentinel.adapter.dubbo.SentinelDubboProviderFilter +sentinel.dubbo.consumer.filter=com.alibaba.csp.sentinel.adapter.dubbo.SentinelDubboConsumerFilter +dubbo.application.context.name.filter=com.alibaba.csp.sentinel.adapter.dubbo.DubboAppContextFilter 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 new file mode 100644 index 00000000..a61f3b4c --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/BaseTest.java @@ -0,0 +1,40 @@ +/* + * 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.slots.clusterbuilder.ClusterBuilderSlot; + +import org.apache.dubbo.rpc.RpcContext; + +/** + * Base test class, provide common methods for subClass + * The package is same as CtSph, to call CtSph.resetChainMap() method for test + * + * Note: Only for test. DO NOT USE IN PRODUCTION! + * + * @author cdfive + */ +public class BaseTest { + + /** + * Clean up resources for context, clusterNodeMap, processorSlotChainMap + */ + protected static void cleanUpAll() { + RpcContext.removeContext(); + ClusterBuilderSlot.getClusterNodeMap().clear(); + CtSph.resetChainMap(); + } +} \ No newline at end of file diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboAppContextFilterTest.java b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboAppContextFilterTest.java new file mode 100644 index 00000000..8c8721e1 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboAppContextFilterTest.java @@ -0,0 +1,75 @@ +/* + * 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.adapter.dubbo; + +import com.alibaba.csp.sentinel.BaseTest; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.RpcContext; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +/** + * @author cdfive + */ +public class DubboAppContextFilterTest extends BaseTest { + + private DubboAppContextFilter filter = new DubboAppContextFilter(); + + @Before + public void setUp() { + cleanUpAll(); + } + + @After + public void cleanUp() { + cleanUpAll(); + } + + @Test + public void testInvokeApplicationKey() { + Invoker invoker = mock(Invoker.class); + Invocation invocation = mock(Invocation.class); + URL url = URL.valueOf("test://test:111/test?application=serviceA"); + when(invoker.getUrl()).thenReturn(url); + + filter.invoke(invoker, invocation); + verify(invoker).invoke(invocation); + + String application = RpcContext.getContext().getAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY); + assertEquals("serviceA", application); + } + + @Test + public void testInvokeNullApplicationKey() { + Invoker invoker = mock(Invoker.class); + Invocation invocation = mock(Invocation.class); + URL url = URL.valueOf("test://test:111/test?application="); + when(invoker.getUrl()).thenReturn(url); + + filter.invoke(invoker, invocation); + verify(invoker).invoke(invocation); + + String application = RpcContext.getContext().getAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY); + assertNull(application); + } +} 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 new file mode 100644 index 00000000..8d3636f1 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboUtilsTest.java @@ -0,0 +1,75 @@ +/* + * 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.adapter.dubbo; + +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.junit.Test; + +import java.lang.reflect.Method; +import java.util.HashMap; + +import com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.*; + +/** + * @author cdfive + */ +public class DubboUtilsTest { + + @Test + public void testGetApplication() { + Invocation invocation = mock(Invocation.class); + when(invocation.getAttachments()).thenReturn(new HashMap<>()); + when(invocation.getAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, "")) + .thenReturn("consumerA"); + + String application = DubboUtils.getApplication(invocation, ""); + verify(invocation).getAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, ""); + + assertEquals("consumerA", application); + } + + @Test(expected = IllegalArgumentException.class) + public void testGetApplicationNoAttachments() { + Invocation invocation = mock(Invocation.class); + when(invocation.getAttachments()).thenReturn(null); + when(invocation.getAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, "")) + .thenReturn("consumerA"); + + DubboUtils.getApplication(invocation, ""); + + fail("No attachments in invocation, IllegalArgumentException should be thrown!"); + } + + @Test + public void testGetResourceName() { + Invoker invoker = mock(Invoker.class); + when(invoker.getInterface()).thenReturn(DemoService.class); + + Invocation invocation = mock(Invocation.class); + Method method = DemoService.class.getMethods()[0]; + when(invocation.getMethodName()).thenReturn(method.getName()); + when(invocation.getParameterTypes()).thenReturn(method.getParameterTypes()); + + String resourceName = DubboUtils.getResourceName(invoker, invocation); + + assertEquals("com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName); + } +} 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 new file mode 100644 index 00000000..e4b30b95 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilterTest.java @@ -0,0 +1,142 @@ +/* + * 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.adapter.dubbo; + +import com.alibaba.csp.sentinel.BaseTest; +import com.alibaba.csp.sentinel.Constants; +import com.alibaba.csp.sentinel.Entry; +import com.alibaba.csp.sentinel.EntryType; +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; +import com.alibaba.csp.sentinel.node.DefaultNode; +import com.alibaba.csp.sentinel.node.Node; +import com.alibaba.csp.sentinel.node.StatisticNode; +import com.alibaba.csp.sentinel.slotchain.ResourceWrapper; + +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Result; +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.*; +import static org.mockito.Mockito.*; + +/** + * @author cdfive + */ +public class SentinelDubboConsumerFilterTest extends BaseTest { + + private SentinelDubboConsumerFilter filter = new SentinelDubboConsumerFilter(); + + @Before + public void setUp() { + cleanUpAll(); + } + + @After + public void cleanUp() { + cleanUpAll(); + } + + @Test + public void testInvoke() { + final Invoker invoker = mock(Invoker.class); + when(invoker.getInterface()).thenReturn(DemoService.class); + + final Invocation invocation = mock(Invocation.class); + Method method = DemoService.class.getMethods()[0]; + when(invocation.getMethodName()).thenReturn(method.getName()); + when(invocation.getParameterTypes()).thenReturn(method.getParameterTypes()); + + final Result result = mock(Result.class); + when(result.hasException()).thenReturn(false); + when(invoker.invoke(invocation)).thenAnswer(invocationOnMock -> { + verifyInvocationStructure(invoker, invocation); + return result; + }); + + filter.invoke(invoker, invocation); + verify(invoker).invoke(invocation); + + Context context = ContextUtil.getContext(); + assertNull(context); + } + + /** + * Simply verify invocation structure in memory: + * EntranceNode(defaultContextName) + * --InterfaceNode(interfaceName) + * ----MethodNode(resourceName) + */ + private void verifyInvocationStructure(Invoker invoker, Invocation invocation) { + 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 + // If consumer is on the top of Dubbo RPC invocation chain, use default context + String resourceName = DubboUtils.getResourceName(invoker, invocation); + assertEquals(Constants.CONTEXT_DEFAULT_NAME, context.getName()); + assertEquals("", context.getOrigin()); + + DefaultNode entranceNode = context.getEntranceNode(); + ResourceWrapper entranceResource = entranceNode.getId(); + assertEquals(Constants.CONTEXT_DEFAULT_NAME, entranceResource.getName()); + assertSame(EntryType.IN, entranceResource.getType()); + + // As SphU.entry(interfaceName, EntryType.OUT); + Set childList = entranceNode.getChildList(); + assertEquals(1, childList.size()); + DefaultNode interfaceNode = (DefaultNode) childList.iterator().next(); + ResourceWrapper interfaceResource = interfaceNode.getId(); + assertEquals(DemoService.class.getName(), interfaceResource.getName()); + assertSame(EntryType.OUT, interfaceResource.getType()); + + // As SphU.entry(resourceName, EntryType.OUT); + childList = interfaceNode.getChildList(); + assertEquals(1, childList.size()); + DefaultNode methodNode = (DefaultNode) childList.iterator().next(); + ResourceWrapper methodResource = methodNode.getId(); + assertEquals(resourceName, methodResource.getName()); + assertSame(EntryType.OUT, methodResource.getType()); + + // Verify curEntry + Entry curEntry = context.getCurEntry(); + assertSame(methodNode, curEntry.getCurNode()); + assertSame(interfaceNode, curEntry.getLastNode()); + assertNull(curEntry.getOriginNode());// As context origin is not "", no originNode should be created in curEntry + + // Verify clusterNode + ClusterNode methodClusterNode = methodNode.getClusterNode(); + ClusterNode interfaceClusterNode = interfaceNode.getClusterNode(); + assertNotSame(methodClusterNode, interfaceClusterNode);// Different resource->Different ProcessorSlot->Different ClusterNode + + // As context origin is "", the StatisticNode should not be created in originCountMap of ClusterNode + Map methodOriginCountMap = methodClusterNode.getOriginCountMap(); + assertEquals(0, methodOriginCountMap.size()); + + Map interfaceOriginCountMap = interfaceClusterNode.getOriginCountMap(); + assertEquals(0, interfaceOriginCountMap.size()); + } +} 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 new file mode 100644 index 00000000..8b0ab899 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilterTest.java @@ -0,0 +1,145 @@ +/* + * 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.adapter.dubbo; + +import com.alibaba.csp.sentinel.BaseTest; +import com.alibaba.csp.sentinel.Entry; +import com.alibaba.csp.sentinel.EntryType; +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; +import com.alibaba.csp.sentinel.node.DefaultNode; +import com.alibaba.csp.sentinel.node.Node; +import com.alibaba.csp.sentinel.node.StatisticNode; +import com.alibaba.csp.sentinel.slotchain.ResourceWrapper; + +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Result; +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.*; +import static org.mockito.Mockito.*; + +/** + * @author cdfive + */ +public class SentinelDubboProviderFilterTest extends BaseTest { + + private SentinelDubboProviderFilter filter = new SentinelDubboProviderFilter(); + + @Before + public void setUp() { + cleanUpAll(); + } + + @After + public void cleanUp() { + cleanUpAll(); + } + + @Test + public void testInvoke() { + final String originApplication = "consumerA"; + + final Invoker invoker = mock(Invoker.class); + when(invoker.getInterface()).thenReturn(DemoService.class); + + final Invocation invocation = mock(Invocation.class); + Method method = DemoService.class.getMethods()[0]; + when(invocation.getMethodName()).thenReturn(method.getName()); + when(invocation.getParameterTypes()).thenReturn(method.getParameterTypes()); + when(invocation.getAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, "")) + .thenReturn(originApplication); + + final Result result = mock(Result.class); + when(result.hasException()).thenReturn(false); + when(invoker.invoke(invocation)).thenAnswer(invocationOnMock -> { + verifyInvocationStructure(originApplication, invoker, invocation); + return result; + }); + + filter.invoke(invoker, invocation); + verify(invoker).invoke(invocation); + + Context context = ContextUtil.getContext(); + assertNull(context); + } + + /** + * Simply verify invocation structure in memory: + * EntranceNode(resourceName) + * --InterfaceNode(interfaceName) + * ----MethodNode(resourceName) + */ + 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); + assertEquals(resourceName, context.getName()); + assertEquals(originApplication, context.getOrigin()); + + DefaultNode entranceNode = context.getEntranceNode(); + ResourceWrapper entranceResource = entranceNode.getId(); + assertEquals(resourceName, entranceResource.getName()); + assertSame(EntryType.IN, entranceResource.getType()); + + // As SphU.entry(interfaceName, EntryType.IN); + Set childList = entranceNode.getChildList(); + assertEquals(1, childList.size()); + DefaultNode interfaceNode = (DefaultNode) childList.iterator().next(); + ResourceWrapper interfaceResource = interfaceNode.getId(); + assertEquals(DemoService.class.getName(), interfaceResource.getName()); + assertSame(EntryType.IN, interfaceResource.getType()); + + // As SphU.entry(resourceName, EntryType.IN, 1, invocation.getArguments()); + childList = interfaceNode.getChildList(); + assertEquals(1, childList.size()); + DefaultNode methodNode = (DefaultNode) childList.iterator().next(); + ResourceWrapper methodResource = methodNode.getId(); + assertEquals(resourceName, methodResource.getName()); + assertSame(EntryType.IN, methodResource.getType()); + + // Verify curEntry + Entry curEntry = context.getCurEntry(); + assertSame(methodNode, curEntry.getCurNode()); + assertSame(interfaceNode, curEntry.getLastNode()); + assertNotNull(curEntry.getOriginNode());// As context origin is not "", originNode should be created + + // Verify clusterNode + ClusterNode methodClusterNode = methodNode.getClusterNode(); + ClusterNode interfaceClusterNode = interfaceNode.getClusterNode(); + assertNotSame(methodClusterNode, interfaceClusterNode);// Different resource->Different ProcessorSlot->Different ClusterNode + + // As context origin is not "", the StatisticNode should be created in originCountMap of ClusterNode + Map methodOriginCountMap = methodClusterNode.getOriginCountMap(); + assertEquals(1, methodOriginCountMap.size()); + assertTrue(methodOriginCountMap.containsKey(originApplication)); + + Map interfaceOriginCountMap = interfaceClusterNode.getOriginCountMap(); + assertEquals(1, interfaceOriginCountMap.size()); + assertTrue(interfaceOriginCountMap.containsKey(originApplication)); + } +} diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallbackRegistryTest.java b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallbackRegistryTest.java new file mode 100644 index 00000000..bc06ebf1 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallbackRegistryTest.java @@ -0,0 +1,50 @@ +/* + * 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.adapter.dubbo.fallback; + +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.Result; +import org.apache.dubbo.rpc.RpcResult; +import org.junit.Assert; +import org.junit.Test; + +/** + * @author Eric Zhao + */ +public class DubboFallbackRegistryTest { + + @Test(expected = SentinelRpcException.class) + public void testDefaultFallback() { + // Test for default. + BlockException ex = new FlowException("xxx"); + DubboFallbackRegistry.getConsumerFallback() + .handle(null, null, ex); + } + + @Test + public void testCustomFallback() { + BlockException ex = new FlowException("xxx"); + DubboFallbackRegistry.setConsumerFallback( + (invoker, invocation, e) -> new RpcResult("Error: " + e.getClass().getName())); + Result result = DubboFallbackRegistry.getConsumerFallback() + .handle(null, null, ex); + Assert.assertFalse("The invocation should not fail", result.hasException()); + Assert.assertEquals("Error: " + ex.getClass().getName(), result.getValue()); + } +} diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/provider/DemoService.java b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/provider/DemoService.java new file mode 100644 index 00000000..2a024cc9 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/provider/DemoService.java @@ -0,0 +1,23 @@ +/* + * 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.adapter.dubbo.provider; + +/** + * @author leyou + */ +public interface DemoService { + String sayHello(String name, int n); +} diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/provider/impl/DemoServiceImpl.java b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/provider/impl/DemoServiceImpl.java new file mode 100644 index 00000000..f804c2c4 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/provider/impl/DemoServiceImpl.java @@ -0,0 +1,27 @@ +/* + * 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.adapter.dubbo.provider.impl; + +import com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService; + +/** + * @author leyou + */ +public class DemoServiceImpl implements DemoService { + public String sayHello(String name, int n) { + return "Hello " + name + ", " + n; + } +} diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/resources/spring-dubbo-consumer-filter.xml b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/resources/spring-dubbo-consumer-filter.xml new file mode 100755 index 00000000..b129cc9d --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/resources/spring-dubbo-consumer-filter.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/resources/spring-dubbo-provider-filter.xml b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/resources/spring-dubbo-provider-filter.xml new file mode 100755 index 00000000..bc4a8fb9 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/src/test/resources/spring-dubbo-provider-filter.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/sentinel-adapter/sentinel-dubbo-adapter/README.md b/sentinel-adapter/sentinel-dubbo-adapter/README.md index b29e3705..cbeb0e2e 100755 --- a/sentinel-adapter/sentinel-dubbo-adapter/README.md +++ b/sentinel-adapter/sentinel-dubbo-adapter/README.md @@ -3,7 +3,10 @@ > Note: 中文文档请见[此处](https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#dubbo)。 Sentinel Dubbo Adapter provides service consumer filter and provider filter -for [Dubbo](http://dubbo.io/) services. +for [Dubbo](https://dubbo.apache.org/en-us/) services. + +**Note: This adapter only supports legacy Dubbo 2.6.x version and below.** +For new Apache Dubbo 2.7.x or above version, please use `sentinel-apache-dubbo-adapter` module instead. To use Sentinel Dubbo Adapter, you can simply add the following dependency to your `pom.xml`: @@ -28,7 +31,7 @@ If you don't want the filters enabled, you can manually disable them. For exampl ``` -For more details of Dubbo filter, see [here](https://dubbo.incubator.apache.org/#/docs/dev/impls/filter.md?lang=en-us). +For more details of Dubbo filter, see [here](http://dubbo.apache.org/en-us/docs/dev/impls/filter.html). ## Dubbo resources @@ -62,4 +65,4 @@ flow control, degrade or system load protection. You can implement your own `Dub and then register to `DubboFallbackRegistry`. If no fallback is configured, Sentinel will wrap the `BlockException` then directly throw it out. -Besides, we can also leverage [Dubbo mock mechanism](http://dubbo.apache.org/#!/docs/user/demos/local-mock.md?lang=en-us) to provide fallback implementation of degraded Dubbo services. \ No newline at end of file +Besides, we can also leverage [Dubbo mock mechanism](http://dubbo.apache.org/en-us/docs/user/demos/local-mock.html) to provide fallback implementation of degraded Dubbo services. \ No newline at end of file