tree 97eb91d293ea751a4856fd7d26101ed1daf4651a
parent da2ef3486ba5c0f27e470f010590b14d330f799a
author Thomas <thomasbruggink@hotmail.com> 1708851938 +0900
committer Jens Geyer <Jens-G@users.noreply.github.com> 1709682838 +0100

THRIFT-5762 Expose service result objects in Java

Some libraries want to bypass the TServer class and handle the full
service startup manually. For example when building a service that hosts
multiple thrift services where the IFace type is unknown when handling a
request.

For example when you host multiple services on top of netty and through
an HTTP path you want to route to the correct thrift service. In this
situation you treat can treat an IFace as an Object and use the
`getProcessMapView()` method to parse a byte array into a thrift message
and pass let the `AsyncProcessFunction` handle the invocation.

To return a correct thrift response it's necessary to write the
`{service_name}_result` that contains the response args.
While it is possible to get an incoming args object from the
(Async)ProcessFunction its unfortunately not possible to get
a result object without using reflection.

This PR extends the (Async)ProcessFunction by adding a
`getEmptyResultInstance` method that returns a new generic `A` (answer)
that matches the `{service_name}_result` object.

This allows thrift users to write the following processing code:
```java
<I> void handleRequest(
        TProtocol in,
        TProtocol out,
        TBaseAsyncProcessor<I> processor,
        I asyncIface
) throws TException {
    final Map<String, AsyncProcessFunction<Object, TBase<?, ?>, TBase<?, ?>, TBase<?, ?>>> processMap = (Map) processor.getProcessMapView();
    final var msg = in.readMessageBegin();
    final var fn = processMap.get(msg.name);

    final var args = fn.getEmptyArgsInstance();
    args.read(in);
    in.readMessageEnd();

    if (fn.isOneway()) {
        return;
    }

    fn.start(asyncIface, args, new AsyncMethodCallback<>() {
        @Override
        public void onComplete(TBase<?, ?> o) {
            try {
                out.writeMessageBegin(new TMessage(fn.getMethodName(), TMessageType.REPLY, msg.getSeqid()));
                final var response_result = fn.getEmptyResultInstance();
                final var success_field = response_result.fieldForId(SUCCESS_ID);
                ((TBase) response_result).setFieldValue(success_field, o);
                response_result.write(out);
                out.writeMessageEnd();
                out.getTransport().flush();
            } catch (TException e) {
                throw new RuntimeException(e);
            }
        }

        @Override
        public void onError(Exception e) {
            try {
                out.writeMessageBegin(new TMessage(fn.getMethodName(), TMessageType.EXCEPTION, msg.getSeqid()));
                ((TApplicationException) e).write(out);
                out.writeMessageEnd();
                out.getTransport().flush();
            } catch (TException ex) {
                throw new RuntimeException(ex);
            }
        }
    });
}
```
The above example code doesn't need any reference to the original types
and can dynamically create the correct objects to return a correct
response.
