【问题标题】:Audit gRPC calls in Java在 Java 中审计 gRPC 调用
【发布时间】:2019-09-26 15:02:57
【问题描述】:

我正在尝试创建一个ServerInterceptor 来审核对 gRPC API 的所有调用。我想为每次调用 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;
}

我的挑战是似乎没有一个地方可以收集这些信息。例如,如果这是一个 REST API,我可以创建一个过滤器,该过滤器可以访问请求和响应对象,其中包含所有标头等,并且可以将过滤器链调用包装在 try/catch 中以确定是否存在错误等。但是,对于 gRPC,所有这些不同的部分都有些脱节。标头在ServerInterceptor#interceptCall 方法中接收,如果我创建SimpleForwardingServerCallListener 并覆盖onMessage 方法,则可以访问请求对象,如果我创建SimpleForwardingServerCall 并覆盖sendMessage 对象,则可以访问响应对象,我可以覆盖SimpleForwardingServerCallListener 中的onHalfComplete 方法并将调用包装在try/catch 中以确定调用是否成功。如何将所有这些信息放在一个对象中,以单行形式写入日志或存储在审计数据库中?

【问题讨论】:

    标签: java grpc grpc-java


    【解决方案1】:

    您应该覆盖您感兴趣的每个调用,复制出您需要的数据。然后在onComplete()/onCancel() 中将数据存储到数据库中。 onComplete()/onCancel() 始终是 RPC 的结束(尽管意识到发送可能发生在取消之后,因为处理取消是不合理的;onCancel() 之后的任何内容都会被 grpc 丢弃)。

    您将创建一个(转发)ServerCall 和一个(转发)ServerCall.Listener。要将数据存储在“一个地方”,您只需让其中一个对象引用另一个对象(例如,嵌套类)。

    请注意,制作Metadata 的完整副本真的很重要,因为它不是线程安全的对象。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-14
      • 1970-01-01
      • 2017-07-14
      • 2018-11-23
      • 2013-10-30
      • 1970-01-01
      相关资源
      最近更新 更多