Skip to content

Commit f00a8cb

Browse files
committed
Remove ServerWebExchange dependency in ServerRequestObservationContext
Avoiding cycle between http.server and web.server packages. See gh-30013
1 parent 220995b commit f00a8cb

File tree

7 files changed

+40
-22
lines changed

7 files changed

+40
-22
lines changed

spring-web/src/main/java/org/springframework/http/server/reactive/observation/ServerRequestObservationContext.java

+25-13
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@
2525
import org.springframework.http.server.reactive.ServerHttpRequest;
2626
import org.springframework.http.server.reactive.ServerHttpResponse;
2727
import org.springframework.lang.Nullable;
28-
import org.springframework.web.server.ServerWebExchange;
2928

3029
/**
3130
* Context that holds information for metadata collection regarding
32-
* {@link ServerHttpObservationDocumentation#HTTP_REACTIVE_SERVER_REQUESTS reactive HTTP requests} observations.
31+
* {@link ServerHttpObservationDocumentation#HTTP_REACTIVE_SERVER_REQUESTS reactive HTTP requests}
32+
* observations.
33+
*
3334
* <p>This context also extends {@link RequestReplyReceiverContext} for propagating
3435
* tracing information during HTTP request processing.
3536
*
@@ -39,10 +40,11 @@
3940
public class ServerRequestObservationContext extends RequestReplyReceiverContext<ServerHttpRequest, ServerHttpResponse> {
4041

4142
/**
42-
* Name of the request attribute holding the {@link ServerRequestObservationContext context} for the current observation.
43+
* Name of the request attribute holding the {@link ServerRequestObservationContext context}
44+
* for the current observation.
4345
* @since 6.1
4446
*/
45-
public static final String CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE = ServerRequestObservationContext.class.getName() + ".context";
47+
public static final String CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE = ServerRequestObservationContext.class.getName();
4648

4749

4850
private final Map<String, Object> attributes;
@@ -53,7 +55,15 @@ public class ServerRequestObservationContext extends RequestReplyReceiverContext
5355
private boolean connectionAborted;
5456

5557

