cl
昨天 c4bba32b20f0869b45ed14be04543869dd91ee6c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package com.vincent.rsf.server.api.feign;
 
import com.vincent.rsf.httpaudit.model.HttpAuditDecision;
import com.vincent.rsf.httpaudit.service.HttpAuditOutboundRecorder;
import feign.Client;
import feign.Request;
import feign.Response;
import feign.Util;
import lombok.RequiredArgsConstructor;
 
import java.io.IOException;
import java.nio.charset.StandardCharsets;
 
/**
 * Feign 出站写 sys_http_audit_log(与 RestTemplate 共用规则与截断)
 */
@RequiredArgsConstructor
public class AuditingFeignClient implements Client {
 
    private static final String FN_FEIGN = "HTTP出站(Feign)";
 
    private final Client delegate;
    private final HttpAuditOutboundRecorder outboundRecorder;
 
    @Override
    public Response execute(Request request, Request.Options options) throws IOException {
        if (!outboundRecorder.isAuditEnabled()) {
            return delegate.execute(request, options);
        }
        String url = request.url();
        String method = request.httpMethod().name();
        byte[] reqBytes = request.body() == null ? new byte[0] : request.body();
        String reqText = new String(reqBytes, StandardCharsets.UTF_8);
        HttpAuditDecision dec = outboundRecorder.decideOutbound(url, method, reqText);
        long t0 = System.currentTimeMillis();
        Response resp;
        try {
            resp = delegate.execute(request, options);
        } catch (Throwable t) {
            outboundRecorder.saveOutbound(FN_FEIGN, url, method, reqText, dec, null, null, t0, t);
            if (t instanceof IOException) {
                throw (IOException) t;
            }
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            }
            if (t instanceof Error) {
                throw (Error) t;
            }
            throw new IOException(t);
        }
        if (!dec.isAudit()) {
            return resp;
        }
        byte[] respBytes;
        try {
            respBytes = Util.toByteArray(resp.body().asInputStream());
        } catch (IOException e) {
            outboundRecorder.saveOutbound(FN_FEIGN, url, method, reqText, dec, resp.status(), null, t0, e);
            throw e;
        }
        String resText = new String(respBytes, StandardCharsets.UTF_8);
        outboundRecorder.saveOutbound(FN_FEIGN, url, method, reqText, dec, resp.status(), resText, t0, null);
        return Response.builder()
                .status(resp.status())
                .reason(resp.reason())
                .headers(resp.headers())
                .body(respBytes)
                .request(resp.request())
                .build();
    }
}