RpcContext { @SuppressWarnings("unchecked") public <T> CompletableFuture<T> asyncCall(Callable<T> callable) { try { try { setAttachment(ASYNC_KEY, Boolean.TRUE.toString()); final T o = callable.call(); if (o != null) { if (o instanceof CompletableFuture) { return (CompletableFuture<T>) o; } return CompletableFuture.completedFuture(o); } else { } } catch (Exception e) { throw new RpcException(e); } finally { removeAttachment(ASYNC_KEY); } } catch (final RpcException e) { CompletableFuture<T> exceptionFuture = new CompletableFuture<>(); exceptionFuture.completeExceptionally(e); return exceptionFuture; } return ((CompletableFuture<T>) getContext().getFuture()); } protected  RpcContext(); static RpcContext getServerContext(); static void restoreServerContext(RpcContext oldServerContext); static void removeServerContext(); static RpcContext getContext(); boolean canRemove(); void clearAfterEachInvoke(boolean remove); static void restoreContext(RpcContext oldContext); static void removeContext(); static void removeContext(boolean checkCanRemove); Object getRequest(); void setRequest(Object request); @SuppressWarnings("unchecked") T getRequest(Class<T> clazz); Object getResponse(); void setResponse(Object response); @SuppressWarnings("unchecked") T getResponse(Class<T> clazz); boolean isProviderSide(); boolean isConsumerSide(); @SuppressWarnings("unchecked") CompletableFuture<T> getCompletableFuture(); @SuppressWarnings("unchecked") Future<T> getFuture(); void setFuture(CompletableFuture<?> future); List<URL> getUrls(); void setUrls(List<URL> urls); URL getUrl(); void setUrl(URL url); String getMethodName(); void setMethodName(String methodName); Class<?>[] getParameterTypes(); void setParameterTypes(Class<?>[] parameterTypes); Object[] getArguments(); void setArguments(Object[] arguments); RpcContext setLocalAddress(String host, int port); InetSocketAddress getLocalAddress(); RpcContext setLocalAddress(InetSocketAddress address); String getLocalAddressString(); String getLocalHostName(); RpcContext setRemoteAddress(String host, int port); InetSocketAddress getRemoteAddress(); RpcContext setRemoteAddress(InetSocketAddress address); String getRemoteApplicationName(); RpcContext setRemoteApplicationName(String remoteApplicationName); String getRemoteAddressString(); String getRemoteHostName(); String getLocalHost(); int getLocalPort(); String getRemoteHost(); int getRemotePort(); String getAttachment(String key); @Experimental("Experiment api for supporting Object transmission") Object getObjectAttachment(String key); RpcContext setAttachment(String key, String value); RpcContext setAttachment(String key, Object value); @Experimental("Experiment api for supporting Object transmission") RpcContext setObjectAttachment(String key, Object value); RpcContext removeAttachment(String key); @Deprecated Map<String, String> getAttachments(); @Experimental("Experiment api for supporting Object transmission") Map<String, Object> getObjectAttachments(); RpcContext setAttachments(Map<String, String> attachment); @Experimental("Experiment api for supporting Object transmission") RpcContext setObjectAttachments(Map<String, Object> attachment); void clearAttachments(); Map<String, Object> get(); RpcContext set(String key, Object value); RpcContext remove(String key); Object get(String key); @Deprecated boolean isServerSide(); @Deprecated boolean isClientSide(); @Deprecated @SuppressWarnings({"unchecked", "rawtypes"}) List<Invoker<?>> getInvokers(); RpcContext setInvokers(List<Invoker<?>> invokers); @Deprecated Invoker<?> getInvoker(); RpcContext setInvoker(Invoker<?> invoker); @Deprecated Invocation getInvocation(); RpcContext setInvocation(Invocation invocation); @SuppressWarnings("unchecked") CompletableFuture<T> asyncCall(Callable<T> callable); void asyncCall(Runnable runnable); @SuppressWarnings("unchecked") static AsyncContext startAsync(); boolean isAsyncStarted(); boolean stopAsync(); AsyncContext getAsyncContext(); String getGroup(); String getVersion(); String getInterfaceName(); String getProtocol(); String getServiceKey(); String getProtocolServiceKey(); URL getConsumerUrl(); void setConsumerUrl(URL consumerUrl); static void setRpcContext(URL url);  }
@Test public void testAsyncCall() { CompletableFuture<String> rpcFuture = RpcContext.getContext().asyncCall(() -> { throw new NullPointerException(); }); rpcFuture.whenComplete((rpcResult, throwable) -> { System.out.println(throwable.toString()); Assertions.assertNull(rpcResult); Assertions.assertTrue(throwable instanceof RpcException); Assertions.assertTrue(throwable.getCause() instanceof NullPointerException); }); Assertions.assertThrows(ExecutionException.class, rpcFuture::get); rpcFuture = rpcFuture.exceptionally(throwable -> "mock success"); Assertions.assertEquals("mock success", rpcFuture.join()); }