@Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { Object thriftProxy = ThriftUtil.buildClient(getServiceInterface(), protocolFactory.getProtocol(getTransport())); ClassLoader originalClassLoader = overrideThreadContextClassLoader(); try { return methodInvocation.getMethod().invoke(thriftProxy, methodInvocation.getArguments()); } catch (InvocationTargetException e) { Throwable targetEx = e.getTargetException(); if (targetEx instanceof InvocationTargetException) { targetEx = ((InvocationTargetException) targetEx).getTargetException(); } if (targetEx instanceof TApplicationException && ((TApplicationException) targetEx).getType() == TApplicationException.MISSING_RESULT) { return null; } else { throw targetEx; } } catch (Throwable ex) { throw new RemoteProxyFailureException("Failed to invoke Thrift proxy for remote service [" + getServiceUrl() + "]", ex); } finally { resetThreadContextClassLoader(originalClassLoader); } }
@Override public boolean process(TProtocol in, TProtocol out) throws TException { TMessage msg = in.readMessageBegin(); Controller<?, ?> fn = (Controller<?, ?>) this.beanFactory .getBean(msg.name); if (fn == null) { if (LOGGER.isWarnEnabled()) { LOGGER.warn("Invalid request: failed to find interface=" + msg.name + ", from: " + getInetAddress(in)); } TProtocolUtil.skip(in, TType.STRUCT); in.readMessageEnd(); TApplicationException x = new TApplicationException( TApplicationException.UNKNOWN_METHOD, "Invalid method name: '" + msg.name + "'"); out.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid)); x.write(out); out.writeMessageEnd(); out.getTransport().flush(); return true; } process(msg.seqid, msg.name, in, out, fn); return true; }
@Override public final boolean process(final TProtocol in, final TProtocol out) throws TException { final TMessage msg = in.readMessageBegin(); final ProcessFunction<LocatorServiceImpl, ?> fn = this.fnMap .get(msg.name); if (fn != null) { fn.process(msg.seqid, in, out, this.inst); // terminate connection on receiving closeConnection // direct class comparison should be the fastest way return fn.getClass() != LocatorService.Processor.closeConnection.class; } else { TProtocolUtil.skip(in, TType.STRUCT); in.readMessageEnd(); TApplicationException x = new TApplicationException( TApplicationException.UNKNOWN_METHOD, "Invalid method name: '" + msg.name + "'"); out.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid)); x.write(out); out.writeMessageEnd(); out.getTransport().flush(); return true; } }
/** * 读取操作 */ @Override public void read(TProtocol iprot) throws TException { if (!"org.apache.thrift.scheme.StandardScheme".equals(iprot.getScheme().getName())) throw new TApplicationException("Service scheme must be 'org.apache.thrift.scheme.StandardScheme' !"); TField schemeField; iprot.readStructBegin(); while (Boolean.TRUE) { schemeField = iprot.readFieldBegin(); if (schemeField.type == TType.STOP) break; if (schemeField.type == TType.STRING) str = iprot.readString(); else throw new TApplicationException("field type must be 'String' !"); iprot.readFieldEnd(); } iprot.readStructEnd(); }
void handleTApplicationException(Throwable cause, Optional<StreamOp> op, SocketAddress addr, ProxyClient sc) { TApplicationException ex = (TApplicationException) cause; if (ex.getType() == TApplicationException.UNKNOWN_METHOD) { // if we encountered unknown method exception on thrift server, it means this proxy // has problem. we should remove it from routing service, clean up ownerships routingService.removeHost(addr, cause); onServerLeft(addr, sc); if (op.isPresent()) { ownershipCache.removeOwnerFromStream(op.get().stream, addr, cause.getMessage()); doSend(op.get(), addr); } } else { handleException(cause, op, addr); } }
@Override public void releaseResource(String handle, List<Integer> idList) throws TException, InvalidSessionHandle, SafeModeException { checkSafeMode("releaseResource"); try { LOG.info("Release " + idList.size() + " resources from session: " + handle); sessionManager.heartbeat(handle); Collection<ResourceGrant> canceledGrants = sessionManager.releaseResource(handle, idList); if (canceledGrants == null) { // LOG.info("No canceled grants for session " + handle); return; } for (ResourceGrant grant: canceledGrants) { nodeManager.cancelGrant(grant.nodeName, handle, grant.id); metrics.releaseResource(grant.type); } scheduler.notifyScheduler(); } catch (RuntimeException e) { throw new TApplicationException(e.getMessage()); } }
private MessageTransalator createTranslator(TProtocolFactory protocolFactory) { return new MessageTransalator(protocolFactory, new AuthTokenExchanger<AuthToken, UserData>() { @Override public AuthToken createEmptyAuthToken() { return new AuthToken(); } @Override public UserData process(AuthToken authToken) throws TException { if ("sometoken".equals(authToken.getToken())) { return new UserData().setId("user1"); } if ("fataltoken".equals(authToken.getToken())) { throw new TApplicationException(TApplicationException.INTERNAL_ERROR, "fatal!!!"); } throw new UnauthorizedException("token is invalid"); } }); }
private static TApplicationException readApplicationException(int seqId, ThriftFunction func, TProtocol inputProtocol, TMessage msg) throws TException { if (msg.seqid != seqId) { throw new TApplicationException(TApplicationException.BAD_SEQUENCE_ID); } if (!func.name().equals(msg.name)) { return new TApplicationException(TApplicationException.WRONG_METHOD_NAME, msg.name); } if (msg.type == TMessageType.EXCEPTION) { final TApplicationException appEx = TApplicationExceptions.read(inputProtocol); inputProtocol.readMessageEnd(); return appEx; } return null; }
/** * Returns newly created {@link ObjectMapper} which is configured properly to serialize some knows classes * in a good way. */ public static ObjectMapper newObjectMapper(SimpleModule... userModules) { ObjectMapper objectMapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addSerializer(TMessage.class, new TMessageSerializer()); module.addSerializer(TBase.class, new TBaseSerializer()); module.addSerializer(TApplicationException.class, new TApplicationExceptionSerializer()); module.addSerializer(ThriftCall.class, new ThriftCallSerializer()); module.addSerializer(ThriftReply.class, new ThriftReplySerializer()); objectMapper.registerModule(module); for (SimpleModule userModule : userModules) { objectMapper.registerModule(userModule); } return objectMapper; }
/** * Converts the specified {@code result} into a Java object. */ public Object getResult(TBase<?, ?> result) throws TException { for (TFieldIdEnum fieldIdEnum : exceptionFields()) { if (ThriftFieldAccess.isSet(result, fieldIdEnum)) { throw (TException) ThriftFieldAccess.get(result, fieldIdEnum); } } final TFieldIdEnum successField = successField(); if (successField == null) { //void method return null; } else if (ThriftFieldAccess.isSet(result, successField)) { return ThriftFieldAccess.get(result, successField); } else { throw new TApplicationException( TApplicationException.MISSING_RESULT, result.getClass().getName() + '.' + successField.getFieldName()); } }
@Test public void testSync_FileService_create_exception() throws Exception { FileService.Client client = new FileService.Client.Factory().getClient(inProto, outProto); client.send_create(BAZ); assertThat(out.length(), is(greaterThan(0))); RuntimeException exception = Exceptions.clearTrace(new RuntimeException()); THttpService service = THttpService.of((FileService.Iface) path -> { throw exception; }, defaultSerializationFormat); invoke(service); try { client.recv_create(); fail(TApplicationException.class.getSimpleName() + " not raised."); } catch (TApplicationException e) { assertThat(e.getType(), is(TApplicationException.INTERNAL_ERROR)); assertThat(e.getMessage(), containsString(exception.toString())); } }
@Test public void testAsync_FileService_create_exception() throws Exception { FileService.Client client = new FileService.Client.Factory().getClient(inProto, outProto); client.send_create(BAZ); assertThat(out.length(), is(greaterThan(0))); RuntimeException exception = Exceptions.clearTrace(new RuntimeException()); THttpService service = THttpService.of( (FileService.AsyncIface) (path, resultHandler) -> resultHandler.onError(exception), defaultSerializationFormat); invoke(service); try { client.recv_create(); fail(TApplicationException.class.getSimpleName() + " not raised."); } catch (TApplicationException e) { assertThat(e.getType(), is(TApplicationException.INTERNAL_ERROR)); assertThat(e.getMessage(), containsString(exception.toString())); } }
public List<ParseTree> parse_text(String text, List<String> outputFormat) throws TApplicationException { List<ParseTree> results = new ArrayList<ParseTree>(); try { treePrinter = ParserUtil.setOptions(outputFormat, tlp); // assume no tokenization was done; use Stanford's default org.ets.research.nlp.stanford_thrift.tokenizer DocumentPreprocessor preprocess = new DocumentPreprocessor(new StringReader(text)); Iterator<List<HasWord>> foundSentences = preprocess.iterator(); while (foundSentences.hasNext()) { Tree parseTree = parser.apply(foundSentences.next()); results.add(new ParseTree(ParserUtil.TreeObjectToString(parseTree, treePrinter), parseTree.score())); } } catch (Exception e) { // FIXME throw new TApplicationException(TApplicationException.INTERNAL_ERROR, e.getMessage()); } return results; }
/** * @param tokens One sentence worth of tokens at a time. * @return A ParseTree object of the String representation of the tree, plus its probability. * @throws TApplicationException */ public ParseTree parse_tokens(List<String> tokens, List<String> outputFormat) throws TApplicationException { try { treePrinter = ParserUtil.setOptions(outputFormat, tlp); // a single sentence worth of tokens String[] tokenArray = new String[tokens.size()]; tokens.toArray(tokenArray); List<CoreLabel> crazyStanfordFormat = Sentence.toCoreLabelList(tokenArray); Tree parseTree = parser.apply(crazyStanfordFormat); return new ParseTree(ParserUtil.TreeObjectToString(parseTree, treePrinter), parseTree.score()); } catch (Exception e) { // FIXME throw new TApplicationException(TApplicationException.INTERNAL_ERROR, e.getMessage()); } }
public ParseTree parse_tagged_sentence(String taggedSentence, List<String> outputFormat, String divider) throws TApplicationException { try { treePrinter = ParserUtil.setOptions(outputFormat, tlp); // a single sentence worth of tagged text, better be properly tokenized >:D Tree parseTree = parser.apply(CoreNLPThriftUtil.getListOfTaggedWordsFromTaggedSentence(taggedSentence, divider)); return new ParseTree(ParserUtil.TreeObjectToString(parseTree, treePrinter), parseTree.score()); } catch (Exception e) { // FIXME throw new TApplicationException(TApplicationException.INTERNAL_ERROR, e.getMessage()); } }
/** If one were to call any of these other methods to get a parse tree for some input sentence * with the -outputFormatOptions flag of "lexicalize", they would receive their parse tree, * in the -outputFormat of their choice, with every leaf marked with it's head word. * This function does exactly that on an existing parse tree. * NOTE that this WILL re-lexicalize a pre-lexicalized tree, so don't pass in a tree that * has been lexicalized and expect to get back the same thing as what you passed in. */ public String lexicalize_parse_tree(String tree) throws TApplicationException { try { Tree parseTree = Tree.valueOf(tree); Tree lexicalizedTree = Trees.lexicalize(parseTree, tlp.headFinder()); treePrinter = ParserUtil.setOptions(null, tlp); // use defaults Function<Tree, Tree> a = TreeFunctions.getLabeledToDescriptiveCoreLabelTreeFunction(); lexicalizedTree = a.apply(lexicalizedTree); return ParserUtil.TreeObjectToString(lexicalizedTree, treePrinter); } catch (Exception e) { // FIXME throw new TApplicationException(TApplicationException.INTERNAL_ERROR, e.getMessage()); } }
public List<ParseTree> sr_parse_text(String untokenizedText, List<String> outputFormat) throws TApplicationException { try { List<ParseTree> results = new ArrayList<ParseTree>(); List<List<TaggedToken>> posTaggedText = tagger.tag_text(untokenizedText); for (List<TaggedToken> taggedSentence : posTaggedText) { List<TaggedWord> taggedWords = CoreNLPThriftUtil.convertTaggedTokensToTaggedWords(taggedSentence); results.add(srparser.parseTaggedWords(taggedWords, outputFormat)); } return results; } catch (Exception e) { // FIXME throw new TApplicationException(TApplicationException.INTERNAL_ERROR, e.getMessage()); } }
@Override public ResultCode Log(List<LogEntry> messages) throws TException { for (LogEntry message : messages) { if (message.getCategory().equals("exception")) { throw new TApplicationException(UNSUPPORTED_CLIENT_TYPE, message.getMessage()); } } this.messages.addAll(messages); return ResultCode.OK; }
private void sumbitTask(TProtocol out, final TMessage msg, final WriterHandler onComplete, Runnable task){ try { serverDef.executor.submit(task); } catch (RejectedExecutionException e) { TApplicationException x = new TApplicationException(TApplicationException.INTERNAL_ERROR, "TooBusy"); writeException(out, msg, onComplete, x, null); logger.error("RejectedExecutionException: "+e.getLocalizedMessage()); } }
@SuppressWarnings({ "rawtypes" }) private void writeException(final TProtocol out, final TMessage msg, final WriterHandler onComplete, final TApplicationException x, TBase args) { Throwable cause = null; try { onComplete.beforeWrite(msg, args, null); out.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid)); x.write(out); out.writeMessageEnd(); out.getTransport().flush(); } catch (Throwable e) { cause = e; } onComplete.afterWrite(msg, cause, TMessageType.EXCEPTION, args, null); }
@Override public final boolean process(final TProtocol in, final TProtocol out) throws TException { final TMessage msg = in.readMessageBegin(); final ProcessFunction<GFXDServiceImpl, ?> fn = this.fnMap.get(msg.name); if (fn != null) { fn.process(msg.seqid, in, out, this.inst); // terminate connection on receiving closeConnection // direct class comparison should be the fastest way // TODO: SW: also need to clean up connection artifacts in the case of // client connection failure (ConnectionListener does get a notification // but how to tie the socket/connectionNumber to the connectionID?) return fn.getClass() != GFXDService.Processor.closeConnection.class; } else { TProtocolUtil.skip(in, TType.STRUCT); in.readMessageEnd(); TApplicationException x = new TApplicationException( TApplicationException.UNKNOWN_METHOD, "Invalid method name: '" + msg.name + "'"); out.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid)); x.write(out); out.writeMessageEnd(); out.getTransport().flush(); return true; } }
/** * 写入操作 */ @Override public void write(TProtocol oprot) throws TException { if (!"org.apache.thrift.scheme.StandardScheme".equals(oprot.getScheme().getName())) throw new TApplicationException("Service scheme must be 'org.apache.thrift.scheme.StandardScheme' !"); oprot.writeStructBegin(getTStruct()); if (str != null) { oprot.writeFieldBegin(new TField("value", TType.STRING, (short) 0)); oprot.writeString(str); oprot.writeFieldEnd(); } oprot.writeFieldStop(); oprot.writeStructEnd(); }
String recvGet() throws TException { ResultThriftBase result = new ResultThriftBase(); receiveBase(result, Processor.FUNCTION_NAME); if (result.isSet(null)) return result.getStr(); else throw new TApplicationException(TApplicationException.MISSING_RESULT, "Get failed: unknown result"); }
@Override public void sessionEnd(String handle, SessionStatus status) throws TException, InvalidSessionHandle, SafeModeException { checkSafeMode("sessionEnd"); try { Session session = sessionManager.getSession(handle); InetAddress sessionAddr = session.getAddress(); LOG.info("sessionEnd called for session: " + handle + " on " + sessionAddr.getHost() + ":" + sessionAddr.getPort() + " with status: " + status); if (status == SessionStatus.TIMED_OUT) { if (session.getUrl() != null && session.getUrl().indexOf(handle) < 0) { metrics.timeoutRemoteJT(1); } } if (status == SessionStatus.FAILED_JOBTRACKER) { metrics.recordCJTFailure(); } Collection<ResourceGrant> canceledGrants = sessionManager.deleteSession(handle, status); if (canceledGrants == null) { return; } for (ResourceGrant grant: canceledGrants) { nodeManager.cancelGrant(grant.nodeName, handle, grant.id); metrics.releaseResource(grant.type); } scheduler.notifyScheduler(); sessionNotifier.deleteSession(handle); } catch (RuntimeException e) { LOG.error("Error in sessionEnd of " + handle, e); throw new TApplicationException(e.getMessage()); } }
@Override public void sessionUpdateInfo(String handle, SessionInfo info) throws TException, InvalidSessionHandle, SafeModeException { checkSafeMode("sessionUpdateInfo"); try { LOG.info("sessionUpdateInfo called for session: " + handle + " with info: " + info); sessionManager.heartbeat(handle); sessionManager.updateInfo(handle, info); } catch (RuntimeException e) { throw new TApplicationException(e.getMessage()); } }
@Override public void sessionHeartbeat(String handle) throws TException, InvalidSessionHandle, SafeModeException { checkSafeMode("sessionHeartbeat"); try { sessionManager.heartbeat(handle); } catch (RuntimeException e) { throw new TApplicationException(e.getMessage()); } }
@Override public void sessionHeartbeatV2(String handle, HeartbeatArgs jtInfo) throws TException, InvalidSessionHandle, SafeModeException { checkSafeMode("sessionHeartbeatV2"); try { Session session = sessionManager.getSession(handle); if (!session.checkHeartbeatInfo(jtInfo)) { sessionEnd(session.getSessionId(), SessionStatus.FAILED_JOBTRACKER); } sessionManager.heartbeatV2(handle, jtInfo); } catch (RuntimeException e) { throw new TApplicationException(e.getMessage()); } }
@Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { if (this.thriftProxy == null) { throw new IllegalStateException("ThriftClientInterceptor is not properly initialized - " + "invoke 'prepare' before attempting any operations"); } ClassLoader originalClassLoader = overrideThreadContextClassLoader(); try { return methodInvocation.getMethod().invoke(thriftProxy, methodInvocation.getArguments()); } catch (InvocationTargetException e) { Throwable targetEx = e.getTargetException(); if (targetEx instanceof InvocationTargetException) { targetEx = ((InvocationTargetException) targetEx).getTargetException(); } if (targetEx instanceof TApplicationException && ((TApplicationException) targetEx).getType() == TApplicationException.MISSING_RESULT) { return null; } else { throw targetEx; } } catch (Throwable ex) { throw new RemoteProxyFailureException( "Failed to invoke Thrift proxy for remote service [" + getServiceUrl() + "]", ex); } finally { resetThreadContextClassLoader(originalClassLoader); } }
@Override public void serialize(TApplicationException value, JsonGenerator gen, SerializerProvider provider) throws IOException { gen.writeRawValue(writeThriftObjectAsTText(protocol -> { try { value.write(protocol); } catch (TException ex) { throw new IllegalArgumentException(ex); } })); }
@Override public void serialize(ThriftReply value, JsonGenerator gen, SerializerProvider provider) throws IOException { if (value == null) { // Oneway function doesn't provide reply gen.writeNull(); return; } gen.writeStartObject(); gen.writeObjectField("header", value.header()); final TBase<?, ?> result; final TApplicationException exception; if (value.isException()) { result = null; exception = value.exception(); } else { result = value.result(); exception = null; } gen.writeObjectField("result", result); gen.writeObjectField("exception", exception); gen.writeEndObject(); }
/** * Reads a {@link TApplicationException} from the specified {@link TProtocol}. * * <p>Note: This has been copied from {@link TApplicationException#read(TProtocol)} due to API differences * between libthrift 0.9.x and 0.10.x. */ public static TApplicationException read(TProtocol iprot) throws TException { TField field; iprot.readStructBegin(); String message = null; int type = TApplicationException.UNKNOWN; while (true) { field = iprot.readFieldBegin(); if (field.type == TType.STOP) { break; } switch (field.id) { case 1: if (field.type == TType.STRING) { message = iprot.readString(); } else { TProtocolUtil.skip(iprot, field.type); } break; case 2: if (field.type == TType.I32) { type = iprot.readI32(); } else { TProtocolUtil.skip(iprot, field.type); } break; default: TProtocolUtil.skip(iprot, field.type); break; } iprot.readFieldEnd(); } iprot.readStructEnd(); return new TApplicationException(type, message); }
/** * I need to know what type thrift message we are processing, * in order to look up fields by their field name. For example, * i I parse a line "count : 7", I need to know we are in a * StatsThriftMessage, or similar, to know that count should be * of type int32, and have a thrift id 1. * * <p>In order to figure this out, I assume that this method was * called (indirectly) by the read() method in a class T which * is a TBase subclass. It is called that way by thrift generated * code. So, I iterate backwards up the call stack, stopping * at the first method call which belongs to a TBase object. * I return the Class for that object. * * <p>One could argue this is someone fragile and error prone. * The alternative is to modify the thrift compiler to generate * code which passes class information into this (and other) * TProtocol objects, and that seems like a lot more work. Given * the low level interface of TProtocol (e.g. methods like readInt(), * rather than readThriftMessage()), it seems likely that a TBase * subclass, which has the knowledge of what fields exist, as well as * their types & relationships, will have to be the caller of * the TProtocol methods. * * <p>Note: this approach does not handle TUnion, because TUnion has its own implementation of * read/write and any TUnion thrift structure does not override its read and write method. * Thus this algorithm fail to get current specific TUnion thrift structure by reading the stack. * To fix this, we can track call stack of nested thrift objects on our own by overriding * TProtocol.writeStructBegin(), rather than relying on the stack trace. */ private static Class<?> getCurrentThriftMessageClass() { StackTraceElement[] frames = Thread.currentThread().getStackTrace(); for (StackTraceElement f : frames) { String className = f.getClassName(); try { Class<?> clazz = Class.forName(className); // Note, we need to check // if the class is abstract, because abstract class does not have metaDataMap // if the class has no-arg constructor, because FieldMetaData.getStructMetaDataMap // calls clazz.newInstance if (isTBase(clazz) && !isAbstract(clazz) && hasNoArgConstructor(clazz)) { return clazz; } if (isTApplicationException(clazz)) { return clazz; } if (isTApplicationExceptions(clazz)) { return TApplicationException.class; } } catch (ClassNotFoundException ex) { log.warn("Can't find class: " + className, ex); } } throw new RuntimeException("Must call (indirectly) from a TBase/TApplicationException object."); }
/** * Creates a new instance that contains a Thrift {@link TMessageType#EXCEPTION} message. */ public ThriftReply(TMessage header, TApplicationException exception) { super(header); if (header.type != TMessageType.EXCEPTION) { throw new IllegalArgumentException( "header.type: " + typeStr(header.type) + " (expected: EXCEPTION)"); } result = null; this.exception = requireNonNull(exception, "exception"); }
/** * Returns the exception of this reply. * * @throws IllegalStateException if the type of this reply is not {@link TMessageType#EXCEPTION} */ public TApplicationException exception() { if (!isException()) { throw new IllegalStateException("not an exception but a reply"); } return exception; }
@Test(timeout = 10000) public void testMessageLogsForException() throws Exception { HelloService.Iface client = Clients.newClient(clientFactory(), getURI(Handlers.EXCEPTION), Handlers.EXCEPTION.iface(), clientOptions); recordMessageLogs = true; assertThatThrownBy(() -> client.hello("trustin")).isInstanceOf(TApplicationException.class); final RequestLog log = requestLogs.take(); assertThat(log.requestHeaders()).isInstanceOf(HttpHeaders.class); assertThat(log.requestContent()).isInstanceOf(RpcRequest.class); assertThat(log.rawRequestContent()).isInstanceOf(ThriftCall.class); final RpcRequest request = (RpcRequest) log.requestContent(); assertThat(request.serviceType()).isEqualTo(HelloService.Iface.class); assertThat(request.method()).isEqualTo("hello"); assertThat(request.params()).containsExactly("trustin"); final ThriftCall rawRequest = (ThriftCall) log.rawRequestContent(); assertThat(rawRequest.header().type).isEqualTo(TMessageType.CALL); assertThat(rawRequest.header().name).isEqualTo("hello"); assertThat(rawRequest.args()).isInstanceOf(HelloService.hello_args.class); assertThat(((HelloService.hello_args) rawRequest.args()).getName()).isEqualTo("trustin"); assertThat(log.responseHeaders()).isInstanceOf(HttpHeaders.class); assertThat(log.responseContent()).isInstanceOf(RpcResponse.class); assertThat(log.rawResponseContent()).isInstanceOf(ThriftReply.class); final RpcResponse response = (RpcResponse) log.responseContent(); assertThat(response.cause()).isNotNull(); final ThriftReply rawResponse = (ThriftReply) log.rawResponseContent(); assertThat(rawResponse.header().type).isEqualTo(TMessageType.EXCEPTION); assertThat(rawResponse.header().name).isEqualTo("hello"); assertThat(rawResponse.exception()).isNotNull(); }
@Test(timeout = 10000) public void testMessageLogsForException() throws Exception { try (TTransport transport = newTransport("http", "/exception")) { HelloService.Client client = new HelloService.Client.Factory().getClient( ThriftProtocolFactories.BINARY.getProtocol(transport)); recordMessageLogs = true; assertThatThrownBy(() -> client.hello("Trustin")).isInstanceOf(TApplicationException.class); } final RequestLog log = requestLogs.take(); assertThat(log.requestHeaders()).isInstanceOf(HttpHeaders.class); assertThat(log.requestContent()).isInstanceOf(RpcRequest.class); assertThat(log.rawRequestContent()).isInstanceOf(ThriftCall.class); final RpcRequest request = (RpcRequest) log.requestContent(); assertThat(request.serviceType()).isEqualTo(HelloService.AsyncIface.class); assertThat(request.method()).isEqualTo("hello"); assertThat(request.params()).containsExactly("Trustin"); final ThriftCall rawRequest = (ThriftCall) log.rawRequestContent(); assertThat(rawRequest.header().type).isEqualTo(TMessageType.CALL); assertThat(rawRequest.header().name).isEqualTo("hello"); assertThat(rawRequest.args()).isInstanceOf(HelloService.hello_args.class); assertThat(((HelloService.hello_args) rawRequest.args()).getName()).isEqualTo("Trustin"); assertThat(log.responseHeaders()).isInstanceOf(HttpHeaders.class); assertThat(log.responseContent()).isInstanceOf(RpcResponse.class); assertThat(log.rawResponseContent()).isInstanceOf(ThriftReply.class); final RpcResponse response = (RpcResponse) log.responseContent(); assertThat(response.cause()).isNotNull(); final ThriftReply rawResponse = (ThriftReply) log.rawResponseContent(); assertThat(rawResponse.header().type).isEqualTo(TMessageType.EXCEPTION); assertThat(rawResponse.header().name).isEqualTo("hello"); assertThat(rawResponse.exception()).isNotNull(); }
@Test public void test() throws Exception { assertThat(client("").hello("a")).isEqualTo("none:a"); assertThat(client("foo").hello("b")).isEqualTo("foo:b"); assertThat(client("bar").hello("c")).isEqualTo("bar:c"); assertThatThrownBy(() -> client("baz").hello("d")) .isInstanceOf(TApplicationException.class) .hasFieldOrPropertyWithValue("type", TApplicationException.UNKNOWN_METHOD); assertThat(methodNames).containsExactly("hello", "foo:hello", "bar:hello"); }