Skip to content

Commit 319dec3

Browse files
committed
add http logger; update todo; increase spring boot version
1 parent 23c44a7 commit 319dec3

File tree

17 files changed

+631
-16
lines changed

17 files changed

+631
-16
lines changed

TODO.md

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
# TODO LIST
22

3-
# 0.1
4-
- Add RequestLogger Interceptor!
5-
6-
7-
8-
9-
10-
3+
# 0 persist road network data
4+
# 0.1 render road network data
115

126
# 1
137
Track Death & Kills and Log Positions regularly

libs/commons/pom.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@
1616

1717
<dependencies>
1818

19+
<dependency>
20+
<groupId>org.springframework.boot</groupId>
21+
<artifactId>spring-boot-starter-web</artifactId>
22+
</dependency>
23+
<dependency>
24+
<groupId>org.springframework.boot</groupId>
25+
<artifactId>spring-boot-starter-validation</artifactId>
26+
</dependency>
27+
1928
<!-- NEEDED FOR: import org.springframework.lang.Nullable -->
2029
<dependency>
2130
<groupId>org.springframework</groupId>
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package com.recom.commons.spring.http.interceptors.commons.parameter;
2+
3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import com.recom.commons.spring.http.interceptors.requestlogger.logger.HttpRequestLoggableDto;
6+
import jakarta.servlet.http.HttpServletRequest;
7+
import lombok.NonNull;
8+
import lombok.extern.slf4j.Slf4j;
9+
import org.springframework.web.method.HandlerMethod;
10+
import org.springframework.web.util.ContentCachingRequestWrapper;
11+
12+
import java.lang.reflect.Parameter;
13+
import java.nio.charset.StandardCharsets;
14+
import java.util.Enumeration;
15+
import java.util.Map;
16+
import java.util.Optional;
17+
18+
@Slf4j
19+
public class ParameterBagExtractor {
20+
21+
@NonNull
22+
public static RawRequestParameterBag deriveRequestParameterBagFromRawRequest(@NonNull final HttpServletRequest request) {
23+
return deriveRequestParameterBagFromRawRequest(request, Optional.empty(), Optional.empty());
24+
}
25+
26+
@NonNull
27+
public static RawRequestParameterBag deriveRequestParameterBagFromRawRequest(
28+
@NonNull final HttpServletRequest request,
29+
@NonNull final Optional<HandlerMethod> maybeHandlerMethod,
30+
@NonNull final Optional<ObjectMapper> maybeObjectMapper
31+
) {
32+
final Enumeration<String> headerNames = request.getHeaderNames();
33+
final Map<String, String[]> parameterMap = request.getParameterMap();
34+
35+
// RAW REQUEST LOGGER
36+
final RawRequestParameterBag rawRequestParameterBag = RawRequestParameterBag.createRaw();
37+
38+
// Raw Request Headers
39+
while (headerNames.hasMoreElements()) {
40+
final String headerName = headerNames.nextElement();
41+
final String headerValue = request.getHeader(headerName);
42+
rawRequestParameterBag.add(RequestParameterType.HEADER, headerName, headerValue);
43+
}
44+
45+
// RAW REQUEST PARAMETERS
46+
parameterMap.forEach((parameterName, parameterValues) -> {
47+
rawRequestParameterBag.add(RequestParameterType.QUERY_PARAM, parameterName, String.join(",", parameterValues));
48+
});
49+
50+
// DERIVE REQUEST BODY AND PATH VARIABLES
51+
if (maybeHandlerMethod.isPresent() && maybeObjectMapper.isPresent()) {
52+
final Parameter[] reflectionParameters = maybeHandlerMethod.get().getMethod().getParameters();
53+
final ObjectMapper objectMapper = maybeObjectMapper.get();
54+
55+
for (final Parameter reflectionParameter : reflectionParameters) {
56+
if (reflectionParameter.isAnnotationPresent(org.springframework.web.bind.annotation.RequestBody.class)) {
57+
final Class<?> parameterType = reflectionParameter.getType();
58+
if (HttpRequestLoggableDto.class.isAssignableFrom(parameterType)) {
59+
// final Object o = objectMapper.convertValue(request.getParameterMap(), parameterType);
60+
getRequestBody(request).ifPresent(requestBody -> {
61+
rawRequestParameterBag.add(RequestParameterType.BODY, "body-raw", requestBody);
62+
try {
63+
final Object mappedValue = objectMapper.readValue(requestBody, parameterType);
64+
rawRequestParameterBag.add(RequestParameterType.BODY, "body-mapped", mappedValue);
65+
} catch (final JsonProcessingException e) {
66+
log.warn("Error while parsing request body: {}", requestBody, e);
67+
}
68+
});
69+
}
70+
}
71+
}
72+
}
73+
74+
return rawRequestParameterBag;
75+
}
76+
77+
@NonNull
78+
private static Optional<String> getRequestBody(final HttpServletRequest request) {
79+
if (request instanceof ContentCachingRequestWrapper wrappedRequest) {
80+
final byte[] content = wrappedRequest.getContentAsByteArray();
81+
if (content.length > 0) {
82+
return Optional.of(new String(content, StandardCharsets.UTF_8));
83+
}
84+
}
85+
86+
return Optional.empty();
87+
}
88+
89+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.recom.commons.spring.http.interceptors.commons.parameter;
2+
3+
import lombok.NonNull;
4+
5+
public class RawRequestParameterBag extends RequestParameterBag {
6+
7+
@NonNull
8+
public static RawRequestParameterBag createRaw() {
9+
return new RawRequestParameterBag();
10+
}
11+
12+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.recom.commons.spring.http.interceptors.commons.parameter;
2+
3+
import lombok.Getter;
4+
import lombok.NonNull;
5+
import lombok.RequiredArgsConstructor;
6+
7+
@Getter
8+
@RequiredArgsConstructor
9+
public class RequestParameter {
10+
11+
@NonNull
12+
private final RequestParameterType requestParameterType;
13+
14+
@NonNull
15+
private final RequestParameterValue requestParameterValue;
16+
17+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
package com.recom.commons.spring.http.interceptors.commons.parameter;
2+
3+
import lombok.NonNull;
4+
import org.springframework.lang.Nullable;
5+
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
import java.util.Objects;
9+
import java.util.Optional;
10+
11+
public class RequestParameterBag extends ArrayList<RequestParameter> {
12+
13+
@NonNull
14+
final List<String> ignoredHeaders = List.of(
15+
"CACHE-CONTROL",
16+
"PRAGMA",
17+
"HOST",
18+
"USER-AGENT",
19+
"MAX-FORWARDS",
20+
"ORIGIN",
21+
"REFERER",
22+
"SEC-CH-UA-PLATFORM",
23+
"SEC-CH-UA",
24+
"SEC-CH-UA-MOBILE",
25+
"SEC-FETCH-SITE",
26+
"SEC-FETCH-MODE",
27+
"SEC-FETCH-DEST",
28+
"X-ARR-LOG-ID",
29+
"CLIENT-IP",
30+
"X-CLIENT-IP",
31+
"DISGUISED-HOST",
32+
"X-SITE-DEPLOYMENT-ID",
33+
"WAS-DEFAULT-HOSTNAME",
34+
"X-FORWARDED-PROTO",
35+
"X-APPSERVICE-PROTO",
36+
"X-ARR-SSL",
37+
"X-FORWARDED-TLSVERSION",
38+
"X-ORIGINAL-URL",
39+
"X-WAWS-UNENCODED-URL",
40+
"X-CLIENT-PORT",
41+
"TRACEPARENT",
42+
"CONTENT-LENGTH",
43+
"POSTMAN-TOKEN",
44+
"ACCEPT-ENCODING",
45+
"CONNECTION",
46+
"X-MS-AUTH-INTERNAL-TOKEN",
47+
"ACCEPT",
48+
"DNT"
49+
);
50+
final List<String> blacklistedHeaders = List.of(
51+
"X-API-KEY",
52+
"OCP-APIM-SUBSCRIPTION-KEY",
53+
"AUTHORIZATION",
54+
"X-SSC-ID-TOKEN"
55+
);
56+
57+
58+
public RequestParameterBag() {
59+
super();
60+
}
61+
62+
public RequestParameterBag(
63+
@NonNull final RequestParameterType type,
64+
@NonNull final String name,
65+
@NonNull final Object value
66+
) {
67+
super();
68+
this.add(new RequestParameter(type, concatNamePlusValue(name, value)));
69+
}
70+
71+
@NonNull
72+
private RequestParameterValue concatNamePlusValue(
73+
@NonNull final String name,
74+
@Nullable final Object value
75+
) {
76+
return new RequestParameterValue(name, value);
77+
}
78+
79+
@NonNull
80+
public static RequestParameterBag create() {
81+
return new RequestParameterBag();
82+
}
83+
84+
@NonNull
85+
public static RequestParameterBag create(
86+
@NonNull final RequestParameterType type,
87+
@NonNull final String name,
88+
@NonNull final Object value
89+
) {
90+
return new RequestParameterBag().add(type, name, value);
91+
}
92+
93+
@NonNull
94+
public RequestParameterBag add(
95+
@NonNull final RequestParameterType type,
96+
@NonNull final String name,
97+
@Nullable final Object value
98+
) {
99+
this.add(new RequestParameter(type, concatNamePlusValue(name, value)));
100+
return this;
101+
}
102+
103+
@NonNull
104+
public String toString() {
105+
return this.stream()
106+
.map(this::mask)
107+
.filter(Objects::nonNull)
108+
.map(requestParameter -> String.format("%s:%s", requestParameter.getRequestParameterType().toString(), requestParameter.getRequestParameterValue().toString()))
109+
.reduce((a, b) -> a + " | " + b)
110+
.orElse("");
111+
}
112+
113+
@Nullable
114+
private RequestParameter mask(@NonNull final RequestParameter requestParameter) {
115+
if (RequestParameterType.HEADER.equals(requestParameter.getRequestParameterType())) {
116+
final String headerName = requestParameter.getRequestParameterValue().getName();
117+
// Ignore Headers with ignored names
118+
if (ignoredHeaders.contains(headerName.toUpperCase())) {
119+
return null;
120+
}
121+
122+
// Mask Headers with blacklisted names
123+
if (blacklistedHeaders.contains(headerName.toUpperCase())) {
124+
return new RequestParameter(requestParameter.getRequestParameterType(), new RequestParameterValue(headerName, "***"));
125+
}
126+
}
127+
128+
return requestParameter;
129+
}
130+
131+
@NonNull
132+
public Optional<RequestParameter> find(
133+
@NonNull final RequestParameterType requestParameterType,
134+
@NonNull final String name
135+
) {
136+
return this.stream()
137+
.filter(requestParameter -> requestParameter.getRequestParameterType().equals(requestParameterType))
138+
.filter(requestParameter -> requestParameter.getRequestParameterValue().getName().equalsIgnoreCase(name))
139+
.findFirst();
140+
141+
}
142+
143+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.recom.commons.spring.http.interceptors.commons.parameter;
2+
3+
public enum RequestParameterType {
4+
PATH,
5+
QUERY_PARAM,
6+
HEADER,
7+
BODY
8+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.recom.commons.spring.http.interceptors.commons.parameter;
2+
3+
import lombok.Getter;
4+
import lombok.NonNull;
5+
import org.springframework.lang.Nullable;
6+
7+
@Getter
8+
public class RequestParameterValue {
9+
10+
@NonNull
11+
private final String name;
12+
@Nullable
13+
private final Object value;
14+
15+
public RequestParameterValue(
16+
@NonNull final String name,
17+
@Nullable final Object value
18+
) {
19+
this.name = name;
20+
this.value = value;
21+
}
22+
23+
@NonNull
24+
public String toString() {
25+
return String.format("%1s='%2s'", name, value);
26+
}
27+
28+
}

0 commit comments

Comments
 (0)