Skip to content

Commit 17d9749

Browse files
committed
feature: add X-Correlation-Id to tracing filter
1 parent 96ff4a0 commit 17d9749

File tree

1 file changed

+11
-138
lines changed

1 file changed

+11
-138
lines changed
Lines changed: 11 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -1,157 +1,30 @@
11
package uk.gov.hmcts.cp.integration;
22

3-
import com.fasterxml.jackson.core.type.TypeReference;
4-
import com.fasterxml.jackson.databind.ObjectMapper;
5-
import org.junit.jupiter.api.AfterEach;
6-
import org.junit.jupiter.api.BeforeEach;
73
import org.junit.jupiter.api.Test;
8-
import org.slf4j.MDC;
9-
import org.springframework.beans.factory.annotation.Autowired;
10-
import org.springframework.beans.factory.annotation.Value;
114
import org.springframework.test.web.servlet.MvcResult;
12-
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
13-
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
14-
import uk.gov.hmcts.cp.entities.ExampleEntity;
15-
import uk.gov.hmcts.cp.repositories.ExampleRepository;
16-
17-
import java.io.ByteArrayOutputStream;
18-
import java.io.PrintStream;
19-
import java.nio.charset.StandardCharsets;
20-
import java.util.Map;
215

226
import static org.assertj.core.api.Assertions.assertThat;
23-
import static org.junit.jupiter.api.Assertions.assertEquals;
24-
import static org.junit.jupiter.api.Assertions.assertNotNull;
7+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
258
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
9+
import static uk.gov.hmcts.cp.filters.tracing.TracingFilter.CORRELATION_ID_KEY;
2610

