use of com.alibaba.dubbo.rpc.RpcInvocation 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.RpcInvocation in project dubbo by alibaba.
the class RegistryDirectoryTest method testDestroy.
/**
* When destroying, RegistryDirectory should: 1. be disconnected from Registry 2. destroy all invokers
*/
@Test
public void testDestroy() {
RegistryDirectory registryDirectory = getRegistryDirectory();
List<URL> serviceUrls = new ArrayList<URL>();
serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX1"));
serviceUrls.add(SERVICEURL2.addParameter("methods", "getXXX1,getXXX2"));
serviceUrls.add(SERVICEURL3.addParameter("methods", "getXXX1,getXXX2,getXXX3"));
registryDirectory.notify(serviceUrls);
List<Invoker> invokers = registryDirectory.list(invocation);
Assert.assertEquals(true, registryDirectory.isAvailable());
Assert.assertEquals(true, invokers.get(0).isAvailable());
registryDirectory.destroy();
Assert.assertEquals(false, registryDirectory.isAvailable());
Assert.assertEquals(false, invokers.get(0).isAvailable());
registryDirectory.destroy();
Map<String, List<Invoker<RegistryDirectoryTest>>> methodInvokerMap = registryDirectory.getMethodInvokerMap();
Map<String, Invoker<RegistryDirectoryTest>> urlInvokerMap = registryDirectory.getUrlInvokerMap();
Assert.assertTrue(methodInvokerMap == null);
Assert.assertEquals(0, urlInvokerMap.size());
// List<U> urls = mockRegistry.getSubscribedUrls();
RpcInvocation inv = new RpcInvocation();
try {
registryDirectory.list(inv);
fail();
} catch (RpcException e) {
Assert.assertTrue(e.getMessage().contains("already destroyed"));
}
}
use of com.alibaba.dubbo.rpc.RpcInvocation in project dubbo by alibaba.
the class RegistryDirectoryTest method test_Notified3invokers.
// 3 invoker notifications===================================
private void test_Notified3invokers(RegistryDirectory registryDirectory) {
List<URL> serviceUrls = new ArrayList<URL>();
serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX1"));
serviceUrls.add(SERVICEURL2.addParameter("methods", "getXXX1,getXXX2"));
serviceUrls.add(SERVICEURL3.addParameter("methods", "getXXX1,getXXX2,getXXX3"));
registryDirectory.notify(serviceUrls);
Assert.assertEquals(true, registryDirectory.isAvailable());
invocation = new RpcInvocation();
List invokers = registryDirectory.list(invocation);
Assert.assertEquals(3, invokers.size());
invocation.setMethodName("getXXX");
invokers = registryDirectory.list(invocation);
Assert.assertEquals(3, invokers.size());
invocation.setMethodName("getXXX1");
invokers = registryDirectory.list(invocation);
Assert.assertEquals(3, invokers.size());
invocation.setMethodName("getXXX2");
invokers = registryDirectory.list(invocation);
Assert.assertEquals(2, invokers.size());
invocation.setMethodName("getXXX3");
invokers = registryDirectory.list(invocation);
Assert.assertEquals(1, invokers.size());
}
use of com.alibaba.dubbo.rpc.RpcInvocation in project dubbo by alibaba.
the class RegistryDirectoryTest method testNotifyoverrideUrls_afterInvoker.
/**
* Test whether the override rule have a high priority
* Scene: first push override , then push invoker
*/
@Test
public void testNotifyoverrideUrls_afterInvoker() {
RegistryDirectory registryDirectory = getRegistryDirectory();
// After pushing two provider, the directory state is restored to true
List<URL> serviceUrls = new ArrayList<URL>();
serviceUrls.add(SERVICEURL.addParameter("timeout", "1000"));
serviceUrls.add(SERVICEURL2.addParameter("timeout", "1000").addParameter("connections", "10"));
registryDirectory.notify(serviceUrls);
Assert.assertEquals(true, registryDirectory.isAvailable());
List<URL> overrideUrls = new ArrayList<URL>();
overrideUrls.add(URL.valueOf("override://0.0.0.0?timeout=1&connections=5"));
registryDirectory.notify(overrideUrls);
// Start validation of parameter values
invocation = new RpcInvocation();
List<Invoker<?>> invokers = registryDirectory.list(invocation);
Assert.assertEquals(2, invokers.size());
Assert.assertEquals("override rute must be first priority", "1", invokers.get(0).getUrl().getParameter("timeout"));
Assert.assertEquals("override rute must be first priority", "5", invokers.get(0).getUrl().getParameter("connections"));
}
use of com.alibaba.dubbo.rpc.RpcInvocation in project dubbo by alibaba.
the class RegistryDirectoryTest method testEmptyNotifyCauseForbidden.
/**
* Empty notify cause forbidden, non-empty notify cancels forbidden state
*/
@Test
public void testEmptyNotifyCauseForbidden() {
RegistryDirectory registryDirectory = getRegistryDirectory();
List invokers = null;
List<URL> serviceUrls = new ArrayList<URL>();
registryDirectory.notify(serviceUrls);
RpcInvocation inv = new RpcInvocation();
try {
invokers = registryDirectory.list(inv);
} catch (RpcException e) {
Assert.assertEquals(RpcException.FORBIDDEN_EXCEPTION, e.getCode());
Assert.assertEquals(false, registryDirectory.isAvailable());
}
serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX1"));
serviceUrls.add(SERVICEURL2.addParameter("methods", "getXXX1,getXXX2"));
serviceUrls.add(SERVICEURL3.addParameter("methods", "getXXX1,getXXX2,getXXX3"));
registryDirectory.notify(serviceUrls);
inv.setMethodName("getXXX2");
invokers = registryDirectory.list(inv);
Assert.assertEquals(true, registryDirectory.isAvailable());
Assert.assertEquals(2, invokers.size());
}
Aggregations