Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Adapter] Support motan RPC #1825

Merged
merged 6 commits into from
Dec 5, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sentinel-adapter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
<module>sentinel-okhttp-adapter</module>
<module>sentinel-jax-rs-adapter</module>
<module>sentinel-quarkus-adapter</module>
<module>sentinel-motan-adapter</module>
</modules>

<dependencyManagement>
Expand Down
50 changes: 50 additions & 0 deletions sentinel-adapter/sentinel-motan-adapter/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>sentinel-adapter</artifactId>
<groupId>com.alibaba.csp</groupId>
<version>1.8.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>sentinel-motan-adapter</artifactId>
<packaging>jar</packaging>

<properties>
<motan.version>1.1.8</motan.version>
</properties>

<dependencies>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
</dependency>
<dependency>
<groupId>com.weibo</groupId>
<artifactId>motan-core</artifactId>
<version>${motan.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.weibo</groupId>
<artifactId>motan-transport-netty4</artifactId>
<version>${motan.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.version}</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>${java.encoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.alibaba.csp.sentinel.adapter.motan;

import com.alibaba.csp.sentinel.adapter.motan.config.MotanAdapterGlobalConfig;
import com.weibo.api.motan.core.extension.Activation;
import com.weibo.api.motan.core.extension.SpiMeta;
import com.weibo.api.motan.filter.Filter;
import com.weibo.api.motan.rpc.Caller;
import com.weibo.api.motan.rpc.Request;

/**
* author: zhangxn8
*/
@SpiMeta(name = MotanAdapterGlobalConfig.BASE_SENTINEL_MOTAN_FILTER)
@Activation(sequence = 1)
public abstract class BaseMotanSentinelFilter implements Filter {

/**
* Get method name of motan rpc
*
* @param caller
* @param request
* @return
*/
abstract String getMethodName(Caller<?> caller, Request request, String prefix);

/**
* Get interface name of motan rpc
*
* @param caller
* @return
*/
abstract String getInterfaceName(Caller<?> caller, String prefix);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.alibaba.csp.sentinel.adapter.motan;

import com.alibaba.csp.sentinel.adapter.motan.config.MotanAdapterGlobalConfig;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.weibo.api.motan.rpc.Caller;
import com.weibo.api.motan.rpc.Request;
import com.weibo.api.motan.util.ReflectUtil;

/**
* author: zhangxn8
*/
public class MotanUtils {

private MotanUtils() {}

public static String getMethodResourceName(Caller<?> caller, Request request){
return getMethodResourceName(caller, request, false);
}

public static String getMethodResourceName(Caller<?> caller, Request request, Boolean useGroupAndVersion) {
StringBuilder buf = new StringBuilder(64);
String interfaceResource = useGroupAndVersion ? caller.getUrl().getPath(): caller.getInterface().getName();
buf.append(interfaceResource)
.append(":")
.append(request.getMethodName())
.append("(");
boolean isFirst = true;
try {
Class<?>[] classTypes = ReflectUtil.forNames(request.getParamtersDesc());
for (Class<?> clazz : classTypes) {
if (!isFirst) {
buf.append(",");
}
buf.append(clazz.getName());
isFirst = false;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
buf.append(")");
return buf.toString();
}

public static String getMethodResourceName(Caller<?> caller, Request request, String prefix) {
if (StringUtil.isNotBlank(prefix)) {
return new StringBuilder(64)
.append(prefix)
.append(getMethodResourceName(caller, request,MotanAdapterGlobalConfig.getMotanInterfaceGroupAndVersionEnabled()))
.toString();
} else {
return getMethodResourceName(caller, request,MotanAdapterGlobalConfig.getMotanInterfaceGroupAndVersionEnabled());
}
}

public static String getInterfaceName(Caller<?> caller) {
return getInterfaceName(caller, false);
}

public static String getInterfaceName(Caller<?> caller, Boolean useGroupAndVersion) {
return useGroupAndVersion ? caller.getUrl().getApplication() : caller.getInterface().getName();
}

public static String getInterfaceName(Caller<?> caller, String prefix) {
if (StringUtil.isNotBlank(prefix)) {
return new StringBuilder(64)
.append(prefix)
.append(getInterfaceName(caller, MotanAdapterGlobalConfig.getMotanInterfaceGroupAndVersionEnabled()))
.toString();
} else {
return getInterfaceName(caller, MotanAdapterGlobalConfig.getMotanInterfaceGroupAndVersionEnabled());
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.alibaba.csp.sentinel.adapter.motan;

import com.alibaba.csp.sentinel.*;
import com.alibaba.csp.sentinel.adapter.motan.config.MotanAdapterGlobalConfig;
import com.alibaba.csp.sentinel.log.RecordLog;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.weibo.api.motan.common.MotanConstants;
import com.weibo.api.motan.core.extension.Activation;
import com.weibo.api.motan.core.extension.SpiMeta;
import com.weibo.api.motan.exception.MotanAbstractException;
import com.weibo.api.motan.rpc.Caller;
import com.weibo.api.motan.rpc.Request;
import com.weibo.api.motan.rpc.Response;

/**
* author: zhangxn8
*/
@Activation(key = MotanConstants.NODE_TYPE_REFERER)
@SpiMeta(name = MotanAdapterGlobalConfig.SENTINEL_MOTAN_CONSUMER)
public class SentinelMotanConsumerFilter extends BaseMotanSentinelFilter {

public SentinelMotanConsumerFilter(){
RecordLog.info("Sentinel motan consumer filter initialized");
}

@Override
String getMethodName(Caller<?> caller, Request request, String prefix) {
return MotanUtils.getMethodResourceName(caller, request, prefix);
}

@Override
String getInterfaceName(Caller<?> caller, String prefix) {
return MotanUtils.getInterfaceName(caller, prefix);
}

@Override
public Response filter(Caller<?> caller, Request request) {
Entry interfaceEntry = null;
Entry methodEntry = null;
String prefix = MotanAdapterGlobalConfig.getMotanConsumerPrefix();
String interfaceResourceName = getInterfaceName(caller, prefix);
String methodResourceName = getMethodName(caller, request, prefix);
try {
interfaceEntry = SphU.entry(interfaceResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT);
methodEntry = SphU.entry(methodResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT,
request.getArguments());
Response result = caller.call(request);
if (result.getException() != null) {
Tracer.traceEntry(result.getException(), interfaceEntry);
Tracer.traceEntry(result.getException(), methodEntry);
}
return result;
} catch (BlockException e) {
return MotanAdapterGlobalConfig.getConsumerFallback().handle(caller, request, e);
} catch (MotanAbstractException e) {
Tracer.traceEntry(e, interfaceEntry);
Tracer.traceEntry(e, methodEntry);
throw e;
} finally {
if (methodEntry != null) {
methodEntry.exit(1, request.getArguments());
}
if (interfaceEntry != null) {
interfaceEntry.exit();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.alibaba.csp.sentinel.adapter.motan;

import com.alibaba.csp.sentinel.*;
import com.alibaba.csp.sentinel.adapter.motan.config.MotanAdapterGlobalConfig;
import com.alibaba.csp.sentinel.context.ContextUtil;
import com.alibaba.csp.sentinel.log.RecordLog;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.weibo.api.motan.common.MotanConstants;
import com.weibo.api.motan.core.extension.Activation;
import com.weibo.api.motan.core.extension.SpiMeta;
import com.weibo.api.motan.exception.MotanAbstractException;
import com.weibo.api.motan.rpc.Caller;
import com.weibo.api.motan.rpc.Request;
import com.weibo.api.motan.rpc.Response;

import java.util.Map;

/**
* author: zhangxn8
*/
@Activation(key = MotanConstants.NODE_TYPE_SERVICE)
@SpiMeta(name = MotanAdapterGlobalConfig.SENTINEL_MOTAN_PROVIDER)
public class SentinelMotanProviderFilter extends BaseMotanSentinelFilter {

public SentinelMotanProviderFilter(){
RecordLog.info("Sentinel motan provider filter initialized");
}

@Override
String getMethodName(Caller<?> caller, Request request, String prefix) {
return MotanUtils.getMethodResourceName(caller, request, prefix);
}

@Override
String getInterfaceName(Caller<?> caller, String prefix) {
return MotanUtils.getInterfaceName(caller, prefix);
}

@Override
public Response filter(Caller<?> caller, Request request) {
Entry interfaceEntry = null;
Entry methodEntry = null;
Map<String, String> attachment = request.getAttachments();
String origin = attachment.getOrDefault(MotanAdapterGlobalConfig.APPLICATION, MotanAdapterGlobalConfig.MOTAN);
String prefix = MotanAdapterGlobalConfig.getMotanProviderPrefix();
String interfaceResourceName = getInterfaceName(caller, prefix);
String methodResourceName = getMethodName(caller, request, prefix);
try {
ContextUtil.enter(methodResourceName, origin);
interfaceEntry = SphU.entry(interfaceResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.IN);
methodEntry = SphU.entry(methodResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.IN,
request.getArguments());
Response result = caller.call(request);
if (result.getException() != null) {
Tracer.traceEntry(result.getException(), interfaceEntry);
Tracer.traceEntry(result.getException(), methodEntry);
}
return result;
} catch (BlockException e) {
return MotanAdapterGlobalConfig.getProviderFallback().handle(caller, request, e);
} catch (MotanAbstractException e) {
Tracer.traceEntry(e, interfaceEntry);
Tracer.traceEntry(e, methodEntry);
throw e;
} finally {
if (methodEntry != null) {
methodEntry.exit(1, request.getArguments());
}
if (interfaceEntry != null) {
interfaceEntry.exit();
}
ContextUtil.exit();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.alibaba.csp.sentinel.adapter.motan.config;

import com.alibaba.csp.sentinel.adapter.motan.fallback.DefaultMotanFallback;
import com.alibaba.csp.sentinel.adapter.motan.fallback.MotanFallback;
import com.alibaba.csp.sentinel.config.SentinelConfig;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.csp.sentinel.util.StringUtil;

/**
* author: zhangxn8
*/
public class MotanAdapterGlobalConfig {

private static final String TRUE_STR = "true";

public static final String APPLICATION = "application";
public static final String MOTAN = "motan";

public static final String BASE_SENTINEL_MOTAN_FILTER = "baseSentinelMotanFilter";
public static final String MOTAN_APP_CONTEXT = "motanAppContext";
public static final String SENTINEL_MOTAN_CONSUMER = "sentinelMotanConsumer";
public static final String SENTINEL_MOTAN_PROVIDER = "sentinelMotanProvider";

public static final String MOTAN_RES_NAME_WITH_PREFIX_KEY = "csp.sentinel.motan.resource.use.prefix";
public static final String MOTAN_PROVIDER_RES_NAME_PREFIX_KEY = "csp.sentinel.motan.resource.provider.prefix";
public static final String MOTAN_CONSUMER_RES_NAME_PREFIX_KEY = "csp.sentinel.motan.resource.consumer.prefix";

public static final String MOTAN_INTERFACE_GROUP_VERSION_ENABLED = "csp.sentinel.motan.interface.group.version.enabled";

private static final String DEFAULT_MOTAN_PROVIDER_PREFIX = "motan:provider:";
private static final String DEFAULT_MOTAN_CONSUMER_PREFIX = "motan:consumer:";

private static volatile MotanFallback consumerFallback = new DefaultMotanFallback();
private static volatile MotanFallback providerFallback = new DefaultMotanFallback();

private MotanAdapterGlobalConfig() {}

public static boolean isUsePrefix() {
return TRUE_STR.equalsIgnoreCase(SentinelConfig.getConfig(MOTAN_RES_NAME_WITH_PREFIX_KEY));
}

public static String getMotanProviderPrefix() {
if (isUsePrefix()) {
String config = SentinelConfig.getConfig(MOTAN_PROVIDER_RES_NAME_PREFIX_KEY);
return StringUtil.isNotBlank(config) ? config : DEFAULT_MOTAN_PROVIDER_PREFIX;
}
return null;
}

public static String getMotanConsumerPrefix() {
if (isUsePrefix()) {
String config = SentinelConfig.getConfig(MOTAN_CONSUMER_RES_NAME_PREFIX_KEY);
return StringUtil.isNotBlank(config) ? config : DEFAULT_MOTAN_CONSUMER_PREFIX;
}
return null;
}

public static Boolean getMotanInterfaceGroupAndVersionEnabled() {
return TRUE_STR.equalsIgnoreCase(SentinelConfig.getConfig(MOTAN_INTERFACE_GROUP_VERSION_ENABLED));
}

public static MotanFallback getConsumerFallback() {
return consumerFallback;
}

public static void setConsumerFallback(MotanFallback consumerFallback) {
AssertUtil.notNull(consumerFallback, "consumerFallback cannot be null");
MotanAdapterGlobalConfig.consumerFallback = consumerFallback;
}

public static MotanFallback getProviderFallback() {
return providerFallback;
}

public static void setProviderFallback(MotanFallback providerFallback) {
AssertUtil.notNull(providerFallback, "providerFallback cannot be null");
MotanAdapterGlobalConfig.providerFallback = providerFallback;
}
}
Loading