From d8714cacebeafd3adb463a58573d5b7940f4fab8 Mon Sep 17 00:00:00 2001 From: iron_city <55343460+DogBaoBao@users.noreply.github.com> Date: Sun, 28 Jun 2020 11:48:35 +0800 Subject: [PATCH] Support customized origin parser in legacy Dubbo 2.6.x adapter (#1555) --- .../sentinel-dubbo-adapter/README.md | 8 +- .../dubbo/SentinelDubboProviderFilter.java | 8 +- .../origin/DefaultDubboOriginParser.java | 34 +++++++++ .../dubbo/origin/DubboOriginParser.java | 38 ++++++++++ .../origin/DubboOriginParserRegistry.java | 37 ++++++++++ .../dubbo/origin/DubboOriginRegistryTest.java | 74 +++++++++++++++++++ 6 files changed, 196 insertions(+), 3 deletions(-) create mode 100644 sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/origin/DefaultDubboOriginParser.java create mode 100644 sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/origin/DubboOriginParser.java create mode 100644 sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/origin/DubboOriginParserRegistry.java create mode 100644 sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/origin/DubboOriginRegistryTest.java diff --git a/sentinel-adapter/sentinel-dubbo-adapter/README.md b/sentinel-adapter/sentinel-dubbo-adapter/README.md index cbeb0e2e..f72fca45 100755 --- a/sentinel-adapter/sentinel-dubbo-adapter/README.md +++ b/sentinel-adapter/sentinel-dubbo-adapter/README.md @@ -65,4 +65,10 @@ 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/en-us/docs/user/demos/local-mock.html) 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. + +## Global dubbo provider origin parse + +Sentinel Dubbo Adapter supports global origin parse for provider. +You can implement your own `DubboOriginParser` interface +and then register to `DubboOriginParserRegistry`. If no originParse is configured, Sentinel will user dubbo url property application. \ No newline at end of file diff --git a/sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilter.java b/sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilter.java index 85d566ad..959281ac 100755 --- a/sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilter.java +++ b/sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilter.java @@ -22,6 +22,7 @@ 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.adapter.dubbo.origin.DubboOriginParserRegistry; import com.alibaba.csp.sentinel.context.ContextUtil; import com.alibaba.csp.sentinel.log.RecordLog; import com.alibaba.csp.sentinel.slots.block.BlockException; @@ -55,14 +56,17 @@ public class SentinelDubboProviderFilter extends AbstractDubboFilter implements @Override public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { // Get origin caller. - String application = DubboUtils.getApplication(invocation, ""); + String origin = DubboOriginParserRegistry.getDubboOriginParser().parse(invoker, invocation); + if (null == origin) { + origin = ""; + } Entry interfaceEntry = null; Entry methodEntry = null; try { String resourceName = getResourceName(invoker, invocation, DubboConfig.getDubboProviderPrefix()); String interfaceName = invoker.getInterface().getName(); - ContextUtil.enter(resourceName, application); + ContextUtil.enter(resourceName, origin); interfaceEntry = SphU.entry(interfaceName, ResourceTypeConstants.COMMON_RPC, EntryType.IN); methodEntry = SphU.entry(resourceName, ResourceTypeConstants.COMMON_RPC, EntryType.IN, invocation.getArguments()); diff --git a/sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/origin/DefaultDubboOriginParser.java b/sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/origin/DefaultDubboOriginParser.java new file mode 100644 index 00000000..015fd2ef --- /dev/null +++ b/sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/origin/DefaultDubboOriginParser.java @@ -0,0 +1,34 @@ +/* + * Copyright 1999-2020 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 + * + * https://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.origin; + +import com.alibaba.csp.sentinel.adapter.dubbo.DubboUtils; +import com.alibaba.dubbo.rpc.Invocation; +import com.alibaba.dubbo.rpc.Invoker; + +/** + * Default Dubbo origin parse. + * + * @author tiecheng + */ +public class DefaultDubboOriginParser implements DubboOriginParser { + + @Override + public String parse(Invoker invoker, Invocation invocation) { + return DubboUtils.getApplication(invocation, ""); + } + +} diff --git a/sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/origin/DubboOriginParser.java b/sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/origin/DubboOriginParser.java new file mode 100644 index 00000000..ecaca0d2 --- /dev/null +++ b/sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/origin/DubboOriginParser.java @@ -0,0 +1,38 @@ +/* + * Copyright 1999-2020 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 + * + * https://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.origin; + +import com.alibaba.csp.sentinel.context.Context; +import com.alibaba.dubbo.rpc.Invocation; +import com.alibaba.dubbo.rpc.Invoker; + +/** + * Customized origin parse in Dubbo provider filter. {@link Context#getOrigin()} + * + * @author tiecheng + */ +public interface DubboOriginParser { + + /** + * Handle the origin parse. + * + * @param invoker Dubbo invoker + * @param invocation Dubbo invocation + * @return parse result + */ + String parse(Invoker invoker, Invocation invocation); + +} diff --git a/sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/origin/DubboOriginParserRegistry.java b/sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/origin/DubboOriginParserRegistry.java new file mode 100644 index 00000000..a25a9c0a --- /dev/null +++ b/sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/origin/DubboOriginParserRegistry.java @@ -0,0 +1,37 @@ +/* + * Copyright 1999-2020 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 + * + * https://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.origin; + +/** + * Global origin parser registry for Dubbo. + * + * @author tiecheng + */ +public final class DubboOriginParserRegistry { + + private static volatile DubboOriginParser dubboOriginParser = new DefaultDubboOriginParser(); + + public static DubboOriginParser getDubboOriginParser() { + return dubboOriginParser; + } + + public static void setDubboOriginParser(DubboOriginParser dubboOriginParser) { + DubboOriginParserRegistry.dubboOriginParser = dubboOriginParser; + } + + private DubboOriginParserRegistry() {} + +} diff --git a/sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/origin/DubboOriginRegistryTest.java b/sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/origin/DubboOriginRegistryTest.java new file mode 100644 index 00000000..e5a1eff1 --- /dev/null +++ b/sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/origin/DubboOriginRegistryTest.java @@ -0,0 +1,74 @@ +/* + * Copyright 1999-2020 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 + * + * https://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.origin; + +import com.alibaba.csp.sentinel.adapter.dubbo.DubboUtils; +import com.alibaba.dubbo.rpc.Invocation; +import com.alibaba.dubbo.rpc.Invoker; +import com.alibaba.dubbo.rpc.RpcInvocation; +import org.junit.After; +import org.junit.Assert; +import org.junit.Test; + +/** + * @author tiecheng + */ +public class DubboOriginRegistryTest { + + @After + public void cleanUp() { + DubboOriginParserRegistry.setDubboOriginParser(new DefaultDubboOriginParser()); + } + + @Test(expected = IllegalArgumentException.class) + public void testDefaultOriginParserFail() { + DubboOriginParserRegistry.getDubboOriginParser().parse(null, null); + } + + @Test + public void testDefaultOriginParserSuccess() { + RpcInvocation invocation = new RpcInvocation(); + String dubboName = "sentinel"; + invocation.setAttachment(DubboUtils.DUBBO_APPLICATION_KEY, dubboName); + String origin = DubboOriginParserRegistry.getDubboOriginParser().parse(null, invocation); + Assert.assertEquals(dubboName, origin); + } + + @Test + public void testCustomOriginParser() { + DubboOriginParserRegistry.setDubboOriginParser(new DubboOriginParser() { + @Override + public String parse(Invoker invoker, Invocation invocation) { + return invocation.getAttachment(DubboUtils.DUBBO_APPLICATION_KEY, "default") + "_" + invocation + .getMethodName(); + } + }); + + RpcInvocation invocation = new RpcInvocation(); + String origin = DubboOriginParserRegistry.getDubboOriginParser().parse(null, invocation); + Assert.assertEquals("default_null", origin); + + String dubboName = "sentinel"; + invocation.setAttachment(DubboUtils.DUBBO_APPLICATION_KEY, dubboName); + origin = DubboOriginParserRegistry.getDubboOriginParser().parse(null, invocation); + Assert.assertEquals(dubboName + "_null", origin); + + invocation.setMethodName("hello"); + origin = DubboOriginParserRegistry.getDubboOriginParser().parse(null, invocation); + Assert.assertEquals(dubboName + "_hello", origin); + } + +}