@@ -15,6 +15,7 @@ | |||
*/ | |||
package com.alibaba.csp.sentinel.adapter.dubbo; | |||
import com.alibaba.csp.sentinel.util.StringUtil; | |||
import org.apache.dubbo.rpc.Invocation; | |||
import org.apache.dubbo.rpc.Invoker; | |||
@@ -35,9 +36,9 @@ public final class DubboUtils { | |||
public static String getResourceName(Invoker<?> invoker, Invocation invocation) { | |||
StringBuilder buf = new StringBuilder(64); | |||
buf.append(invoker.getInterface().getName()) | |||
.append(":") | |||
.append(invocation.getMethodName()) | |||
.append("("); | |||
.append(":") | |||
.append(invocation.getMethodName()) | |||
.append("("); | |||
boolean isFirst = true; | |||
for (Class<?> clazz : invocation.getParameterTypes()) { | |||
if (!isFirst) { | |||
@@ -50,5 +51,17 @@ public final class DubboUtils { | |||
return buf.toString(); | |||
} | |||
private DubboUtils() {} | |||
public static String getResourceName(Invoker<?> invoker, Invocation invocation, String prefix) { | |||
if (StringUtil.isNotBlank(prefix)) { | |||
return new StringBuilder(64) | |||
.append(prefix) | |||
.append(getResourceName(invoker, invocation)) | |||
.toString(); | |||
} else { | |||
return getResourceName(invoker, invocation); | |||
} | |||
} | |||
private DubboUtils() { | |||
} | |||
} |
@@ -19,10 +19,10 @@ 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.config.DubboConfig; | |||
import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DubboFallbackRegistry; | |||
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; | |||
@@ -32,7 +32,7 @@ import org.apache.dubbo.rpc.RpcException; | |||
/** | |||
* <p>Dubbo service consumer filter for Sentinel. Auto activated by default.</p> | |||
* | |||
* <p> | |||
* If you want to disable the consumer filter, you can configure: | |||
* <pre> | |||
* <dubbo:consumer filter="-sentinel.dubbo.consumer.filter"/> | |||
@@ -53,7 +53,7 @@ public class SentinelDubboConsumerFilter implements Filter { | |||
Entry interfaceEntry = null; | |||
Entry methodEntry = null; | |||
try { | |||
String resourceName = DubboUtils.getResourceName(invoker, invocation); | |||
String resourceName = DubboUtils.getResourceName(invoker, invocation, DubboConfig.getDubboConsumerPrefix()); | |||
interfaceEntry = SphU.entry(invoker.getInterface().getName(), EntryType.OUT); | |||
methodEntry = SphU.entry(resourceName, EntryType.OUT); | |||
@@ -19,11 +19,11 @@ 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.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; | |||
@@ -34,7 +34,7 @@ import org.apache.dubbo.rpc.RpcException; | |||
/** | |||
* <p>Apache Dubbo service provider filter that enables integration with Sentinel. Auto activated by default.</p> | |||
* <p>Note: this only works for Apache Dubbo 2.7.x or above version.</p> | |||
* | |||
* <p> | |||
* If you want to disable the provider filter, you can configure: | |||
* <pre> | |||
* <dubbo:provider filter="-sentinel.dubbo.provider.filter"/> | |||
@@ -58,7 +58,7 @@ public class SentinelDubboProviderFilter implements Filter { | |||
Entry interfaceEntry = null; | |||
Entry methodEntry = null; | |||
try { | |||
String resourceName = DubboUtils.getResourceName(invoker, invocation); | |||
String resourceName = DubboUtils.getResourceName(invoker, invocation, DubboConfig.getDubboProviderPrefix()); | |||
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). | |||
@@ -0,0 +1,62 @@ | |||
/* | |||
* 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.config; | |||
import com.alibaba.csp.sentinel.config.SentinelConfig; | |||
import com.alibaba.csp.sentinel.util.StringUtil; | |||
/** | |||
* <p> | |||
* Responsible for dubbo service provider, consumer attribute configuration | |||
* </p> | |||
* | |||
* @author lianglin | |||
* @since 1.7.0 | |||
*/ | |||
public final class DubboConfig { | |||
public static final String DUBBO_USE_PREFIX = "csp.sentinel.dubbo.resource.use.prefix"; | |||
private static final String TRUE_STR = "true"; | |||
public static final String DUBBO_PROVIDER_PREFIX = "csp.sentinel.dubbo.resource.provider.prefix"; | |||
public static final String DUBBO_CONSUMER_PREFIX = "csp.sentinel.dubbo.resource.consumer.prefix"; | |||
private static final String DEFAULT_DUBBO_PROVIDER_PREFIX = "dubbo:provider:"; | |||
private static final String DEFAULT_DUBBO_CONSUMER_PREFIX = "dubbo:consumer:"; | |||
public static boolean isUsePrefix(){ | |||
return TRUE_STR.equalsIgnoreCase(SentinelConfig.getConfig(DUBBO_USE_PREFIX)); | |||
} | |||
public static String getDubboProviderPrefix() { | |||
if (isUsePrefix()) { | |||
String config = SentinelConfig.getConfig(DUBBO_PROVIDER_PREFIX); | |||
return StringUtil.isNotBlank(config) ? config : DEFAULT_DUBBO_PROVIDER_PREFIX; | |||
} | |||
return null; | |||
} | |||
public static String getDubboConsumerPrefix() { | |||
if (isUsePrefix()) { | |||
String config = SentinelConfig.getConfig(DUBBO_CONSUMER_PREFIX); | |||
return StringUtil.isNotBlank(config) ? config : DEFAULT_DUBBO_CONSUMER_PREFIX; | |||
} | |||
return null; | |||
} | |||
} |
@@ -15,15 +15,18 @@ | |||
*/ | |||
package com.alibaba.csp.sentinel.adapter.dubbo; | |||
import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboConfig; | |||
import com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService; | |||
import com.alibaba.csp.sentinel.config.SentinelConfig; | |||
import org.apache.dubbo.rpc.Invocation; | |||
import org.apache.dubbo.rpc.Invoker; | |||
import org.junit.After; | |||
import org.junit.Before; | |||
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.*; | |||
@@ -33,12 +36,28 @@ import static org.mockito.Mockito.*; | |||
*/ | |||
public class DubboUtilsTest { | |||
@Before | |||
public void setUp() { | |||
SentinelConfig.setConfig("csp.sentinel.dubbo.resource.use.prefix", "true"); | |||
SentinelConfig.setConfig(DubboConfig.DUBBO_PROVIDER_PREFIX, ""); | |||
SentinelConfig.setConfig(DubboConfig.DUBBO_CONSUMER_PREFIX, ""); | |||
} | |||
@After | |||
public void tearDown() { | |||
SentinelConfig.setConfig("csp.sentinel.dubbo.resource.use.prefix", "false"); | |||
SentinelConfig.setConfig(DubboConfig.DUBBO_PROVIDER_PREFIX, ""); | |||
SentinelConfig.setConfig(DubboConfig.DUBBO_CONSUMER_PREFIX, ""); | |||
} | |||
@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"); | |||
.thenReturn("consumerA"); | |||
String application = DubboUtils.getApplication(invocation, ""); | |||
verify(invocation).getAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, ""); | |||
@@ -51,7 +70,7 @@ public class DubboUtilsTest { | |||
Invocation invocation = mock(Invocation.class); | |||
when(invocation.getAttachments()).thenReturn(null); | |||
when(invocation.getAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, "")) | |||
.thenReturn("consumerA"); | |||
.thenReturn("consumerA"); | |||
DubboUtils.getApplication(invocation, ""); | |||
@@ -72,4 +91,31 @@ public class DubboUtilsTest { | |||
assertEquals("com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName); | |||
} | |||
@Test | |||
public void testGetResourceNameWithPrefix() { | |||
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()); | |||
//test with default prefix | |||
String resourceName = DubboUtils.getResourceName(invoker, invocation, DubboConfig.getDubboProviderPrefix()); | |||
assertEquals("dubbo:provider:com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName); | |||
resourceName = DubboUtils.getResourceName(invoker, invocation, DubboConfig.getDubboConsumerPrefix()); | |||
assertEquals("dubbo:consumer:com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName); | |||
//test with custom prefix | |||
SentinelConfig.setConfig(DubboConfig.DUBBO_PROVIDER_PREFIX, "my:dubbo:provider:"); | |||
SentinelConfig.setConfig(DubboConfig.DUBBO_CONSUMER_PREFIX, "my:dubbo:consumer:"); | |||
resourceName = DubboUtils.getResourceName(invoker, invocation, DubboConfig.getDubboProviderPrefix()); | |||
assertEquals("my:dubbo:provider:com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName); | |||
resourceName = DubboUtils.getResourceName(invoker, invocation, DubboConfig.getDubboConsumerPrefix()); | |||
assertEquals("my:dubbo:consumer:com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName); | |||
} | |||
} |
@@ -15,6 +15,7 @@ | |||
*/ | |||
package com.alibaba.csp.sentinel.adapter.dubbo; | |||
import com.alibaba.csp.sentinel.util.StringUtil; | |||
import com.alibaba.dubbo.rpc.Filter; | |||
import com.alibaba.dubbo.rpc.Invocation; | |||
import com.alibaba.dubbo.rpc.Invoker; | |||
@@ -27,9 +28,9 @@ abstract class AbstractDubboFilter implements Filter { | |||
protected String getResourceName(Invoker<?> invoker, Invocation invocation) { | |||
StringBuilder buf = new StringBuilder(64); | |||
buf.append(invoker.getInterface().getName()) | |||
.append(":") | |||
.append(invocation.getMethodName()) | |||
.append("("); | |||
.append(":") | |||
.append(invocation.getMethodName()) | |||
.append("("); | |||
boolean isFirst = true; | |||
for (Class<?> clazz : invocation.getParameterTypes()) { | |||
if (!isFirst) { | |||
@@ -41,4 +42,16 @@ abstract class AbstractDubboFilter implements Filter { | |||
buf.append(")"); | |||
return buf.toString(); | |||
} | |||
protected String getResourceName(Invoker<?> invoker, Invocation invocation, String prefix) { | |||
if (StringUtil.isBlank(prefix)) { | |||
return getResourceName(invoker, invocation); | |||
} | |||
StringBuilder buf = new StringBuilder(64); | |||
return buf.append(prefix) | |||
.append(getResourceName(invoker, invocation)) | |||
.toString(); | |||
} | |||
} |
@@ -19,8 +19,8 @@ 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.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 com.alibaba.dubbo.common.extension.Activate; | |||
@@ -53,7 +53,7 @@ public class SentinelDubboConsumerFilter extends AbstractDubboFilter implements | |||
Entry interfaceEntry = null; | |||
Entry methodEntry = null; | |||
try { | |||
String resourceName = getResourceName(invoker, invocation); | |||
String resourceName = getResourceName(invoker, invocation, DubboConfig.getDubboConsumerPrefix()); | |||
interfaceEntry = SphU.entry(invoker.getInterface().getName(), EntryType.OUT); | |||
methodEntry = SphU.entry(resourceName, EntryType.OUT); | |||
@@ -19,11 +19,11 @@ 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.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 com.alibaba.csp.sentinel.slots.block.SentinelRpcException; | |||
import com.alibaba.dubbo.common.extension.Activate; | |||
import com.alibaba.dubbo.rpc.Filter; | |||
import com.alibaba.dubbo.rpc.Invocation; | |||
@@ -57,7 +57,7 @@ public class SentinelDubboProviderFilter extends AbstractDubboFilter implements | |||
Entry interfaceEntry = null; | |||
Entry methodEntry = null; | |||
try { | |||
String resourceName = getResourceName(invoker, invocation); | |||
String resourceName = getResourceName(invoker, invocation, DubboConfig.getDubboProviderPrefix()); | |||
String interfaceName = invoker.getInterface().getName(); | |||
ContextUtil.enter(resourceName, application); | |||
interfaceEntry = SphU.entry(interfaceName, EntryType.IN); | |||
@@ -0,0 +1,62 @@ | |||
/* | |||
* 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.config; | |||
import com.alibaba.csp.sentinel.config.SentinelConfig; | |||
import com.alibaba.csp.sentinel.util.StringUtil; | |||
/** | |||
* <p> | |||
* Responsible for dubbo service provider, consumer attribute configuration | |||
* </p> | |||
* | |||
* @author lianglin | |||
* @since 1.7.0 | |||
*/ | |||
public final class DubboConfig { | |||
public static final String DUBBO_USE_PREFIX = "csp.sentinel.dubbo.resource.use.prefix"; | |||
private static final String TRUE_STR = "true"; | |||
public static final String DUBBO_PROVIDER_PREFIX = "csp.sentinel.dubbo.resource.provider.prefix"; | |||
public static final String DUBBO_CONSUMER_PREFIX = "csp.sentinel.dubbo.resource.consumer.prefix"; | |||
private static final String DEFAULT_DUBBO_PROVIDER_PREFIX = "dubbo:provider:"; | |||
private static final String DEFAULT_DUBBO_CONSUMER_PREFIX = "dubbo:consumer:"; | |||
public static boolean isUsePrefix() { | |||
return TRUE_STR.equalsIgnoreCase(SentinelConfig.getConfig(DUBBO_USE_PREFIX)); | |||
} | |||
public static String getDubboProviderPrefix() { | |||
if (isUsePrefix()) { | |||
String config = SentinelConfig.getConfig(DUBBO_PROVIDER_PREFIX); | |||
return StringUtil.isNotBlank(config) ? config : DEFAULT_DUBBO_PROVIDER_PREFIX; | |||
} | |||
return null; | |||
} | |||
public static String getDubboConsumerPrefix() { | |||
if (isUsePrefix()) { | |||
String config = SentinelConfig.getConfig(DUBBO_CONSUMER_PREFIX); | |||
return StringUtil.isNotBlank(config) ? config : DEFAULT_DUBBO_CONSUMER_PREFIX; | |||
} | |||
return null; | |||
} | |||
} |
@@ -1,22 +1,42 @@ | |||
package com.alibaba.csp.sentinel.adapter.dubbo; | |||
import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboConfig; | |||
import com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService; | |||
import com.alibaba.csp.sentinel.config.SentinelConfig; | |||
import com.alibaba.dubbo.rpc.Invocation; | |||
import com.alibaba.dubbo.rpc.Invoker; | |||
import com.alibaba.dubbo.rpc.Result; | |||
import com.alibaba.dubbo.rpc.RpcException; | |||
import org.junit.After; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import java.lang.reflect.Method; | |||
import static org.junit.Assert.*; | |||
import static org.mockito.Mockito.*; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
/** | |||
* @author cdfive | |||
*/ | |||
public class AbstractDubboFilterTest { | |||
@Before | |||
public void setUp() { | |||
SentinelConfig.setConfig("csp.sentinel.dubbo.resource.use.prefix", "true"); | |||
SentinelConfig.setConfig(DubboConfig.DUBBO_PROVIDER_PREFIX, ""); | |||
SentinelConfig.setConfig(DubboConfig.DUBBO_CONSUMER_PREFIX, ""); | |||
} | |||
@After | |||
public void tearDown() { | |||
SentinelConfig.setConfig("csp.sentinel.dubbo.resource.use.prefix", "false"); | |||
SentinelConfig.setConfig(DubboConfig.DUBBO_PROVIDER_PREFIX, ""); | |||
SentinelConfig.setConfig(DubboConfig.DUBBO_CONSUMER_PREFIX, ""); | |||
} | |||
private AbstractDubboFilter filter = new AbstractDubboFilter() { | |||
@Override | |||
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { | |||
@@ -24,6 +44,7 @@ public class AbstractDubboFilterTest { | |||
} | |||
}; | |||
@Test | |||
public void testGetResourceName() { | |||
Invoker invoker = mock(Invoker.class); | |||
@@ -38,4 +59,32 @@ public class AbstractDubboFilterTest { | |||
assertEquals("com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName); | |||
} | |||
@Test | |||
public void testGetResourceNameWithPrefix() { | |||
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()); | |||
//test with default prefix | |||
String resourceName = filter.getResourceName(invoker, invocation, DubboConfig.getDubboProviderPrefix()); | |||
System.out.println("resourceName = " + resourceName); | |||
assertEquals("dubbo:provider:com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName); | |||
resourceName = filter.getResourceName(invoker, invocation, DubboConfig.getDubboConsumerPrefix()); | |||
assertEquals("dubbo:consumer:com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName); | |||
//test with custom prefix | |||
SentinelConfig.setConfig(DubboConfig.DUBBO_PROVIDER_PREFIX, "my:dubbo:provider:"); | |||
SentinelConfig.setConfig(DubboConfig.DUBBO_CONSUMER_PREFIX, "my:dubbo:consumer:"); | |||
resourceName = filter.getResourceName(invoker, invocation, DubboConfig.getDubboProviderPrefix()); | |||
assertEquals("my:dubbo:provider:com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName); | |||
resourceName = filter.getResourceName(invoker, invocation, DubboConfig.getDubboConsumerPrefix()); | |||
assertEquals("my:dubbo:consumer:com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName); | |||
} | |||
} |