1.interceptor的beforeMethod引入新的参数,允许在方法内部,拦截并设置方法新的返回值。如设置,则原方法体将不再执行。

2.代码级别修复dubbo插件的拦截器机制。
3.所有插件的重构代码功能,待测试。@ascrutae
This commit is contained in:
wusheng 2016-06-19 15:04:37 +08:00
parent a49e19c7b3
commit c23b988193
14 changed files with 124 additions and 68 deletions

View File

@ -41,12 +41,17 @@ public class ClassInstanceMethodsInterceptor {
throws Exception {
InstanceMethodInvokeContext interceptorContext = new InstanceMethodInvokeContext(obj,
method.getName(), allArguments);
MethodInterceptResult result = new MethodInterceptResult();
try {
interceptor.beforeMethod(instanceContext, interceptorContext);
interceptor.beforeMethod(instanceContext, interceptorContext, result);
} catch (Throwable t) {
logger.error("class[{}] before method[{}] intercept failue:{}",
obj.getClass(), method.getName(), t.getMessage(), t);
}
if(!result.isContinue()){
return result._ret();
}
Object ret = null;
try {
ret = zuper.call();

View File

@ -34,12 +34,17 @@ public class ClassStaticMethodsInterceptor {
@SuperCall Callable<?> zuper) throws Exception {
MethodInvokeContext interceptorContext = new MethodInvokeContext(
method.getName(), allArguments);
MethodInterceptResult result = new MethodInterceptResult();
try {
interceptor.beforeMethod(interceptorContext);
interceptor.beforeMethod(interceptorContext, result);
} catch (Throwable t) {
logger.error("class[{}] before static method[{}] intercept failue:{}",
clazz, method.getName(), t.getMessage(), t);
}
if(!result.isContinue()){
return result._ret();
}
Object ret = null;
try {
ret = zuper.call();

View File

@ -5,7 +5,7 @@ import com.ai.cloud.skywalking.plugin.interceptor.EnhancedClassInstanceContext;
public interface IntanceMethodsAroundInterceptor {
public void onConstruct(EnhancedClassInstanceContext context, ConstructorInvokeContext interceptorContext);
public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext);
public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, MethodInterceptResult result);
public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, Object ret);

View File

@ -0,0 +1,20 @@
package com.ai.cloud.skywalking.plugin.interceptor.enhance;
public class MethodInterceptResult {
private boolean isContinue = true;
private Object _ret = null;
public void defineReturnValue(Object ret){
this.isContinue = false;
this._ret = ret;
}
public boolean isContinue() {
return isContinue;
}
Object _ret(){
return _ret;
}
}

View File

@ -2,7 +2,7 @@ package com.ai.cloud.skywalking.plugin.interceptor.enhance;
public interface StaticMethodsAroundInterceptor {
public void beforeMethod(MethodInvokeContext interceptorContext);
public void beforeMethod(MethodInvokeContext interceptorContext, MethodInterceptResult result);
public Object afterMethod(MethodInvokeContext interceptorContext, Object ret);

View File

@ -4,6 +4,7 @@ import com.ai.cloud.skywalking.plugin.interceptor.EnhancedClassInstanceContext;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.ConstructorInvokeContext;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.InstanceMethodInvokeContext;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.IntanceMethodsAroundInterceptor;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.MethodInterceptResult;
/**
* Created by xin on 16-6-8.
@ -15,7 +16,7 @@ public class TestAroundInterceptor implements IntanceMethodsAroundInterceptor {
}
@Override
public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext) {
public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, MethodInterceptResult result) {
System.out.println("before method");
}

View File

@ -4,6 +4,7 @@ import com.ai.cloud.skywalking.plugin.interceptor.EnhancedClassInstanceContext;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.ConstructorInvokeContext;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.InstanceMethodInvokeContext;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.IntanceMethodsAroundInterceptor;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.MethodInterceptResult;
public class TestAroundInterceptor implements IntanceMethodsAroundInterceptor {
@ -14,7 +15,7 @@ public class TestAroundInterceptor implements IntanceMethodsAroundInterceptor {
}
@Override
public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext) {
public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, MethodInterceptResult result) {
System.out.println("beforeMethod : " + context.get("test.key", String.class));
}

View File

@ -1,12 +1,13 @@
package test.ai.cloud.plugin;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.MethodInterceptResult;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.MethodInvokeContext;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.StaticMethodsAroundInterceptor;
public class TestStaticAroundInterceptor implements StaticMethodsAroundInterceptor {
@Override
public void beforeMethod(MethodInvokeContext interceptorContext) {
public void beforeMethod(MethodInvokeContext interceptorContext, MethodInterceptResult result) {
System.out.println("beforeMethod : static");
}

View File

@ -1,56 +0,0 @@
package com.ai.cloud.skywalking.plugin;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
import com.alibaba.dubbo.rpc.*;
import net.bytebuddy.implementation.bind.annotation.Argument;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import java.util.List;
public class DubboFilterBuildInterceptor {
@RuntimeType
public <T> Object intercept(
@Argument(0) final Invoker invoker,
@Argument(1) final String key,
@Argument(2) final String group)
throws Exception {
final URL newURL = invoker.getUrl().addParameter(key, "skywalking$enhanceFilter");
Invoker<T> last = invoker;
List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(newURL, key, group);
if (filters.size() > 0) {
for (int i = filters.size() - 1; i >= 0; i--) {
final Filter filter = filters.get(i);
final Invoker<T> next = last;
last = new Invoker<T>() {
public Class<T> getInterface() {
return invoker.getInterface();
}
public URL getUrl() {
return newURL;
}
public boolean isAvailable() {
return invoker.isAvailable();
}
public Result invoke(Invocation invocation) throws RpcException {
return filter.invoke(next, invocation);
}
public void destroy() {
invoker.destroy();
}
@Override
public String toString() {
return invoker.toString();
}
};
}
}
return last;
}
}

View File

@ -1,4 +1,4 @@
package com.ai.cloud.skywalking.plugin;
package com.ai.cloud.skywalking.plugin.dubbo;
import com.ai.cloud.skywalking.plugin.interceptor.MethodMatcher;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.ClassStaticMethodsEnhancePluginDefine;
@ -13,7 +13,6 @@ public class DubboPluginDefine extends ClassStaticMethodsEnhancePluginDefine {
@Override
protected StaticMethodsAroundInterceptor getStaticMethodsInterceptor() {
// TODO Auto-generated method stub
return null;
}

View File

@ -0,0 +1,78 @@
package com.ai.cloud.skywalking.plugin.dubbo;
import java.util.List;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.MethodInterceptResult;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.MethodInvokeContext;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.StaticMethodsAroundInterceptor;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
import com.alibaba.dubbo.rpc.Filter;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcException;
public class ProtocolFilterBuildChainInterceptor implements StaticMethodsAroundInterceptor{
@SuppressWarnings("rawtypes")
@Override
public void beforeMethod(MethodInvokeContext interceptorContext,
MethodInterceptResult result) {
Object[] args = interceptorContext.allArguments();
final Invoker<?> invoker = (Invoker<?>)args[0];
String key = (String)args[1];
String group = (String)args[2];
final URL newURL = invoker.getUrl().addParameter(key, "skywalking$enhanceFilter");
Invoker<?> last = invoker;
List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(newURL, key, group);
if (filters.size() > 0) {
for (int i = filters.size() - 1; i >= 0; i--) {
final Filter filter = filters.get(i);
final Invoker<?> next = last;
last = new Invoker() {
public Class<?> getInterface() {
return invoker.getInterface();
}
public URL getUrl() {
return newURL;
}
public boolean isAvailable() {
return invoker.isAvailable();
}
public Result invoke(Invocation invocation) throws RpcException {
return filter.invoke(next, invocation);
}
public void destroy() {
invoker.destroy();
}
@Override
public String toString() {
return invoker.toString();
}
};
}
}
result.defineReturnValue(last);
}
@Override
public Object afterMethod(MethodInvokeContext interceptorContext, Object ret) {
return null;
//unreachable
}
@Override
public void handleMethodException(Throwable t,
MethodInvokeContext interceptorContext, Object ret) {
//unreachable
}
}

View File

@ -1 +1 @@
com.ai.cloud.skywalking.plugin.DubboPluginDefine
com.ai.cloud.skywalking.plugin.dubbo.DubboPluginDefine

View File

@ -9,6 +9,7 @@ import com.ai.cloud.skywalking.plugin.interceptor.EnhancedClassInstanceContext;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.ConstructorInvokeContext;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.InstanceMethodInvokeContext;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.IntanceMethodsAroundInterceptor;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.MethodInterceptResult;
public class HttpClientExecuteInterceptor implements IntanceMethodsAroundInterceptor {
/**
@ -25,7 +26,7 @@ public class HttpClientExecuteInterceptor implements IntanceMethodsAroundInterce
@Override
public void beforeMethod(EnhancedClassInstanceContext context,
InstanceMethodInvokeContext interceptorContext) {
InstanceMethodInvokeContext interceptorContext, MethodInterceptResult result) {
Object[] allArguments = interceptorContext.allArguments();
if (allArguments[0] == null || allArguments[1] == null) {
// illegal args, can't trace. ignore.

View File

@ -5,6 +5,7 @@ import com.ai.cloud.skywalking.model.Identification;
import com.ai.cloud.skywalking.plugin.interceptor.EnhancedClassInstanceContext;
import com.ai.cloud.skywalking.plugin.interceptor.assist.SimpleObjectFirstInvokeInterceptor;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.InstanceMethodInvokeContext;
import com.ai.cloud.skywalking.plugin.interceptor.enhance.MethodInterceptResult;
public abstract class JedisBaseInterceptor extends SimpleObjectFirstInvokeInterceptor {
protected static final String REDIS_CONN_INFO_KEY = "redisClusterConnInfo";
@ -12,7 +13,7 @@ public abstract class JedisBaseInterceptor extends SimpleObjectFirstInvokeInterc
private static RPCBuriedPointSender sender = new RPCBuriedPointSender();
@Override
public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext) {
public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, MethodInterceptResult result) {
if (this.isFirstBeforeMethod(context)) {
/**
* redis server wouldn't process rpc context. ignore the