Browse Source

Reorganize server observability packages

Prior to this commit, the server observability support would create a
cycle in Java packages.

This commit refactors the current arrangement to solve this by:

* "flattening" the reactive HTTP instrumentation; this removes the
  dependency to the `ServerWebExchange` and `PathPattern` types
* moving the `observation` package under
  `org.springframework.http.server` and
  `org.springframework.http.server.reactive`

See gh-29477
pull/29492/head
Brian Clozel 2 years ago
parent
commit
1ad7cc3702
  1. 2
      gradle.properties
  2. 6
      spring-web/src/main/java/org/springframework/http/server/observation/DefaultServerRequestObservationConvention.java
  3. 6
      spring-web/src/main/java/org/springframework/http/server/observation/ServerHttpObservationDocumentation.java
  4. 8
      spring-web/src/main/java/org/springframework/http/server/observation/ServerRequestObservationContext.java
  5. 4
      spring-web/src/main/java/org/springframework/http/server/observation/ServerRequestObservationConvention.java
  6. 4
      spring-web/src/main/java/org/springframework/http/server/observation/package-info.java
  7. 13
      spring-web/src/main/java/org/springframework/http/server/reactive/observation/DefaultServerRequestObservationConvention.java
  8. 6
      spring-web/src/main/java/org/springframework/http/server/reactive/observation/ServerHttpObservationDocumentation.java
  9. 37
      spring-web/src/main/java/org/springframework/http/server/reactive/observation/ServerRequestObservationContext.java
  10. 4
      spring-web/src/main/java/org/springframework/http/server/reactive/observation/ServerRequestObservationConvention.java
  11. 4
      spring-web/src/main/java/org/springframework/http/server/reactive/observation/package-info.java
  12. 10
      spring-web/src/main/java/org/springframework/web/filter/ServerHttpObservationFilter.java
  13. 13
      spring-web/src/main/java/org/springframework/web/filter/reactive/ServerHttpObservationFilter.java
  14. 2
      spring-web/src/test/java/org/springframework/http/server/observation/DefaultServerRequestObservationConventionTests.java
  15. 35
      spring-web/src/test/java/org/springframework/http/server/reactive/observation/DefaultServerRequestObservationConventionTests.java
  16. 2
      spring-web/src/test/java/org/springframework/web/filter/ServerHttpObservationFilterTests.java
  17. 2
      spring-web/src/test/java/org/springframework/web/filter/reactive/ServerHttpObservationFilterTests.java
  18. 2
      spring-webflux/src/main/java/org/springframework/web/reactive/function/server/support/RouterFunctionMapping.java
  19. 2
      spring-webflux/src/main/java/org/springframework/web/reactive/handler/AbstractUrlHandlerMapping.java
  20. 2
      spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java
  21. 6
      spring-webflux/src/test/java/org/springframework/web/reactive/function/server/support/RouterFunctionMappingTests.java
  22. 7
      spring-webflux/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java
  23. 2
      spring-webmvc/src/test/java/org/springframework/web/servlet/function/support/RouterFunctionMappingTests.java
  24. 2
      spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java

2
gradle.properties

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
version=6.0.0-SNAPSHOT
version=6.0.0-RC4
org.gradle.caching=true
org.gradle.jvmargs=-Xmx2048m

6
spring-web/src/main/java/org/springframework/http/observation/DefaultServerRequestObservationConvention.java → spring-web/src/main/java/org/springframework/http/server/observation/DefaultServerRequestObservationConvention.java