2711
class TracingIntegrationTest extends IntegrationTestBase {
2812

29-
// Constants for tracing field names
30-
private static final String TRACE_ID_FIELD = "traceId";
31-
private static final String SPAN_ID_FIELD = "spanId";
32-
33-
// Constants for test trace values
34-
private static final String TEST_TRACE_ID_1 = "test-trace-id-12345";
35-
private static final String TEST_SPAN_ID_1 = "test-span-id-67890";
36-
private static final String TEST_TRACE_ID_2 = "1234-1234";
37-
private static final String TEST_SPAN_ID_2 = "567-567";
38-
39-
@Value("${spring.application.name}")
40-
private String springApplicationName;
41-
42-
private final PrintStream originalStdOut = System.out;
43-
44-
@Autowired
45-
ExampleRepository exampleRepository;
46-
47-
private ExampleEntity entity;
48-
49-
@BeforeEach
50-
void setup() {
51-
MDC.put(TRACE_ID_FIELD, TEST_TRACE_ID_1);
52-
MDC.put(SPAN_ID_FIELD, TEST_SPAN_ID_1);
53-
MDC.put("applicationName", springApplicationName);
54-
entity = exampleRepository.save(
55-
ExampleEntity.builder()
56-
.exampleText("Welcome to service-hmcts-springboot-template")
57-
.build()
58-
);
59-
}
60-
61-
@AfterEach
62-
void afterEach() {
63-
System.setOut(originalStdOut);
64-
MDC.clear();
65-
}
13+
private static final String TEST_CORRELATION_ID = "12345678-1234-1234-1234-123456789012";
6614

6715
@Test
68-
void incoming_request_should_add_new_tracing() throws Exception {
69-
final MvcResultHelper result = performRequestAndCaptureLogs("/example/{example_id}", null, null);
70-
final Map<String, Object> rootControllerLog = findRootControllerLog(result.capturedLogOutput());
71-
72-
assertThat(rootControllerLog).isNotNull();
73-
assertNotNull(rootControllerLog.get(TRACE_ID_FIELD));
74-
assertNotNull(rootControllerLog.get(SPAN_ID_FIELD));
75-
assertThat(rootControllerLog).containsEntry("applicationName", springApplicationName);
76-
77-
assertCommonLogFields(rootControllerLog);
16+
void incomingRequestShouldReturnOk() throws Exception {
17+
mockMvc.perform(get("/"))
18+
.andExpect(status().isOk());
7819
}
7920

8021
@Test
81-
void incoming_request_with_traceId_should_pass_through() throws Exception {
82-
// Override the MDC with the header values that would be set by TracingFilter
83-
MDC.put(TRACE_ID_FIELD, TEST_TRACE_ID_2);
84-
MDC.put(SPAN_ID_FIELD, TEST_SPAN_ID_2);
85-
86-
final MvcResultHelper result = performRequestAndCaptureLogs("/example/{example_id}", TEST_TRACE_ID_2, TEST_SPAN_ID_2);
87-
final Map<String, Object> rootControllerLog = findRootControllerLog(result.capturedLogOutput());
88-
89-
assertTracingFields(rootControllerLog, TEST_TRACE_ID_2, TEST_SPAN_ID_2);
90-
assertResponseHeaders(result.mvcResult(), TEST_TRACE_ID_2, TEST_SPAN_ID_2);
91-
}
92-
93-
private ByteArrayOutputStream captureStdOut() {
94-
final ByteArrayOutputStream capturedStdOut = new ByteArrayOutputStream();
95-
System.setOut(new PrintStream(capturedStdOut, true, StandardCharsets.UTF_8));
96-
return capturedStdOut;
97-
}
98-
99-
private MvcResultHelper performRequestAndCaptureLogs(final String path, final String traceId, final String spanId) throws Exception {
100-
final ByteArrayOutputStream capturedStdOut = captureStdOut();
101-
102-
MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get(path, entity.getId());
103-
if (traceId != null) {
104-
requestBuilder = requestBuilder.header(TRACE_ID_FIELD, traceId);
105-
}
106-
if (spanId != null) {
107-
requestBuilder = requestBuilder.header(SPAN_ID_FIELD, spanId);
108-
}
109-
110-
final MvcResult result = mockMvc.perform(requestBuilder)
111-
.andExpect(status().isOk())
22+
void subscriptionEndpointWithCorrelationIdShouldEchoHeaderInResponse() throws Exception {
23+
MvcResult result = mockMvc.perform(get("/")
24+
.header(CORRELATION_ID_KEY, TEST_CORRELATION_ID))
11225
.andReturn();
11326

114-
return new MvcResultHelper(result, capturedStdOut.toString(StandardCharsets.UTF_8));
115-
}
116-
117-
private Map<String, Object> findRootControllerLog(final String logOutput) throws Exception {
118-
final String[] logLines = logOutput.split("\n");
119-
final ObjectMapper objectMapper = new ObjectMapper();
120-
final TypeReference<Map<String, Object>> typeReference = new TypeReference<>() {
121-
};
122-
123-
Map<String, Object> stringObjectMap = null;
124-
for (final String logLine : logLines) {
125-
if (logLine.contains("ExampleController") && stringObjectMap == null) {
126-
stringObjectMap = objectMapper.readValue(logLine, typeReference);
127-
}
128-
}
129-
130-
if (stringObjectMap != null) {
131-
return stringObjectMap;
132-
} else {
133-
throw new AssertionError("RootController log message not found in output: " + logOutput);
134-
}
135-
}
136-
137-
private void assertTracingFields(final Map<String, Object> log, final String expectedTraceId, final String expectedSpanId) {
138-
assertThat(log).isNotNull();
139-
assertEquals(log.get(TRACE_ID_FIELD), expectedTraceId);
140-
assertEquals(log.get(SPAN_ID_FIELD), expectedSpanId);
141-
assertEquals(log.get("applicationName"), springApplicationName);
142-
}
143-
144-
private void assertCommonLogFields(final Map<String, Object> log) {
145-
assertEquals("uk.gov.hmcts.cp.controllers.ExampleController", log.get("logger_name"));
146-
assertEquals(log.get("message"), "getExampleByExampleId example for " + entity.getId() + "\n");
147-
}
148-
149-
private void assertResponseHeaders(final MvcResult result, final String expectedTraceId, final String expectedSpanId) {
150-
assertThat(result.getResponse().getHeader(TRACE_ID_FIELD)).isEqualTo(expectedTraceId);
151-
assertThat(result.getResponse().getHeader(SPAN_ID_FIELD)).isEqualTo(expectedSpanId);
152-
}
153-
154-
// Helper class to encapsulate MvcResult and captured log output
155-
private record MvcResultHelper(MvcResult mvcResult, String capturedLogOutput) {
27+
String responseCorrelationId = result.getResponse().getHeader(CORRELATION_ID_KEY);
28+
assertThat(responseCorrelationId).isEqualTo(TEST_CORRELATION_ID);
15629
}
15730
}

0 commit comments

Comments
 (0)