Browse Source

Expose request id at the ServerHttpRequest level

Hiding it (at AbstractServerHttpRequest) complicates matters since
requests are often mutated and decorated, plus it's also possible to
implement the interface directly (we've one, albeit corner case).

Issue: SPR-16966
pull/1783/head
Rossen Stoyanchev 8 years ago
parent
commit
bc3cf0eeb8
  1. 48
      spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpRequest.java
  2. 10
      spring-web/src/main/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilder.java
  3. 2
      spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpRequest.java
  4. 8
      spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequest.java
  5. 5
      spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequestDecorator.java
  6. 2
      spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java
  7. 9
      spring-web/src/main/java/org/springframework/web/server/adapter/HttpWebHandlerAdapter.java
  8. 12
      spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java

48
spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpRequest.java

@ -64,7 +64,7 @@ public abstract class AbstractServerHttpRequest implements ServerHttpRequest {
private SslInfo sslInfo; private SslInfo sslInfo;
@Nullable @Nullable
private String connectionId; private String id;
@Nullable @Nullable
private String logPrefix; private String logPrefix;
@ -83,6 +83,26 @@ public abstract class AbstractServerHttpRequest implements ServerHttpRequest {
} }
public String getId() {
if (this.id == null) {
this.id = initId();
if (this.id == null) {
this.id = ObjectUtils.getIdentityHexString(this);
}
}
return this.id;
}
/**
* Obtain the request id to use, or {@code null} in which case the Object
* identity of this request instance is used.
* @since 5.1
*/
@Nullable
protected String initId() {
return null;
}
@Override @Override
public URI getURI() { public URI getURI() {
return this.uri; return this.uri;
@ -186,37 +206,13 @@ public abstract class AbstractServerHttpRequest implements ServerHttpRequest {
*/ */
public abstract <T> T getNativeRequest(); public abstract <T> T getNativeRequest();
/**
* Return an id representing the underlying connection, if available, or
* otherwise the identify of the request object.
* @since 5.1
*/
public String getConnectionId() {
if (this.connectionId == null) {
this.connectionId = initConnectionId();
if (this.connectionId == null) {
this.connectionId = ObjectUtils.getIdentityHexString(this);
}
}
return this.connectionId;
}
/**
* Obtain the connection id, if available.
* @since 5.1
*/
@Nullable
protected String initConnectionId() {
return null;
}
/** /**
* For internal use in logging at the HTTP adapter layer. * For internal use in logging at the HTTP adapter layer.
* @since 5.1 * @since 5.1
*/ */
String getLogPrefix() { String getLogPrefix() {
if (this.logPrefix == null) { if (this.logPrefix == null) {
this.logPrefix = "[" + getConnectionId() + "] "; this.logPrefix = "[" + getId() + "] ";
} }
return this.logPrefix; return this.logPrefix;
} }

10
spring-web/src/main/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilder.java

@ -32,7 +32,6 @@ import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
@ -192,8 +191,6 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
private final ServerHttpRequest originalRequest; private final ServerHttpRequest originalRequest;
private final String requestId;
public MutatedServerHttpRequest(URI uri, @Nullable String contextPath, public MutatedServerHttpRequest(URI uri, @Nullable String contextPath,
HttpHeaders headers, String methodValue, MultiValueMap<String, HttpCookie> cookies, HttpHeaders headers, String methodValue, MultiValueMap<String, HttpCookie> cookies,
@ -206,9 +203,6 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
this.sslInfo = sslInfo != null ? sslInfo : originalRequest.getSslInfo(); this.sslInfo = sslInfo != null ? sslInfo : originalRequest.getSslInfo();
this.body = body; this.body = body;
this.originalRequest = originalRequest; this.originalRequest = originalRequest;
this.requestId = originalRequest instanceof AbstractServerHttpRequest ?
((AbstractServerHttpRequest) originalRequest).getConnectionId() :
ObjectUtils.getIdentityHexString(originalRequest);
} }
@Override @Override
@ -245,8 +239,8 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
} }
@Override @Override
public String getConnectionId() { public String getId() {
return this.requestId; return this.originalRequest.getId();
} }
} }

2
spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpRequest.java

