VoltronProxyInvocationHandler implements InvocationHandler { @Override public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { if (close.equals(method)) { handler.shutdown(); entityClientEndpoint.close(); return null; } else if (registerMessageListener.equals(method)) { final Class<?> eventType = (Class<?>) args[0]; final MessageListener<?> arg = (MessageListener<?>) args[1]; final CopyOnWriteArrayList<MessageListener<?>> messageListeners = listeners.get(eventType); if (messageListeners == null) { throw new IllegalArgumentException("Event type '" + eventType + "' isn't supported"); } messageListeners.add(arg); return null; } else if (setEndpointListener.equals(method)) { this.endpointListener = (EndpointListener) args[0]; return null; } final MethodDescriptor methodDescriptor = MethodDescriptor.of(method); final InvocationBuilder<ProxyEntityMessage, ProxyEntityResponse> builder = entityClientEndpoint.beginInvoke() .message(new ProxyEntityMessage(methodDescriptor, args, MessageType.MESSAGE)).withExecutor(handler); if (methodDescriptor.isAsync()) { switch (methodDescriptor.getAck()) { case NONE: break; case RECEIVED: builder.ackReceived(); break; default: throw new IllegalStateException(methodDescriptor.getAck().name()); } return new ProxiedInvokeFuture<>(builder.invoke()); } else { return getResponse(builder.invoke().get()); } } VoltronProxyInvocationHandler(final EntityClientEndpoint<ProxyEntityMessage, ProxyEntityResponse> entityClientEndpoint, Collection<Class<?>> events, final Codec codec); @Override Object invoke(final Object proxy, final Method method, final Object[] args);  }
@SuppressWarnings("unchecked") @Test public void testNullsClientIdAnnotatedParams() throws Throwable { final Set<Object> valuesSeen = new HashSet<Object>(); final SerializationCodec codec = new SerializationCodec() { @Override public byte[] encode(final Class<?> type, final Object value) { valuesSeen.add(value); return super.encode(type, value); } }; final EntityClientEndpoint<ProxyEntityMessage, ProxyEntityResponse> endpoint = mock(EntityClientEndpoint.class); final InvocationBuilder builder = mock(InvocationBuilder.class); when(endpoint.beginInvoke()).thenReturn(builder); when(builder.message(ArgumentMatchers.<EntityMessage>any())).thenReturn(builder); when(builder.withExecutor(ArgumentMatchers.<Executor>any())).thenReturn(builder); final InvokeFuture future = mock(InvokeFuture.class); when(builder.invoke()).thenReturn(future); when(future.get()).thenReturn(ProxyEntityResponse.messageResponse(Void.TYPE, null)); Map<MethodDescriptor, Byte> methodMappings = invert(createMethodMappings(TestInterface.class)); VoltronProxyInvocationHandler handler = new VoltronProxyInvocationHandler(endpoint, Collections.<Class<?>>emptyList(), codec); for (MethodDescriptor method : methodMappings.keySet()) { handler.invoke(null, method.getMethod(), new Object[] { "String", new Object() }); } for (Object objects : valuesSeen) { assertNull(((Object[]) objects)[1]); } }