use of com.alibaba.dubbo.rpc.RpcResult in project dubbo by alibaba.
the class ExceptionFilter method invoke.
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
try {
Result result = invoker.invoke(invocation);
if (result.hasException() && GenericService.class != invoker.getInterface()) {
try {
Throwable exception = result.getException();
// 如果是checked异常,直接抛出
if (!(exception instanceof RuntimeException) && (exception instanceof Exception)) {
return result;
}
// 在方法签名上有声明,直接抛出
try {
Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());
Class<?>[] exceptionClassses = method.getExceptionTypes();
for (Class<?> exceptionClass : exceptionClassses) {
if (exception.getClass().equals(exceptionClass)) {
return result;
}
}
} catch (NoSuchMethodException e) {
return result;
}
// 未在方法签名上定义的异常,在服务器端打印ERROR日志
logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + exception.getClass().getName() + ": " + exception.getMessage(), exception);
// 异常类和接口类在同一jar包里,直接抛出
String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface());
String exceptionFile = ReflectUtils.getCodeBase(exception.getClass());
if (serviceFile == null || exceptionFile == null || serviceFile.equals(exceptionFile)) {
return result;
}
// 是JDK自带的异常,直接抛出
String className = exception.getClass().getName();
if (className.startsWith("java.") || className.startsWith("javax.")) {
return result;
}
// 是Dubbo本身的异常,直接抛出
if (exception instanceof RpcException) {
return result;
}
// 否则,包装成RuntimeException抛给客户端
return new RpcResult(new RuntimeException(StringUtils.toString(exception)));
} catch (Throwable e) {
logger.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
return result;
}
}
return result;
} catch (RuntimeException e) {
logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
throw e;
}
}
use of com.alibaba.dubbo.rpc.RpcResult in project dubbo by alibaba.
the class GenericImplFilter method invoke.
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
String generic = invoker.getUrl().getParameter(Constants.GENERIC_KEY);
if (ProtocolUtils.isGeneric(generic) && !Constants.$INVOKE.equals(invocation.getMethodName()) && invocation instanceof RpcInvocation) {
RpcInvocation invocation2 = (RpcInvocation) invocation;
String methodName = invocation2.getMethodName();
Class<?>[] parameterTypes = invocation2.getParameterTypes();
Object[] arguments = invocation2.getArguments();
String[] types = new String[parameterTypes.length];
for (int i = 0; i < parameterTypes.length; i++) {
types[i] = ReflectUtils.getName(parameterTypes[i]);
}
Object[] args;
if (ProtocolUtils.isBeanGenericSerialization(generic)) {
args = new Object[arguments.length];
for (int i = 0; i < arguments.length; i++) {
args[i] = JavaBeanSerializeUtil.serialize(arguments[i], JavaBeanAccessor.METHOD);
}
} else {
args = PojoUtils.generalize(arguments);
}
invocation2.setMethodName(Constants.$INVOKE);
invocation2.setParameterTypes(GENERIC_PARAMETER_TYPES);
invocation2.setArguments(new Object[] { methodName, types, args });
Result result = invoker.invoke(invocation2);
if (!result.hasException()) {
Object value = result.getValue();
try {
Method method = invoker.getInterface().getMethod(methodName, parameterTypes);
if (ProtocolUtils.isBeanGenericSerialization(generic)) {
if (value == null) {
return new RpcResult(value);
} else if (value instanceof JavaBeanDescriptor) {
return new RpcResult(JavaBeanSerializeUtil.deserialize((JavaBeanDescriptor) value));
} else {
throw new RpcException(new StringBuilder(64).append("The type of result value is ").append(value.getClass().getName()).append(" other than ").append(JavaBeanDescriptor.class.getName()).append(", and the result is ").append(value).toString());
}
} else {
return new RpcResult(PojoUtils.realize(value, method.getReturnType(), method.getGenericReturnType()));
}
} catch (NoSuchMethodException e) {
throw new RpcException(e.getMessage(), e);
}
} else if (result.getException() instanceof GenericException) {
GenericException exception = (GenericException) result.getException();
try {
String className = exception.getExceptionClass();
Class<?> clazz = ReflectUtils.forName(className);
Throwable targetException = null;
Throwable lastException = null;
try {
targetException = (Throwable) clazz.newInstance();
} catch (Throwable e) {
lastException = e;
for (Constructor<?> constructor : clazz.getConstructors()) {
try {
targetException = (Throwable) constructor.newInstance(new Object[constructor.getParameterTypes().length]);
break;
} catch (Throwable e1) {
lastException = e1;
}
}
}
if (targetException != null) {
try {
Field field = Throwable.class.getDeclaredField("detailMessage");
if (!field.isAccessible()) {
field.setAccessible(true);
}
field.set(targetException, exception.getExceptionMessage());
} catch (Throwable e) {
logger.warn(e.getMessage(), e);
}
result = new RpcResult(targetException);
} else if (lastException != null) {
throw lastException;
}
} catch (Throwable e) {
throw new RpcException("Can not deserialize exception " + exception.getExceptionClass() + ", message: " + exception.getExceptionMessage(), e);
}
}
return result;
}
if (invocation.getMethodName().equals(Constants.$INVOKE) && invocation.getArguments() != null && invocation.getArguments().length == 3 && ProtocolUtils.isGeneric(generic)) {
Object[] args = (Object[]) invocation.getArguments()[2];
if (ProtocolUtils.isJavaGenericSerialization(generic)) {
for (Object arg : args) {
if (!(byte[].class == arg.getClass())) {
error(byte[].class.getName(), arg.getClass().getName());
}
}
} else if (ProtocolUtils.isBeanGenericSerialization(generic)) {
for (Object arg : args) {
if (!(arg instanceof JavaBeanDescriptor)) {
error(JavaBeanDescriptor.class.getName(), arg.getClass().getName());
}
}
}
((RpcInvocation) invocation).setAttachment(Constants.GENERIC_KEY, invoker.getUrl().getParameter(Constants.GENERIC_KEY));
}
return invoker.invoke(invocation);
}
use of com.alibaba.dubbo.rpc.RpcResult in project dubbo by alibaba.
the class CompatibleFilterFilterTest method testInvokerNonJsonPojoSerialization.
@Test
public void testInvokerNonJsonPojoSerialization() {
invocation = EasyMock.createMock(Invocation.class);
EasyMock.expect(invocation.getMethodName()).andReturn("echo").anyTimes();
EasyMock.expect(invocation.getParameterTypes()).andReturn(new Class<?>[] { String.class }).anyTimes();
EasyMock.expect(invocation.getArguments()).andReturn(new Object[] { "hello" }).anyTimes();
EasyMock.replay(invocation);
invoker = EasyMock.createMock(Invoker.class);
EasyMock.expect(invoker.isAvailable()).andReturn(true).anyTimes();
EasyMock.expect(invoker.getInterface()).andReturn(DemoService.class).anyTimes();
RpcResult result = new RpcResult();
result.setValue("hello");
EasyMock.expect(invoker.invoke(invocation)).andReturn(result).anyTimes();
URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
EasyMock.expect(invoker.getUrl()).andReturn(url).anyTimes();
EasyMock.replay(invoker);
Result filterResult = compatibleFilter.invoke(invoker, invocation);
assertEquals("hello", filterResult.getValue());
}
use of com.alibaba.dubbo.rpc.RpcResult in project dubbo by alibaba.
the class CompatibleFilterFilterTest method testInvokerNonJsonEnumSerialization.
@Test
public void testInvokerNonJsonEnumSerialization() {
invocation = EasyMock.createMock(Invocation.class);
EasyMock.expect(invocation.getMethodName()).andReturn("enumlength").anyTimes();
EasyMock.expect(invocation.getParameterTypes()).andReturn(new Class<?>[] { Type[].class }).anyTimes();
EasyMock.expect(invocation.getArguments()).andReturn(new Object[] { "hello" }).anyTimes();
EasyMock.replay(invocation);
invoker = EasyMock.createMock(Invoker.class);
EasyMock.expect(invoker.isAvailable()).andReturn(true).anyTimes();
EasyMock.expect(invoker.getInterface()).andReturn(DemoService.class).anyTimes();
RpcResult result = new RpcResult();
result.setValue("High");
EasyMock.expect(invoker.invoke(invocation)).andReturn(result).anyTimes();
URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
EasyMock.expect(invoker.getUrl()).andReturn(url).anyTimes();
EasyMock.replay(invoker);
Result filterResult = compatibleFilter.invoke(invoker, invocation);
assertEquals(Type.High, filterResult.getValue());
}
use of com.alibaba.dubbo.rpc.RpcResult in project dubbo by alibaba.
the class CompatibleFilterFilterTest method testInvokerGeneric.
@Test
public void testInvokerGeneric() {
invocation = EasyMock.createMock(Invocation.class);
EasyMock.expect(invocation.getMethodName()).andReturn("$enumlength").anyTimes();
EasyMock.expect(invocation.getParameterTypes()).andReturn(new Class<?>[] { Enum.class }).anyTimes();
EasyMock.expect(invocation.getArguments()).andReturn(new Object[] { "hello" }).anyTimes();
EasyMock.replay(invocation);
invoker = EasyMock.createMock(Invoker.class);
EasyMock.expect(invoker.isAvailable()).andReturn(true).anyTimes();
EasyMock.expect(invoker.getInterface()).andReturn(DemoService.class).anyTimes();
RpcResult result = new RpcResult();
result.setValue("High");
EasyMock.expect(invoker.invoke(invocation)).andReturn(result).anyTimes();
URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
EasyMock.expect(invoker.getUrl()).andReturn(url).anyTimes();
EasyMock.replay(invoker);
Result filterResult = compatibleFilter.invoke(invoker, invocation);
assertEquals(filterResult, result);
}
Aggregations