@ -176,7 +176,7 @@ class ReactorServerHttpRequest extends AbstractServerHttpRequest {
@Override @Override
@Nullable @Nullable
protected String initConnectionId() { protected String initId() {
return this.request instanceof Connection ? return this.request instanceof Connection ?
((Connection) this.request).channel().id().asShortText() : null; ((Connection) this.request).channel().id().asShortText() : null;
} }

8
spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequest.java

@ -38,6 +38,14 @@ import org.springframework.util.MultiValueMap;
*/ */
public interface ServerHttpRequest extends HttpRequest, ReactiveHttpInputMessage { public interface ServerHttpRequest extends HttpRequest, ReactiveHttpInputMessage {
/**
* Return an id that represents the underlying connection, if available, or
* the request, for the purpose of correlating log messages.
* @since 5.1
* @see org.springframework.web.server.ServerWebExchange#getLogPrefix()
*/
String getId();
/** /**
* Returns a structured representation of the request path including the * Returns a structured representation of the request path including the
* context path + path within application portions, path segments with * context path + path within application portions, path segments with

5
spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequestDecorator.java

@ -55,6 +55,11 @@ public class ServerHttpRequestDecorator implements ServerHttpRequest {
// ServerHttpRequest delegation methods... // ServerHttpRequest delegation methods...
@Override
public String getId() {
return getDelegate().getId();
}
@Override @Override
@Nullable @Nullable
public HttpMethod getMethod() { public HttpMethod getMethod() {

2
spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java

@ -129,7 +129,7 @@ class UndertowServerHttpRequest extends AbstractServerHttpRequest {
} }
@Override @Override
protected String initConnectionId() { protected String initId() {
return ObjectUtils.getIdentityHexString(this.exchange.getConnection()); return ObjectUtils.getIdentityHexString(this.exchange.getConnection());
} }

9
spring-web/src/main/java/org/springframework/web/server/adapter/HttpWebHandlerAdapter.java

@ -29,13 +29,11 @@ import org.springframework.core.NestedExceptionUtils;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.codec.LoggingCodecSupport; import org.springframework.http.codec.LoggingCodecSupport;
import org.springframework.http.codec.ServerCodecConfigurer; import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.http.server.reactive.AbstractServerHttpRequest;
import org.springframework.http.server.reactive.HttpHandler; import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebHandler; import org.springframework.web.server.WebHandler;
@ -216,7 +214,7 @@ public class HttpWebHandlerAdapter extends WebHandlerDecorator implements HttpHa
public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) { public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
ServerWebExchange exchange = createExchange(request, response); ServerWebExchange exchange = createExchange(request, response);
exchange.getAttributes().put(ServerWebExchange.LOG_ID_ATTRIBUTE, initLogId(request)); exchange.getAttributes().put(ServerWebExchange.LOG_ID_ATTRIBUTE, request.getId());
logExchange(exchange); logExchange(exchange);
return getDelegate().handle(exchange) return getDelegate().handle(exchange)
@ -230,11 +228,6 @@ public class HttpWebHandlerAdapter extends WebHandlerDecorator implements HttpHa
getCodecConfigurer(), getLocaleContextResolver(), this.applicationContext); getCodecConfigurer(), getLocaleContextResolver(), this.applicationContext);
} }
private String initLogId(ServerHttpRequest request) {
return request instanceof AbstractServerHttpRequest ?
((AbstractServerHttpRequest) request).getConnectionId() : ObjectUtils.getIdentityHexString(request);
}
private void logExchange(ServerWebExchange exchange) { private void logExchange(ServerWebExchange exchange) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
String logPrefix = exchange.getLogPrefix(); String logPrefix = exchange.getLogPrefix();

12
spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java

@ -178,7 +178,7 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder {
@Override @Override
public ServerRequest build() { public ServerRequest build() {
ServerHttpRequest serverHttpRequest = new BuiltServerHttpRequest( ServerHttpRequest serverHttpRequest = new BuiltServerHttpRequest(this.exchange.getRequest().getId(),
this.methodName, this.uri, this.headers, this.cookies, this.body); this.methodName, this.uri, this.headers, this.cookies, this.body);
ServerWebExchange exchange = new DelegatingServerWebExchange( ServerWebExchange exchange = new DelegatingServerWebExchange(
serverHttpRequest, this.exchange, this.messageReaders); serverHttpRequest, this.exchange, this.messageReaders);
@ -190,6 +190,8 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder {
private static final Pattern QUERY_PATTERN = Pattern.compile("([^&=]+)(=?)([^&]+)?"); private static final Pattern QUERY_PATTERN = Pattern.compile("([^&=]+)(=?)([^&]+)?");
private final String id;
private final String method; private final String method;
private final URI uri; private final URI uri;
@ -204,9 +206,10 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder {
private final Flux<DataBuffer> body; private final Flux<DataBuffer> body;
public BuiltServerHttpRequest(String method, URI uri, HttpHeaders headers, public BuiltServerHttpRequest(String id, String method, URI uri, HttpHeaders headers,
MultiValueMap<String, HttpCookie> cookies, Flux<DataBuffer> body) { MultiValueMap<String, HttpCookie> cookies, Flux<DataBuffer> body) {
this.id = id;
this.method = method; this.method = method;
this.uri = uri; this.uri = uri;
this.path = RequestPath.parse(uri, null); this.path = RequestPath.parse(uri, null);
@ -241,6 +244,11 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder {
return queryParams; return queryParams;
} }
@Override
public String getId() {
return this.id;
}
@Override @Override
public String getMethodValue() { public String getMethodValue() {
return this.method; return this.method;

Loading…
Cancel
Save