From 1d2f06958093b8ec1ca03d48cd75274295a7295e Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 9 Oct 2018 11:53:06 +0100 Subject: [PATCH] Allow HttpTrace instances to be created Previously, the API required to create HttpTrace instances was package-private. This made it difficult to implement an HttpTraceRepository that persists the HttpTrace instances rather than holding them in memory as it inhibited recreation of the instances when they read from the persistent store. This commit adds public constructors to HttpTrace and related classes to enable recreation of an HttpTrace. The package-private methods for mutating properties have not been made public to ensure that the public API remains immutable. Closes gh-14726 --- .../boot/actuate/trace/http/HttpTrace.java | 81 ++++++++++++++++--- 1 file changed, 72 insertions(+), 9 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/trace/http/HttpTrace.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/trace/http/HttpTrace.java index 74912c2c7f1..b80ffc9f571 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/trace/http/HttpTrace.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/trace/http/HttpTrace.java @@ -18,6 +18,7 @@ package org.springframework.boot.actuate.trace.http; import java.net.URI; import java.time.Instant; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -33,7 +34,7 @@ import org.springframework.util.StringUtils; */ public final class HttpTrace { - private final Instant timestamp = Instant.now(); + private final Instant timestamp; private volatile Principal principal; @@ -45,8 +46,32 @@ public final class HttpTrace { private volatile Long timeTaken; + /** + * Creates a fully-configured {@code HttpTrace} instance. Primarly for use by + * {@link HttpTraceRepository} implementations when recreating a trace from a + * persistent store. + * @param request the request + * @param response the response + * @param timestamp the timestamp of the request-response exchange + * @param principal the principal, if any + * @param session the session, if any + * @param timeTaken the time taken, in milliseconds, to complete the request-response + * exchange, if known + * @since 2.1.0 + */ + public HttpTrace(Request request, Response response, Instant timestamp, + Principal principal, Session session, Long timeTaken) { + this.request = request; + this.response = response; + this.timestamp = timestamp; + this.principal = principal; + this.session = session; + this.timeTaken = timeTaken; + } + HttpTrace(TraceableRequest request) { this.request = new Request(request); + this.timestamp = Instant.now(); } public Instant getTimestamp() { @@ -107,10 +132,26 @@ public final class HttpTrace { private final String remoteAddress; private Request(TraceableRequest request) { - this.method = request.getMethod(); - this.uri = request.getUri(); - this.headers = request.getHeaders(); - this.remoteAddress = request.getRemoteAddress(); + this(request.getMethod(), request.getUri(), request.getHeaders(), + request.getRemoteAddress()); + } + + /** + * Creates a fully-configured {@code Request} instance. Primarly for use by + * {@link HttpTraceRepository} implementations when recreating a request from a + * persistent store. + * @param method the HTTP method of the request + * @param uri the URI of the request + * @param headers the request headers + * @param remoteAddress remote address from which the request was sent, if known + * @since 2.1.0 + */ + public Request(String method, URI uri, Map> headers, + String remoteAddress) { + this.method = method; + this.uri = uri; + this.headers = new LinkedHashMap<>(headers); + this.remoteAddress = remoteAddress; } public String getMethod() { @@ -141,8 +182,20 @@ public final class HttpTrace { private final Map> headers; Response(TraceableResponse response) { - this.status = response.getStatus(); - this.headers = response.getHeaders(); + this(response.getStatus(), response.getHeaders()); + } + + /** + * Creates a fully-configured {@code Response} instance. Primarly for use by + * {@link HttpTraceRepository} implementations when recreating a response from a + * persistent store. + * @param status the status of the response + * @param headers the response headers + * @since 2.1.0 + */ + public Response(int status, Map> headers) { + this.status = status; + this.headers = new LinkedHashMap<>(headers); } public int getStatus() { @@ -162,7 +215,12 @@ public final class HttpTrace { private final String id; - private Session(String id) { + /** + * Creates a {@code Session}. + * @param id the session id + * @since 2.1.0 + */ + public Session(String id) { this.id = id; } @@ -179,7 +237,12 @@ public final class HttpTrace { private final String name; - private Principal(String name) { + /** + * Creates a {@code Principal}. + * @param name the name of the principal + * @since 2.1.0 + */ + public Principal(String name) { this.name = name; }