Аудит вызовов gRPC в Java - PullRequest
       83

Аудит вызовов gRPC в Java

2 голосов
/ 26 сентября 2019

Я пытаюсь создать ServerInterceptor для аудита всех вызовов API gRPC.Я хотел бы составить объект со структурой, как показано ниже для каждого вызова API.Эти звонки - все унарные звонки - простой запрос и ответ.

public class ApiAudit {

    private Map<String, String> headers;
    private long processTime;
    private String api;
    private String protocol;
    private String requestBody;
    private String responseBody;
    private int responseCode;
    private String errorMessage;
    private boolean isDeprecated;
}

Моя проблема в том, что, похоже, нет единого места, где я мог бы собрать эту информацию.Если бы это был API REST, например, я мог бы создать фильтр, который имел бы доступ к объектам запроса и ответа, которые содержат все заголовки и т. Д., И мог бы обернуть вызов цепочки фильтров в попытку / уловку, чтобы определить, был лиошибки и т. д. Однако, с gRPC все эти разные части несколько разобщены.Заголовки принимаются в методе ServerInterceptor#interceptCall, объект запроса доступен, если я создаю SimpleForwardingServerCallListener и переопределяю метод onMessage, объект ответа доступен, если я создаю SimpleForwardingServerCall и переопределяю объект sendMessageи я могу переопределить метод onHalfComplete в SimpleForwardingServerCallListener и обернуть вызов там в try / catch, чтобы определить, был ли вызов успешным.Как я могу собрать всю эту информацию в один объект, чтобы записать в виде одной строки в журнал или сохранить в базе данных аудита?

1 Ответ

0 голосов
/ 26 сентября 2019

Вы должны переопределить каждый интересующий вас вызов, скопировав необходимые данные.Затем в onComplete() / onCancel() вы сохраняете данные в базе данных.onComplete() / onCancel() всегда является концом RPC (хотя следует понимать, что отправка может произойти после отмены, потому что обработка отмены является слишком медленной; что-либо после onCancel() отбрасывается grpc).

Выбудет создавать (переадресация) ServerCall и (пересылка) ServerCall.Listener.Чтобы хранить данные в «одном месте», вы можете просто сделать так, чтобы один из ваших объектов ссылался на другой (например, на вложенный класс).

Обратите внимание, что действительно важно сделатьполная копия Metadata, поскольку он не является потокобезопасным объектом.

Metadata copy = new Metadata();
copy.merge(headers);
next.interceptCall(call, headers);
...