56-
public ServerRequestObservationContext(ServerHttpRequest request, ServerHttpResponse response, Map<String, Object> attributes) {
58+
/**
59+
* Create a new {@code ServerRequestObservationContext} instance.
60+
* @param request the current request
61+
* @param response the current response
62+
* @param attributes the current attributes
63+
*/
64+
public ServerRequestObservationContext(
65+
ServerHttpRequest request, ServerHttpResponse response, Map<String, Object> attributes) {
66+
5767
super((req, key) -> req.getHeaders().getFirst(key));
5868
setCarrier(request);
5969
setResponse(response);
@@ -89,8 +99,8 @@ public void setPathPattern(@Nullable String pathPattern) {
8999
}
90100

91101
/**
92-
* Whether the current connection was aborted by the client, resulting
93-
* in a {@link reactor.core.publisher.SignalType#CANCEL cancel signal} on the reactive chain,
102+
* Whether the current connection was aborted by the client, resulting in a
103+
* {@link reactor.core.publisher.SignalType#CANCEL cancel signal} on the reactive chain,
94104
* or an {@code AbortedException} when reading the request.
95105
* @return if the connection has been aborted
96106
*/
@@ -99,8 +109,8 @@ public boolean isConnectionAborted() {
99109
}
100110

101111
/**
102-
* Set whether the current connection was aborted by the client, resulting
103-
* in a {@link reactor.core.publisher.SignalType#CANCEL cancel signal} on the reactive chain,
112+
* Set whether the current connection was aborted by the client, resulting in a
113+
* {@link reactor.core.publisher.SignalType#CANCEL cancel signal} on the reactive chain,
104114
* or an {@code AbortedException} when reading the request.
105115
* @param connectionAborted if the connection has been aborted
106116
*/
@@ -110,13 +120,15 @@ public void setConnectionAborted(boolean connectionAborted) {
110120

111121

112122
/**
113-
* Get the current {@link ServerRequestObservationContext observation context} from the given exchange, if available.
114-
* @param exchange the current exchange
123+
* Get the current {@link ServerRequestObservationContext observation context}
124+
* from the given attributes, if available.
125+
* @param attributes the current exchange attributes
115126
* @return the current observation context
116127
* @since 6.1
117128
*/
118-
public static Optional<ServerRequestObservationContext> findCurrent(ServerWebExchange exchange) {
119-
return Optional.ofNullable(exchange.getAttribute(CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE));
129+
public static Optional<ServerRequestObservationContext> findCurrent(Map<String, Object> attributes) {
130+
return Optional.ofNullable(
131+
(ServerRequestObservationContext) attributes.get(CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE));
120132
}
121133

122134
}

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -296,9 +296,10 @@ public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response)
296296
exchange.getLogPrefix() + formatRequest(exchange.getRequest()) +
297297
(traceOn ? ", headers=" + formatHeaders(exchange.getRequest().getHeaders()) : ""));
298298

299-
ServerRequestObservationContext observationContext = new ServerRequestObservationContext(exchange.getRequest(),
300-
exchange.getResponse(), exchange.getAttributes());
301-
exchange.getAttributes().put(ServerRequestObservationContext.CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE, observationContext);
299+
ServerRequestObservationContext observationContext = new ServerRequestObservationContext(
300+
exchange.getRequest(), exchange.getResponse(), exchange.getAttributes());
301+
exchange.getAttributes().put(
302+
ServerRequestObservationContext.CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE, observationContext);
302303

303304
return getDelegate().handle(exchange)
304305
.transformDeferred(call -> transform(exchange, observationContext, call))

spring-web/src/test/java/org/springframework/web/server/adapter/HttpWebHandlerAdapterObservabilityTests.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class HttpWebHandlerAdapterObservabilityTests {
5151

5252
private final MockServerHttpResponse response = new MockServerHttpResponse();
5353

54+
5455
@Test
5556
void handlerShouldSetObservationContextOnExchange() {
5657
HttpStatusSuccessStubWebHandler targetHandler = new HttpStatusSuccessStubWebHandler(HttpStatus.OK);
@@ -97,6 +98,7 @@ private TestObservationRegistryAssert.TestObservationRegistryAssertReturningObse
9798
.hasObservationWithNameEqualTo("http.server.requests").that();
9899
}
99100

101+
100102
private static class HttpStatusSuccessStubWebHandler implements WebHandler {
101103

102104
private final HttpStatus responseStatus;
@@ -109,12 +111,13 @@ public HttpStatusSuccessStubWebHandler(HttpStatus responseStatus) {
109111

110112
@Override
111113
public Mono<Void> handle(ServerWebExchange exchange) {
112-
this.observationContext = ServerRequestObservationContext.findCurrent(exchange);
114+
this.observationContext = ServerRequestObservationContext.findCurrent(exchange.getAttributes());
113115
exchange.getResponse().setStatusCode(this.responseStatus);
114116
return Mono.empty();
115117
}
116118
}
117119

120+
118121
private static class ReactorContextWebHandler implements WebHandler {
119122

120123
ContextView contextView;
@@ -129,6 +132,7 @@ public Mono<Void> handle(ServerWebExchange exchange) {
129132
}
130133
}
131134

135+
132136
private static class ThrowingExceptionWebHandler implements WebHandler {
133137

134138
private final Throwable exception;
@@ -141,11 +145,12 @@ private ThrowingExceptionWebHandler(Throwable exception) {
141145

142146
@Override
143147
public Mono<Void> handle(ServerWebExchange exchange) {
144-
this.observationContext = ServerRequestObservationContext.findCurrent(exchange);
148+
this.observationContext = ServerRequestObservationContext.findCurrent(exchange.getAttributes());
145149
return Mono.error(this.exception);
146150
}
147151
}
148152

153+
149154
private static class BadRequestExceptionHandler implements WebExceptionHandler {
150155

151156
@Override

spring-webflux/src/main/java/org/springframework/web/reactive/function/server/support/RouterFunctionMapping.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ private void setAttributes(
174174
org.springframework.web.filter.reactive.ServerHttpObservationFilter
175175
.findObservationContext(serverRequest.exchange())
176176
.ifPresent(context -> context.setPathPattern(matchingPattern.toString()));
177-
ServerRequestObservationContext.findCurrent(serverRequest.exchange())
177+
ServerRequestObservationContext.findCurrent(serverRequest.exchange().getAttributes())
178178
.ifPresent(context -> context.setPathPattern(matchingPattern.toString()));
179179
}
180180
Map<String, String> uriVariables =

spring-webflux/src/main/java/org/springframework/web/reactive/handler/AbstractUrlHandlerMapping.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ protected Object lookupHandler(PathContainer lookupPath, ServerWebExchange excha
170170
org.springframework.web.filter.reactive.ServerHttpObservationFilter
171171
.findObservationContext(exchange)
172172
.ifPresent(context -> context.setPathPattern(pattern.toString()));
173-
ServerRequestObservationContext.findCurrent(exchange)
173+
ServerRequestObservationContext.findCurrent(exchange.getAttributes())
174174
.ifPresent(context -> context.setPathPattern(pattern.toString()));
175175
exchange.getAttributes().put(PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, pathWithinMapping);
176176
exchange.getAttributes().put(URI_TEMPLATE_VARIABLES_ATTRIBUTE, matchInfo.getUriVariables());

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ protected void handleMatch(RequestMappingInfo info, HandlerMethod handlerMethod,
145145
org.springframework.web.filter.reactive.ServerHttpObservationFilter
146146
.findObservationContext(exchange)
147147
.ifPresent(context -> context.setPathPattern(bestPattern.toString()));
148-
ServerRequestObservationContext.findCurrent(exchange)
148+
ServerRequestObservationContext.findCurrent(exchange.getAttributes())
149149
.ifPresent(context -> context.setPathPattern(bestPattern.toString()));
150150
exchange.getAttributes().put(URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriVariables);
151151
exchange.getAttributes().put(MATRIX_VARIABLES_ATTRIBUTE, matrixVariables);

spring-webflux/src/test/java/org/springframework/web/reactive/function/server/support/RouterFunctionMappingTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ void mappedRequestShouldHoldAttributes() {
137137
assertThat(matchingPattern.getPatternString()).isEqualTo("/match");
138138
assertThat(org.springframework.web.filter.reactive.ServerHttpObservationFilter.findObservationContext(exchange))
139139
.hasValueSatisfying(context -> assertThat(context.getPathPattern()).isEqualTo(matchingPattern.getPatternString()));
140-
assertThat(ServerRequestObservationContext.findCurrent(exchange))
140+
assertThat(ServerRequestObservationContext.findCurrent(exchange.getAttributes()))
141141
.hasValueSatisfying(context -> assertThat(context.getPathPattern()).isEqualTo(matchingPattern.getPatternString()));
142142

143143
ServerRequest serverRequest = exchange.getAttribute(RouterFunctions.REQUEST_ATTRIBUTE);

0 commit comments

Comments
 (0)