http://jira.mfd.msk:8088/browse/BKI-3215 Added CachedHttpRequestWrapper to handle request body before doFilter invocation; Added memberCode ro logs; Updated version to 1.17
This commit is contained in:
parent
b61970a71e
commit
3b9c2eaa15
5 changed files with 125 additions and 14 deletions
|
|
@ -1,5 +1,5 @@
|
|||
#commons
|
||||
APP_VERSION=1.16
|
||||
APP_VERSION=1.17
|
||||
REGISTRY_URL=rh8-vm3.nbki.msk:5000
|
||||
JMX_PORT=
|
||||
JMX_HOSTNAME=
|
||||
|
|
|
|||
2
pom.xml
2
pom.xml
|
|
@ -10,7 +10,7 @@
|
|||
</parent>
|
||||
<groupId>ru.nbch</groupId>
|
||||
<artifactId>credit-tracker</artifactId>
|
||||
<version>1.16</version>
|
||||
<version>1.17</version>
|
||||
<name>credit_tracker</name>
|
||||
<description>Credit Tracker Application</description>
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package ru.nbch.credit_tracker.config.rest.filters;
|
|||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletRequestWrapper;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.Part;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
|
@ -12,11 +13,18 @@ import org.springframework.util.StringUtils;
|
|||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
import org.springframework.web.util.ContentCachingRequestWrapper;
|
||||
import org.springframework.web.util.ContentCachingResponseWrapper;
|
||||
import ru.nbch.credit_tracker.config.rest.wrappers.CachedHttpRequestWrapper;
|
||||
import ru.nbch.credit_tracker.entities.user_request.active_packages.MonitoringActivePackagesRequest;
|
||||
import ru.nbch.credit_tracker.entities.user_request.all_packages.MonitoringAllPackagesRequest;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@Order(0)
|
||||
|
|
@ -25,6 +33,12 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
|
|||
private static final Set<String> SENSITIVE_HEADERS = Set.of("authorization", "cookie", "set-cookie");
|
||||
private static final int MAX_BODY = 10 * 1024;
|
||||
|
||||
private final IXmlProcessor xmlProcessor;
|
||||
|
||||
public HttpLoggingFilter(IXmlProcessor xmlProcessor) {
|
||||
this.xmlProcessor = xmlProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldNotFilter(HttpServletRequest request) {
|
||||
String path = request.getRequestURI();
|
||||
|
|
@ -38,7 +52,7 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
|
|||
|
||||
long startNs = System.nanoTime();
|
||||
|
||||
ContentCachingRequestWrapper req = wrapRequest(request);
|
||||
HttpServletRequestWrapper req = wrapRequest(request);
|
||||
ContentCachingResponseWrapper resp = new ContentCachingResponseWrapper(response);
|
||||
|
||||
String correlationId = Optional.ofNullable(request.getHeader("X-Correlation-Id"))
|
||||
|
|
@ -46,14 +60,15 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
|
|||
.orElse(UUID.randomUUID().toString());
|
||||
resp.setHeader("X-Correlation-Id", correlationId);
|
||||
|
||||
logIncomingRequest(req, correlationId);
|
||||
String memberCode = parseMemberCode(req);
|
||||
logIncomingRequest(req, correlationId, memberCode);
|
||||
|
||||
try {
|
||||
chain.doFilter(req, resp);
|
||||
} finally {
|
||||
long tookMs = (System.nanoTime() - startNs) / 1_000_000;
|
||||
|
||||
Map<String, String> reqParams = paramsMap(req);
|
||||
Map<String, String> reqParams = paramsMap(req, memberCode);
|
||||
|
||||
Map<String, String> reqHeaders = headersMap(req);
|
||||
Map<String, String> respHeaders = headersMap(resp);
|
||||
|
|
@ -62,10 +77,9 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
|
|||
mask(respHeaders);
|
||||
|
||||
log.info(
|
||||
"HTTP (RESPONSE) {} {}{} | status={} | took={}ms | cid={} | reqHeaders={} | reqParams={} | respHeaders={}",
|
||||
"HTTP (RESPONSE) {} {} | status={} | took={}ms | cid={} | reqHeaders={} | reqParams={} | respHeaders={}",
|
||||
req.getMethod(),
|
||||
req.getRequestURI(),
|
||||
req.getQueryString() == null ? "" : "?" + req.getQueryString(),
|
||||
resp.getStatus(),
|
||||
tookMs,
|
||||
correlationId,
|
||||
|
|
@ -78,34 +92,75 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
|
|||
}
|
||||
}
|
||||
|
||||
private String parseMemberCode(HttpServletRequestWrapper req) {
|
||||
String memberCode = null;
|
||||
if (!(req instanceof CachedHttpRequestWrapper)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void logIncomingRequest(ContentCachingRequestWrapper req, String correlationId) {
|
||||
Map<String, String> reqParams = paramsMap(req);
|
||||
String body = ((CachedHttpRequestWrapper) req).getBody();
|
||||
if (isBlank(body)) {
|
||||
return null;
|
||||
}
|
||||
switch (req.getRequestURI()) {
|
||||
case "/api/v1/signal/active_packages":
|
||||
try {
|
||||
MonitoringActivePackagesRequest activePackagesRequest = xmlProcessor.read(body, MonitoringActivePackagesRequest.class);
|
||||
if (activePackagesRequest != null && isNotBlank(activePackagesRequest.getUserId())) {
|
||||
memberCode = activePackagesRequest.getUserId().substring(0, 6);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
memberCode = null;
|
||||
}
|
||||
break;
|
||||
case "/api/v1/signal/all_packages":
|
||||
try {
|
||||
MonitoringAllPackagesRequest allPackagesRequest = xmlProcessor.read(body, MonitoringAllPackagesRequest.class);
|
||||
if (allPackagesRequest != null && isNotBlank(allPackagesRequest.getUserId())) {
|
||||
memberCode = allPackagesRequest.getUserId().substring(0, 6);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
memberCode = null;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return memberCode;
|
||||
}
|
||||
|
||||
|
||||
private void logIncomingRequest(HttpServletRequestWrapper req, String correlationId, String memberCode) {
|
||||
Map<String, String> reqParams = paramsMap(req, memberCode);
|
||||
Map<String, String> reqHeaders = headersMap(req);
|
||||
mask(reqHeaders);
|
||||
|
||||
log.info(
|
||||
"HTTP (REQUEST) {} {}{} | cid={} | reqHeaders={} | reqParams={}",
|
||||
"HTTP (REQUEST) {} {} | cid={} | reqHeaders={} | reqParams={}",
|
||||
req.getMethod(),
|
||||
req.getRequestURI(),
|
||||
req.getQueryString() == null ? "" : "?" + req.getQueryString(),
|
||||
correlationId,
|
||||
reqHeaders,
|
||||
reqParams
|
||||
);
|
||||
}
|
||||
|
||||
private static ContentCachingRequestWrapper wrapRequest(HttpServletRequest request) {
|
||||
return (request instanceof ContentCachingRequestWrapper c) ? c : new ContentCachingRequestWrapper(request, MAX_BODY);
|
||||
private static HttpServletRequestWrapper wrapRequest(HttpServletRequest request) throws IOException {
|
||||
return switch (request.getRequestURI()) {
|
||||
case "/api/v1/signal/active_packages", "/api/v1/signal/all_packages" ->
|
||||
new CachedHttpRequestWrapper(request);
|
||||
default ->
|
||||
(request instanceof ContentCachingRequestWrapper c) ? c : new ContentCachingRequestWrapper(request, MAX_BODY);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private static Map<String, String> headersMap(HttpServletRequest req) {
|
||||
return Collections.list(req.getHeaderNames()).stream()
|
||||
.collect(Collectors.toMap(h -> h, req::getHeader, (a, b) -> a, LinkedHashMap::new));
|
||||
}
|
||||
|
||||
private Map<String, String> paramsMap(ContentCachingRequestWrapper req) {
|
||||
private static Map<String, String> paramsMap(HttpServletRequestWrapper req, String memberCode) {
|
||||
Map<String, String> paramsMap = new LinkedHashMap<>();
|
||||
req.getParameterMap().forEach((k, v) -> {
|
||||
String params = String.join(", ", v);
|
||||
|
|
@ -120,6 +175,11 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
|
|||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (memberCode != null) {
|
||||
paramsMap.put("memberCode", memberCode);
|
||||
}
|
||||
|
||||
return paramsMap;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
package ru.nbch.credit_tracker.config.rest.wrappers;
|
||||
|
||||
import jakarta.servlet.ReadListener;
|
||||
import jakarta.servlet.ServletInputStream;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletRequestWrapper;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
@Getter
|
||||
public class CachedHttpRequestWrapper extends HttpServletRequestWrapper {
|
||||
private final String body;
|
||||
|
||||
|
||||
public CachedHttpRequestWrapper(HttpServletRequest request) throws IOException {
|
||||
super(request);
|
||||
body = IOUtils.toString(request.getReader());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletInputStream getInputStream() {
|
||||
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(getBody().getBytes());
|
||||
return new ServletInputStream() {
|
||||
public int read() {
|
||||
return byteArrayInputStream.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadListener(ReadListener listener) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -6,6 +6,8 @@ import org.springframework.context.annotation.Configuration;
|
|||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||
import ru.nbch.credit_tracker.entities.external_response.monitoring_report_file.SgnlReportMonitorigSetupError;
|
||||
import ru.nbch.credit_tracker.entities.external_response.online_report.SgnlOnlineReport;
|
||||
import ru.nbch.credit_tracker.entities.user_request.active_packages.MonitoringActivePackagesRequest;
|
||||
import ru.nbch.credit_tracker.entities.user_request.all_packages.MonitoringAllPackagesRequest;
|
||||
import ru.nbch.credit_tracker.entities.user_response.errors.MonitoringError;
|
||||
import ru.nbch.credit_tracker.entities.user_response.success.MonitoringSetupResponse;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor;
|
||||
|
|
@ -26,6 +28,8 @@ public class XmlConfig {
|
|||
// unmarshalling classes
|
||||
SgnlOnlineReport.class,
|
||||
SgnlReportMonitorigSetupError.class,
|
||||
MonitoringActivePackagesRequest.class,
|
||||
MonitoringAllPackagesRequest.class,
|
||||
// marshalling classes
|
||||
MonitoringError.class,
|
||||
MonitoringSetupResponse.class);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue