/** * Transforms the given {@link Throwable} into a string and wraps it into an {@link IOException}. * * @param request the RPC request which caused the {@link Throwable} to be wrapped * @param throwable the {@link Throwable} to be wrapped * @return the {@link} IOException created from the {@link Throwable} */ private static IOException wrapInIOException( final RPCRequest request, final Throwable throwable) { final StringBuilder sb = new StringBuilder("The remote procedure call of method "); sb.append(request.getInterfaceName()); sb.append('.'); sb.append(request.getMethodName()); sb.append(" caused an unregistered exception: "); sb.append(StringUtils.stringifyException(throwable)); return new IOException(sb.toString()); }
private void processIncomingRPCRequest( final InetSocketAddress remoteSocketAddress, final RPCRequest rpcRequest) { final Integer messageID = Integer.valueOf(rpcRequest.getMessageID()); if (this.requestsBeingProcessed.putIfAbsent(messageID, rpcRequest) != null) { Log.debug( "Request " + rpcRequest.getMessageID() + " is already being processed at the moment"); return; } final CachedResponse cachedResponse = this.cachedResponses.get(messageID); if (cachedResponse != null) { try { final int numberOfRetries = this.networkThread.send(cachedResponse.packets); this.statistics.reportSuccessfulTransmission( rpcRequest.getMethodName() + " (Response)", cachedResponse.packets.length, numberOfRetries); } catch (final Exception e) { Log.error("Caught exception while trying to send RPC response: ", e); } finally { this.requestsBeingProcessed.remove(messageID); } return; } final RPCProtocol callbackHandler = this.callbackHandlers.get(rpcRequest.getInterfaceName()); if (callbackHandler == null) { Log.error("Cannot find callback handler for protocol " + rpcRequest.getInterfaceName()); this.requestsBeingProcessed.remove(messageID); return; } try { final Method method = callbackHandler .getClass() .getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes()); RPCResponse rpcResponse = null; try { final Object retVal = method.invoke(callbackHandler, rpcRequest.getArgs()); rpcResponse = new RPCReturnValue(rpcRequest.getMessageID(), retVal); } catch (final InvocationTargetException ite) { Throwable targetException = ite.getTargetException(); // Make sure the stack trace is correctly filled targetException.getStackTrace(); if (!this.isThrowableRegistered(targetException.getClass())) targetException = wrapInIOException(rpcRequest, targetException); rpcResponse = new RPCThrowable(rpcRequest.getMessageID(), targetException); } final DatagramPacket[] packets = this.messageToPackets(remoteSocketAddress, rpcResponse); this.cachedResponses.put(messageID, new CachedResponse(System.currentTimeMillis(), packets)); final int numberOfRetries = this.networkThread.send(packets); this.statistics.reportSuccessfulTransmission( rpcRequest.getMethodName() + " (Response)", packets.length, numberOfRetries); } catch (final Exception e) { Log.error("Caught processing RPC request: ", e); } finally { this.requestsBeingProcessed.remove(messageID); } }