@ -14,15 +14,15 @@ @@ -14,15 +14,15 @@
* limitations under the License.
*/
package org.springframework.http.observation;
package org.springframework.http.server.observation;
import io.micrometer.common.KeyValue;
import io.micrometer.common.KeyValues;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.observation.ServerHttpObservationDocumentation.HighCardinalityKeyNames;
import org.springframework.http.observation.ServerHttpObservationDocumentation.LowCardinalityKeyNames;
import org.springframework.http.server.observation.ServerHttpObservationDocumentation.HighCardinalityKeyNames;
import org.springframework.http.server.observation.ServerHttpObservationDocumentation.LowCardinalityKeyNames;
import org.springframework.util.StringUtils;
/**

6
spring-web/src/main/java/org/springframework/http/observation/ServerHttpObservationDocumentation.java → spring-web/src/main/java/org/springframework/http/server/observation/ServerHttpObservationDocumentation.java

@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.http.observation;
package org.springframework.http.server.observation;
import io.micrometer.common.KeyValue;
import io.micrometer.common.docs.KeyName;
@ -33,9 +33,9 @@ import io.micrometer.observation.docs.ObservationDocumentation; @@ -33,9 +33,9 @@ import io.micrometer.observation.docs.ObservationDocumentation;
public enum ServerHttpObservationDocumentation implements ObservationDocumentation {
/**
* HTTP exchanges observations for Servlet-based servers.
* HTTP request observations for Servlet-based servers.
*/
HTTP_SERVLET_SERVER_EXCHANGES {
HTTP_SERVLET_SERVER_REQUESTS {
@Override
public Class<? extends ObservationConvention<? extends Observation.Context>> getDefaultConvention() {
return DefaultServerRequestObservationConvention.class;

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

@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.http.observation;
package org.springframework.http.server.observation;
import io.micrometer.observation.transport.RequestReplyReceiverContext;
import jakarta.servlet.http.HttpServletRequest;
@ -23,10 +23,10 @@ import jakarta.servlet.http.HttpServletResponse; @@ -23,10 +23,10 @@ import jakarta.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;
/**
* Context that holds information for metadata collection during observations
* for {@link ServerHttpObservationDocumentation#HTTP_SERVLET_SERVER_EXCHANGES Servlet HTTP exchanges}.
* Context that holds information for metadata collection regarding
* {@link ServerHttpObservationDocumentation#HTTP_SERVLET_SERVER_REQUESTS Servlet HTTP requests} observations.
* <p>This context also extends {@link RequestReplyReceiverContext} for propagating
* tracing information with the HTTP server exchange.
* tracing information during HTTP request processing.
*
* @author Brian Clozel
* @since 6.0

4
spring-web/src/main/java/org/springframework/http/observation/ServerRequestObservationConvention.java → spring-web/src/main/java/org/springframework/http/server/observation/ServerRequestObservationConvention.java

@ -14,13 +14,13 @@ @@ -14,13 +14,13 @@
* limitations under the License.
*/
package org.springframework.http.observation;
package org.springframework.http.server.observation;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationConvention;
/**
* Interface for an {@link ObservationConvention} for {@link ServerHttpObservationDocumentation#HTTP_SERVLET_SERVER_EXCHANGES Servlet HTTP exchanges}.
* Interface for an {@link ObservationConvention} for {@link ServerHttpObservationDocumentation#HTTP_SERVLET_SERVER_REQUESTS Servlet HTTP requests}.
*
* @author Brian Clozel
* @since 6.0

4
spring-web/src/main/java/org/springframework/http/observation/package-info.java → spring-web/src/main/java/org/springframework/http/server/observation/package-info.java

@ -1,9 +1,9 @@ @@ -1,9 +1,9 @@
/**
* Instrumentation for {@link io.micrometer.observation.Observation observing} HTTP applications.
* Instrumentation for {@link io.micrometer.observation.Observation observing} HTTP server applications.
*/
@NonNullApi
@NonNullFields
package org.springframework.http.observation;
package org.springframework.http.server.observation;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;

13
spring-web/src/main/java/org/springframework/http/observation/reactive/DefaultServerRequestObservationConvention.java → spring-web/src/main/java/org/springframework/http/server/reactive/observation/DefaultServerRequestObservationConvention.java

@ -14,17 +14,16 @@ @@ -14,17 +14,16 @@
* limitations under the License.
*/
package org.springframework.http.observation.reactive;
package org.springframework.http.server.reactive.observation;
import io.micrometer.common.KeyValue;
import io.micrometer.common.KeyValues;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.observation.reactive.ServerHttpObservationDocumentation.HighCardinalityKeyNames;
import org.springframework.http.observation.reactive.ServerHttpObservationDocumentation.LowCardinalityKeyNames;
import org.springframework.http.server.reactive.observation.ServerHttpObservationDocumentation.HighCardinalityKeyNames;
import org.springframework.http.server.reactive.observation.ServerHttpObservationDocumentation.LowCardinalityKeyNames;
import org.springframework.util.StringUtils;
import org.springframework.web.util.pattern.PathPattern;
/**
* Default {@link ServerRequestObservationConvention}.
@ -117,12 +116,12 @@ public class DefaultServerRequestObservationConvention implements ServerRequestO @@ -117,12 +116,12 @@ public class DefaultServerRequestObservationConvention implements ServerRequestO
protected KeyValue uri(ServerRequestObservationContext context) {
if (context.getCarrier() != null) {
PathPattern pattern = context.getPathPattern();
String pattern = context.getPathPattern();
if (pattern != null) {
if (pattern.toString().isEmpty()) {
if (pattern.isEmpty()) {
return URI_ROOT;
}
return KeyValue.of(LowCardinalityKeyNames.URI, pattern.toString());
return KeyValue.of(LowCardinalityKeyNames.URI, pattern);
}
if (context.getResponse() != null && context.getResponse().getStatusCode() != null) {
HttpStatus status = HttpStatus.resolve(context.getResponse().getStatusCode().value());

6
spring-web/src/main/java/org/springframework/http/observation/reactive/ServerHttpObservationDocumentation.java → spring-web/src/main/java/org/springframework/http/server/reactive/observation/ServerHttpObservationDocumentation.java

@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.http.observation.reactive;
package org.springframework.http.server.reactive.observation;
import io.micrometer.common.KeyValue;
import io.micrometer.common.docs.KeyName;
@ -33,9 +33,9 @@ import io.micrometer.observation.docs.ObservationDocumentation; @@ -33,9 +33,9 @@ import io.micrometer.observation.docs.ObservationDocumentation;
public enum ServerHttpObservationDocumentation implements ObservationDocumentation {
/**
* HTTP exchanges observations for reactive servers.
* HTTP request observations for reactive servers.
*/
HTTP_REACTIVE_SERVER_EXCHANGES {
HTTP_REACTIVE_SERVER_REQUESTS {
@Override
public Class<? extends ObservationConvention<? extends Observation.Context>> getDefaultConvention() {
return DefaultServerRequestObservationConvention.class;

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

@ -14,46 +14,47 @@ @@ -14,46 +14,47 @@
* limitations under the License.
*/
package org.springframework.http.observation.reactive;
package org.springframework.http.server.reactive.observation;
import java.util.Collections;
import java.util.Map;
import io.micrometer.observation.transport.RequestReplyReceiverContext;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.lang.Nullable;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.pattern.PathPattern;
/**
* Context that holds information for metadata collection during observations
* for {@link ServerHttpObservationDocumentation#HTTP_REACTIVE_SERVER_EXCHANGES reactive HTTP exchanges}.
* Context that holds information for metadata collection regarding
* {@link ServerHttpObservationDocumentation#HTTP_REACTIVE_SERVER_REQUESTS reactive HTTP requests} observations.
* <p>This context also extends {@link RequestReplyReceiverContext} for propagating
* tracing information with the HTTP server exchange.
* tracing information during HTTP request processing.
*
* @author Brian Clozel
* @since 6.0
*/
public class ServerRequestObservationContext extends RequestReplyReceiverContext<ServerHttpRequest, ServerHttpResponse> {
private final ServerWebExchange serverWebExchange;
private final Map<String, Object> attributes;
@Nullable
private PathPattern pathPattern;
private String pathPattern;
private boolean connectionAborted;
public ServerRequestObservationContext(ServerWebExchange exchange) {
super((request, key) -> request.getHeaders().getFirst(key));
this.serverWebExchange = exchange;
setCarrier(exchange.getRequest());
setResponse(exchange.getResponse());
public ServerRequestObservationContext(ServerHttpRequest request, ServerHttpResponse response, Map<String, Object> attributes) {
super((req, key) -> req.getHeaders().getFirst(key));
setCarrier(request);
setResponse(response);
this.attributes = Collections.unmodifiableMap(attributes);
}
/**
* Return the current {@link ServerWebExchange HTTP exchange}.
* Return an immutable map of the current request attributes.
*/
public ServerWebExchange getServerWebExchange() {
return this.serverWebExchange;
public Map<String, Object> getAttributes() {
return this.attributes;
}
/**
@ -63,7 +64,7 @@ public class ServerRequestObservationContext extends RequestReplyReceiverContext @@ -63,7 +64,7 @@ public class ServerRequestObservationContext extends RequestReplyReceiverContext
* @return the path pattern, or {@code null} if none found
*/
@Nullable
public PathPattern getPathPattern() {
public String getPathPattern() {
return this.pathPattern;
}
@ -72,7 +73,7 @@ public class ServerRequestObservationContext extends RequestReplyReceiverContext @@ -72,7 +73,7 @@ public class ServerRequestObservationContext extends RequestReplyReceiverContext
* <p>Path patterns must have a low cardinality for the entire application.
* @param pathPattern the path pattern, for example {@code "/projects/{name}"}.
*/
public void setPathPattern(@Nullable PathPattern pathPattern) {
public void setPathPattern(@Nullable String pathPattern) {
this.pathPattern = pathPattern;
}

4
spring-web/src/main/java/org/springframework/http/observation/reactive/ServerRequestObservationConvention.java → spring-web/src/main/java/org/springframework/http/server/reactive/observation/ServerRequestObservationConvention.java

@ -14,13 +14,13 @@ @@ -14,13 +14,13 @@
* limitations under the License.
*/
package org.springframework.http.observation.reactive;
package org.springframework.http.server.reactive.observation;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationConvention;
/**
* Interface for an {@link ObservationConvention} for {@link ServerHttpObservationDocumentation#HTTP_REACTIVE_SERVER_EXCHANGES reactive HTTP exchanges}.
* Interface for an {@link ObservationConvention} for {@link ServerHttpObservationDocumentation#HTTP_REACTIVE_SERVER_REQUESTS reactive HTTP requests}.
*
* @author Brian Clozel
* @since 6.0

4
spring-web/src/main/java/org/springframework/http/observation/reactive/package-info.java → spring-web/src/main/java/org/springframework/http/server/reactive/observation/package-info.java

@ -1,9 +1,9 @@ @@ -1,9 +1,9 @@
/**
* Instrumentation for {@link io.micrometer.observation.Observation observing} reactive HTTP applications.
* Instrumentation for {@link io.micrometer.observation.Observation observing} reactive HTTP server applications.
*/
@NonNullApi
@NonNullFields
package org.springframework.http.observation.reactive;
package org.springframework.http.server.reactive.observation;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;

10
spring-web/src/main/java/org/springframework/web/filter/ServerHttpObservationFilter.java

@ -27,10 +27,10 @@ import jakarta.servlet.ServletException; @@ -27,10 +27,10 @@ import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.observation.DefaultServerRequestObservationConvention;
import org.springframework.http.observation.ServerHttpObservationDocumentation;
import org.springframework.http.observation.ServerRequestObservationContext;
import org.springframework.http.observation.ServerRequestObservationConvention;
import org.springframework.http.server.observation.DefaultServerRequestObservationConvention;
import org.springframework.http.server.observation.ServerHttpObservationDocumentation;
import org.springframework.http.server.observation.ServerRequestObservationContext;
import org.springframework.http.server.observation.ServerRequestObservationConvention;
import org.springframework.lang.Nullable;
@ -127,7 +127,7 @@ public class ServerHttpObservationFilter extends OncePerRequestFilter { @@ -127,7 +127,7 @@ public class ServerHttpObservationFilter extends OncePerRequestFilter {
Observation observation = (Observation) request.getAttribute(CURRENT_OBSERVATION_ATTRIBUTE);
if (observation == null) {
ServerRequestObservationContext context = new ServerRequestObservationContext(request, response);
observation = ServerHttpObservationDocumentation.HTTP_SERVLET_SERVER_EXCHANGES.observation(this.observationConvention,
observation = ServerHttpObservationDocumentation.HTTP_SERVLET_SERVER_REQUESTS.observation(this.observationConvention,
DEFAULT_OBSERVATION_CONVENTION, () -> context, this.observationRegistry).start();
request.setAttribute(CURRENT_OBSERVATION_ATTRIBUTE, observation);
if (!observation.isNoop()) {

13
spring-web/src/main/java/org/springframework/web/filter/reactive/ServerHttpObservationFilter.java

@ -25,11 +25,11 @@ import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccess @@ -25,11 +25,11 @@ import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccess
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;
import org.springframework.http.observation.reactive.DefaultServerRequestObservationConvention;
import org.springframework.http.observation.reactive.ServerHttpObservationDocumentation;
import org.springframework.http.observation.reactive.ServerRequestObservationContext;
import org.springframework.http.observation.reactive.ServerRequestObservationConvention;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.observation.DefaultServerRequestObservationConvention;
import org.springframework.http.server.reactive.observation.ServerHttpObservationDocumentation;
import org.springframework.http.server.reactive.observation.ServerRequestObservationContext;
import org.springframework.http.server.reactive.observation.ServerRequestObservationConvention;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
@ -96,13 +96,14 @@ public class ServerHttpObservationFilter implements WebFilter { @@ -96,13 +96,14 @@ public class ServerHttpObservationFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
ServerRequestObservationContext observationContext = new ServerRequestObservationContext(exchange);
ServerRequestObservationContext observationContext = new ServerRequestObservationContext(exchange.getRequest(),
exchange.getResponse(), exchange.getAttributes());
exchange.getAttributes().put(CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE, observationContext);
return chain.filter(exchange).transformDeferred(call -> filter(exchange, observationContext, call));
}
private Publisher<Void> filter(ServerWebExchange exchange, ServerRequestObservationContext observationContext, Mono<Void> call) {
Observation observation = ServerHttpObservationDocumentation.HTTP_REACTIVE_SERVER_EXCHANGES.observation(this.observationConvention,
Observation observation = ServerHttpObservationDocumentation.HTTP_REACTIVE_SERVER_REQUESTS.observation(this.observationConvention,
DEFAULT_OBSERVATION_CONVENTION, () -> observationContext, this.observationRegistry);
observation.start();
return call.doOnEach(signal -> {

2
spring-web/src/test/java/org/springframework/http/observation/DefaultServerRequestObservationConventionTests.java → spring-web/src/test/java/org/springframework/http/server/observation/DefaultServerRequestObservationConventionTests.java

@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.http.observation;
package org.springframework.http.server.observation;
import io.micrometer.common.KeyValue;
import io.micrometer.observation.Observation;

35
spring-web/src/test/java/org/springframework/http/observation/reactive/DefaultServerRequestObservationConventionTests.java → spring-web/src/test/java/org/springframework/http/server/reactive/observation/DefaultServerRequestObservationConventionTests.java

@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.http.observation.reactive;
package org.springframework.http.server.reactive.observation;
import io.micrometer.common.KeyValue;
import io.micrometer.observation.Observation;
@ -23,13 +23,12 @@ import org.junit.jupiter.api.Test; @@ -23,13 +23,12 @@ import org.junit.jupiter.api.Test;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.testfixture.http.server.reactive.MockServerHttpRequest;
import org.springframework.web.testfixture.server.MockServerWebExchange;
import org.springframework.web.util.pattern.PathPattern;
import org.springframework.web.util.pattern.PathPatternParser;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link DefaultServerRequestObservationConvention}.
*
* @author Brian Clozel
*/
class DefaultServerRequestObservationConventionTests {
@ -45,22 +44,22 @@ class DefaultServerRequestObservationConventionTests { @@ -45,22 +44,22 @@ class DefaultServerRequestObservationConventionTests {
@Test
void shouldHaveContextualName() {
ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/test/resource"));
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange);
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange.getRequest(), exchange.getResponse(), exchange.getAttributes());
assertThat(convention.getContextualName(context)).isEqualTo("http get");
}
@Test
void contextualNameShouldUsePathPatternWhenAvailable() {
ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/test/resource"));
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange);
context.setPathPattern(PathPatternParser.defaultInstance.parse("/test/{name}"));
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange.getRequest(), exchange.getResponse(), exchange.getAttributes());
context.setPathPattern("/test/{name}");
assertThat(convention.getContextualName(context)).isEqualTo("http get /test/{name}");
}
@Test
void supportsOnlyHttpRequestsObservationContext() {
ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.post("/test/resource"));
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange);
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange.getRequest(), exchange.getResponse(), exchange.getAttributes());
assertThat(this.convention.supportsContext(context)).isTrue();
assertThat(this.convention.supportsContext(new Observation.Context())).isFalse();
}
@ -69,7 +68,7 @@ class DefaultServerRequestObservationConventionTests { @@ -69,7 +68,7 @@ class DefaultServerRequestObservationConventionTests {
void addsKeyValuesForExchange() {
ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.post("/test/resource"));
exchange.getResponse().setRawStatusCode(201);
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange);
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange.getRequest(), exchange.getResponse(), exchange.getAttributes());
assertThat(this.convention.getLowCardinalityKeyValues(context)).hasSize(5)
.contains(KeyValue.of("method", "POST"), KeyValue.of("uri", "UNKNOWN"), KeyValue.of("status", "201"),
@ -82,9 +81,8 @@ class DefaultServerRequestObservationConventionTests { @@ -82,9 +81,8 @@ class DefaultServerRequestObservationConventionTests {
void addsKeyValuesForExchangeWithPathPattern() {
ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/test/resource"));
exchange.getResponse().setRawStatusCode(200);
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange);
PathPattern pathPattern = getPathPattern("/test/{name}");
context.setPathPattern(pathPattern);
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange.getRequest(), exchange.getResponse(), exchange.getAttributes());
context.setPathPattern("/test/{name}");
assertThat(this.convention.getLowCardinalityKeyValues(context)).hasSize(5)
.contains(KeyValue.of("method", "GET"), KeyValue.of("uri", "/test/{name}"), KeyValue.of("status", "200"),
@ -97,7 +95,7 @@ class DefaultServerRequestObservationConventionTests { @@ -97,7 +95,7 @@ class DefaultServerRequestObservationConventionTests {
@Test
void addsKeyValuesForErrorExchange() {
ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/test/resource"));
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange);
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange.getRequest(), exchange.getResponse(), exchange.getAttributes());
context.setError(new IllegalArgumentException("custom error"));
exchange.getResponse().setRawStatusCode(500);
@ -111,7 +109,7 @@ class DefaultServerRequestObservationConventionTests { @@ -111,7 +109,7 @@ class DefaultServerRequestObservationConventionTests {
@Test
void addsKeyValuesForRedirectExchange() {
ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/test/redirect"));
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange);
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange.getRequest(), exchange.getResponse(), exchange.getAttributes());
exchange.getResponse().setRawStatusCode(302);
exchange.getResponse().getHeaders().add("Location", "https://example.org/other");
@ -125,7 +123,7 @@ class DefaultServerRequestObservationConventionTests { @@ -125,7 +123,7 @@ class DefaultServerRequestObservationConventionTests {
@Test
void addsKeyValuesForNotFoundExchange() {
ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/test/notFound"));
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange);
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange.getRequest(), exchange.getResponse(), exchange.getAttributes());
exchange.getResponse().setRawStatusCode(404);
assertThat(this.convention.getLowCardinalityKeyValues(context)).hasSize(5)
@ -138,7 +136,7 @@ class DefaultServerRequestObservationConventionTests { @@ -138,7 +136,7 @@ class DefaultServerRequestObservationConventionTests {
@Test
void addsKeyValuesForCancelledExchange() {
ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/test/resource"));
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange);
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange.getRequest(), exchange.getResponse(), exchange.getAttributes());
context.setConnectionAborted(true);
exchange.getResponse().setRawStatusCode(200);
@ -152,16 +150,11 @@ class DefaultServerRequestObservationConventionTests { @@ -152,16 +150,11 @@ class DefaultServerRequestObservationConventionTests {
@Test
void supportsNullStatusCode() {
ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/test/resource"));
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange);
ServerRequestObservationContext context = new ServerRequestObservationContext(exchange.getRequest(), exchange.getResponse(), exchange.getAttributes());
assertThat(this.convention.getLowCardinalityKeyValues(context))
.contains(KeyValue.of("status", "UNKNOWN"),
KeyValue.of("exception", "none"), KeyValue.of("outcome", "UNKNOWN"));
}
private static PathPattern getPathPattern(String pattern) {
PathPatternParser pathPatternParser = new PathPatternParser();
return pathPatternParser.parse(pattern);
}
}

2
spring-web/src/test/java/org/springframework/web/filter/ServerHttpObservationFilterTests.java

@ -24,7 +24,7 @@ import jakarta.servlet.ServletException; @@ -24,7 +24,7 @@ import jakarta.servlet.ServletException;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpMethod;
import org.springframework.http.observation.ServerRequestObservationContext;
import org.springframework.http.server.observation.ServerRequestObservationContext;
import org.springframework.web.testfixture.servlet.MockFilterChain;
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
import org.springframework.web.testfixture.servlet.MockHttpServletResponse;

2
spring-web/src/test/java/org/springframework/web/filter/reactive/ServerHttpObservationFilterTests.java

@ -27,7 +27,7 @@ import org.junit.jupiter.api.Test; @@ -27,7 +27,7 @@ import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import org.springframework.http.observation.reactive.ServerRequestObservationContext;
import org.springframework.http.server.reactive.observation.ServerRequestObservationContext;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import org.springframework.web.testfixture.http.server.reactive.MockServerHttpRequest;

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

@ -172,7 +172,7 @@ public class RouterFunctionMapping extends AbstractHandlerMapping implements Ini @@ -172,7 +172,7 @@ public class RouterFunctionMapping extends AbstractHandlerMapping implements Ini
if (matchingPattern != null) {
attributes.put(BEST_MATCHING_PATTERN_ATTRIBUTE, matchingPattern);
ServerHttpObservationFilter.findObservationContext(serverRequest.exchange())
.ifPresent(context -> context.setPathPattern(matchingPattern));
.ifPresent(context -> context.setPathPattern(matchingPattern.toString()));
}
Map<String, String> uriVariables =
(Map<String, String>) attributes.get(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE);

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

@ -167,7 +167,7 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping { @@ -167,7 +167,7 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping {
exchange.getAttributes().put(BEST_MATCHING_HANDLER_ATTRIBUTE, handler);
exchange.getAttributes().put(BEST_MATCHING_PATTERN_ATTRIBUTE, pattern);
ServerHttpObservationFilter.findObservationContext(exchange)
.ifPresent(context -> context.setPathPattern(pattern));
.ifPresent(context -> context.setPathPattern(pattern.toString()));
exchange.getAttributes().put(PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, pathWithinMapping);
exchange.getAttributes().put(URI_TEMPLATE_VARIABLES_ATTRIBUTE, matchInfo.getUriVariables());

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

@ -141,7 +141,7 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe @@ -141,7 +141,7 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
exchange.getAttributes().put(BEST_MATCHING_HANDLER_ATTRIBUTE, handlerMethod);
exchange.getAttributes().put(BEST_MATCHING_PATTERN_ATTRIBUTE, bestPattern);
ServerHttpObservationFilter.findObservationContext(exchange)
.ifPresent(context -> context.setPathPattern(bestPattern));
.ifPresent(context -> context.setPathPattern(bestPattern.toString()));
exchange.getAttributes().put(URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriVariables);
exchange.getAttributes().put(MATRIX_VARIABLES_ATTRIBUTE, matrixVariables);

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

@ -22,7 +22,7 @@ import reactor.test.StepVerifier; @@ -22,7 +22,7 @@ import reactor.test.StepVerifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.http.observation.reactive.ServerRequestObservationContext;
import org.springframework.http.server.reactive.observation.ServerRequestObservationContext;
import org.springframework.web.filter.reactive.ServerHttpObservationFilter;
import org.springframework.web.reactive.HandlerMapping;
import org.springframework.web.reactive.function.server.HandlerFunction;
@ -137,7 +137,7 @@ class RouterFunctionMappingTests { @@ -137,7 +137,7 @@ class RouterFunctionMappingTests {
assertThat(matchingPattern).isNotNull();
assertThat(matchingPattern.getPatternString()).isEqualTo("/match");
assertThat(ServerHttpObservationFilter.findObservationContext(exchange))
.hasValueSatisfying(context -> assertThat(context.getPathPattern()).isEqualTo(matchingPattern));
.hasValueSatisfying(context -> assertThat(context.getPathPattern()).isEqualTo(matchingPattern.getPatternString()));
ServerRequest serverRequest = exchange.getAttribute(RouterFunctions.REQUEST_ATTRIBUTE);
assertThat(serverRequest).isNotNull();
@ -148,7 +148,7 @@ class RouterFunctionMappingTests { @@ -148,7 +148,7 @@ class RouterFunctionMappingTests {
private ServerWebExchange createExchange(String urlTemplate) {
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get(urlTemplate));
ServerRequestObservationContext observationContext = new ServerRequestObservationContext(exchange);
ServerRequestObservationContext observationContext = new ServerRequestObservationContext(exchange.getRequest(), exchange.getResponse(), exchange.getAttributes());
exchange.getAttributes().put(CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE, observationContext);
return exchange;
}

7
spring-webflux/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java

@ -36,7 +36,7 @@ import org.springframework.core.annotation.AnnotationUtils; @@ -36,7 +36,7 @@ import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.observation.reactive.ServerRequestObservationContext;
import org.springframework.http.server.reactive.observation.ServerRequestObservationContext;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Controller;
import org.springframework.util.ClassUtils;
@ -263,12 +263,11 @@ public class RequestMappingInfoHandlerMappingTests { @@ -263,12 +263,11 @@ public class RequestMappingInfoHandlerMappingTests {
public void handleMatchBestMatchingPatternAttributeInObservationContext() {
RequestMappingInfo key = paths("/{path1}/2", "/**").build();
ServerWebExchange exchange = MockServerWebExchange.from(get("/1/2"));
ServerRequestObservationContext observationContext = new ServerRequestObservationContext(exchange);
ServerRequestObservationContext observationContext = new ServerRequestObservationContext(exchange.getRequest(), exchange.getResponse(), exchange.getAttributes());
exchange.getAttributes().put(CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE, observationContext);
this.handlerMapping.handleMatch(key, handlerMethod, exchange);
assertThat(observationContext.getPathPattern()).isNotNull();
assertThat(observationContext.getPathPattern().toString()).isEqualTo("/{path1}/2");
assertThat(observationContext.getPathPattern()).isEqualTo("/{path1}/2");
}
@Test // gh-22543

2
spring-webmvc/src/test/java/org/springframework/web/servlet/function/support/RouterFunctionMappingTests.java

@ -26,7 +26,7 @@ import org.junit.jupiter.params.provider.ValueSource; @@ -26,7 +26,7 @@ import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.observation.ServerRequestObservationContext;
import org.springframework.http.server.observation.ServerRequestObservationContext;
import org.springframework.web.filter.ServerHttpObservationFilter;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerMapping;

2
spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java

@ -33,8 +33,8 @@ import org.springframework.core.annotation.AnnotationUtils; @@ -33,8 +33,8 @@ import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.observation.ServerRequestObservationContext;
import org.springframework.http.server.RequestPath;
import org.springframework.http.server.observation.ServerRequestObservationContext;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Controller;
import org.springframework.util.MultiValueMap;

Loading…
Cancel
Save