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
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
version=6.0.0-SNAPSHOT
|
||||
version=6.0.0-RC4
|
||||
|
||||
org.gradle.caching=true
|
||||
org.gradle.jvmargs=-Xmx2048m
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
@@ -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;
|
||||
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;
|
||||
@@ -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;
|
||||
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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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
|
||||
|
||||
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());
|
||||
@@ -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;
|
||||
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;
|
||||
@@ -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
|
||||
* @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
|
||||
* <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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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 {
|
||||
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()) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@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 -> {
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
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 {
|
||||
@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 {
|
||||
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 {
|
||||
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 {
|
||||
@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 {
|
||||
@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 {
|
||||
@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 {
|
||||
@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 {
|
||||
@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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 {
|
||||
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 {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user