Tengo un servidor GRPC-java y necesidad de hacer una llamada asincrónica a un servicio de autenticación, antes de procesar una solicitud. Creo que esto debe hacerse en un interceptor, pero requiere para devolver de forma sincrónica un oyente desde interceptCall ()
class AuthInterceptor implements ServerInterceptor {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
ServerCall<ReqT, RespT> call,
Metadata headers,
ServerCallHandler<ReqT, RespT> next
) {
String token = ""; //get token from headers
authService.authorize(token).subscribe(
ok -> // process the request
error -> call.close(Status.UNAUTHENTICATED, headers)
);
// Here we need to return a Listener, but we haven't started a call yet
}
}
Así que las preguntas son: cómo hacer una llamada asincrónica de un ServerInterceptor, y si no se puede hacer, lo que es la forma correcta de las solicitudes de forma asíncrona autenticar GRPC? Sé que se puede hacer directamente en los servicios GRPC con StreamObservers, pero solicitud de autorización es una preocupación transversal y interceptores parece ser un lugar perfecto para ello.
Es necesario para devolver una ServerCall.Listener
. Pero ya que no se conoce el Listener
delegar en, puede reemplazar cada método en el Listener
que añadir la devolución de llamada a una cola. Una vez que la autenticación se ha completado, la fuga de la cola.
class DelayedListener<ReqT> extends Listener<ReqT> {
private Listener<ReqT> delegate;
private List<Runnable> events = new ArrayList<Runnable>();
@Override public synchronized void onMessage(ReqT message) {
if (delegate == null) {
events.add(() -> delegate.onMessage(message));
} else {
delegate.onMessage(message);
}
}
...
public synchronized void setDelegate(Listener<ReqT> delegate) {
this.delegate = delegate;
for (Runnable runnable : events) {
runnable.run();
}
events = null;
}
}