RefererInvocationHandler extends AbstractRefererHandler<T> implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (isLocalMethod(method)) { if ("toString".equals(method.getName())) { return clustersToString(); } if ("equals".equals(method.getName())) { return proxyEquals(args[0]); } if ("hashCode".equals(method.getName())) { return this.clusters == null ? 0 : this.clusters.hashCode(); } throw new MotanServiceException("can not invoke local method:" + method.getName()); } DefaultRequest request = new DefaultRequest(); request.setRequestId(RequestIdGenerator.getRequestId()); request.setArguments(args); String methodName = method.getName(); boolean async = false; if (methodName.endsWith(MotanConstants.ASYNC_SUFFIX) && method.getReturnType().equals(ResponseFuture.class)) { methodName = MotanFrameworkUtil.removeAsyncSuffix(methodName); async = true; } request.setMethodName(methodName); request.setParamtersDesc(ReflectUtil.getMethodParamDesc(method)); request.setInterfaceName(interfaceName); return invokeRequest(request, getRealReturnType(async, this.clz, method, methodName), async); } RefererInvocationHandler(Class<T> clz, List<Cluster<T>> clusters); @Override Object invoke(Object proxy, Method method, Object[] args); boolean isLocalMethod(Method method);  }
@SuppressWarnings({"rawtypes", "unchecked"}) @Test public void testInvokeException() throws Throwable { final Cluster cluster = mockery.mock(Cluster.class); final URL u = new URL("motan", "local", 80, "test"); u.addParameter(URLParamType.nodeType.getName(), MotanConstants.NODE_TYPE_REFERER); mockery.checking(new Expectations() { { one(cluster).call(with(any(Request.class))); will(throwException(new MotanBizException("just test", new StackOverflowError()))); allowing(cluster).getUrl(); will(returnValue(u)); } }); List<Cluster> clus = new ArrayList<Cluster>(); clus.add(cluster); RefererInvocationHandler handler = new RefererInvocationHandler(String.class, clus); Method[] methods = String.class.getMethods(); try { handler.invoke(null, methods[1], null); } catch (Exception e) { assertTrue(e instanceof MotanServiceException); assertTrue(e.getMessage().contains("StackOverflowError")); } }
@Test @SuppressWarnings({"rawtypes", "unchecked"}) public void testAsync() { final Cluster cluster = mockery.mock(Cluster.class); final URL u = new URL("motan", "local", 80, "test"); u.addParameter(URLParamType.nodeType.getName(), MotanConstants.NODE_TYPE_REFERER); final ResponseFuture response = mockery.mock(ResponseFuture.class); mockery.checking(new Expectations() { { one(cluster).call(with(any(Request.class))); will(returnValue(response)); allowing(cluster).getUrl(); will(returnValue(u)); allowing(response).setReturnType(with(any(Class.class))); allowing(response).setAttachment(with(any(String.class)), with(any(String.class))); } }); List<Cluster> clus = new ArrayList<Cluster>(); clus.add(cluster); RefererInvocationHandler handler = new RefererInvocationHandler(String.class, clus); Method method; try { method = TestService.class.getMethod("helloAsync", new Class<?>[] {}); ResponseFuture res = (ResponseFuture) handler.invoke(null, method, null); assertEquals(response, res); assertTrue((Boolean) RpcContext.getContext().getAttribute(MotanConstants.ASYNC_SUFFIX)); } catch (Throwable e) { e.printStackTrace(); assertTrue(false); } }