From 54732605a5c8ec2528854919b2e512332bf88498 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 15 Jul 2025 20:56:36 +0200 Subject: [PATCH] Backport nullability refinements for Micrometer See gh-35170 --- ...ultServerRequestObservationConvention.java | 14 ++++-- ...ultServerRequestObservationConvention.java | 14 ++++-- .../filter/ServerHttpObservationFilter.java | 49 ++++++++++++------- 3 files changed, 49 insertions(+), 28 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/server/observation/DefaultServerRequestObservationConvention.java b/spring-web/src/main/java/org/springframework/http/server/observation/DefaultServerRequestObservationConvention.java index fae5f121e84..49b4f5139a4 100644 --- a/spring-web/src/main/java/org/springframework/http/server/observation/DefaultServerRequestObservationConvention.java +++ b/spring-web/src/main/java/org/springframework/http/server/observation/DefaultServerRequestObservationConvention.java @@ -29,6 +29,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; import org.springframework.http.server.observation.ServerHttpObservationDocumentation.HighCardinalityKeyNames; import org.springframework.http.server.observation.ServerHttpObservationDocumentation.LowCardinalityKeyNames; +import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; /** @@ -89,12 +90,16 @@ public class DefaultServerRequestObservationConvention implements ServerRequestO } @Override + @Nullable public String getContextualName(ServerRequestObservationContext context) { - String httpMethod = context.getCarrier().getMethod().toLowerCase(Locale.ROOT); - if (context.getPathPattern() != null) { - return "http " + httpMethod + " " + context.getPathPattern(); + if (context.getCarrier() != null) { + String httpMethod = context.getCarrier().getMethod().toLowerCase(Locale.ROOT); + if (context.getPathPattern() != null) { + return "http " + httpMethod + " " + context.getPathPattern(); + } + return "http " + httpMethod; } - return "http " + httpMethod; + return null; } @Override @@ -193,7 +198,6 @@ public class DefaultServerRequestObservationConvention implements ServerRequestO return HTTP_OUTCOME_UNKNOWN; } } - } } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/observation/DefaultServerRequestObservationConvention.java b/spring-web/src/main/java/org/springframework/http/server/reactive/observation/DefaultServerRequestObservationConvention.java index 9e3ddb423b1..1b22791f3d3 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/observation/DefaultServerRequestObservationConvention.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/observation/DefaultServerRequestObservationConvention.java @@ -27,6 +27,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; import org.springframework.http.server.reactive.observation.ServerHttpObservationDocumentation.HighCardinalityKeyNames; import org.springframework.http.server.reactive.observation.ServerHttpObservationDocumentation.LowCardinalityKeyNames; +import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; /** @@ -87,12 +88,16 @@ public class DefaultServerRequestObservationConvention implements ServerRequestO } @Override + @Nullable public String getContextualName(ServerRequestObservationContext context) { - String httpMethod = context.getCarrier().getMethod().name().toLowerCase(Locale.ROOT); - if (context.getPathPattern() != null) { - return "http " + httpMethod + " " + context.getPathPattern(); + if (context.getCarrier() != null) { + String httpMethod = context.getCarrier().getMethod().name().toLowerCase(Locale.ROOT); + if (context.getPathPattern() != null) { + return "http " + httpMethod + " " + context.getPathPattern(); + } + return "http " + httpMethod; } - return "http " + httpMethod; + return null; } @Override @@ -191,7 +196,6 @@ public class DefaultServerRequestObservationConvention implements ServerRequestO return HTTP_OUTCOME_UNKNOWN; } } - } } diff --git a/spring-web/src/main/java/org/springframework/web/filter/ServerHttpObservationFilter.java b/spring-web/src/main/java/org/springframework/web/filter/ServerHttpObservationFilter.java index 138407e29c5..db4df4a175a 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/ServerHttpObservationFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/ServerHttpObservationFilter.java @@ -55,19 +55,23 @@ import org.springframework.lang.Nullable; public class ServerHttpObservationFilter extends OncePerRequestFilter { /** - * Name of the request attribute holding the {@link ServerRequestObservationContext context} for the current observation. + * Name of the request attribute holding the {@link ServerRequestObservationContext} for the current observation. */ - public static final String CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE = ServerHttpObservationFilter.class.getName() + ".context"; + public static final String CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE = + ServerHttpObservationFilter.class.getName() + ".context"; - private static final ServerRequestObservationConvention DEFAULT_OBSERVATION_CONVENTION = new DefaultServerRequestObservationConvention(); + private static final String CURRENT_OBSERVATION_ATTRIBUTE = + ServerHttpObservationFilter.class.getName() + ".observation"; - private static final String CURRENT_OBSERVATION_ATTRIBUTE = ServerHttpObservationFilter.class.getName() + ".observation"; + private static final ServerRequestObservationConvention DEFAULT_OBSERVATION_CONVENTION = + new DefaultServerRequestObservationConvention(); private final ObservationRegistry observationRegistry; private final ServerRequestObservationConvention observationConvention; + /** * Create an {@code HttpRequestsObservationFilter} that records observations * against the given {@link ObservationRegistry}. The default @@ -89,14 +93,6 @@ public class ServerHttpObservationFilter extends OncePerRequestFilter { this.observationConvention = observationConvention; } - /** - * Get the current {@link ServerRequestObservationContext observation context} from the given request, if available. - * @param request the current request - * @return the current observation context - */ - public static Optional findObservationContext(HttpServletRequest request) { - return Optional.ofNullable((ServerRequestObservationContext) request.getAttribute(CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE)); - } @Override protected boolean shouldNotFilterAsyncDispatch() { @@ -150,8 +146,9 @@ 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_REQUESTS.observation(this.observationConvention, - DEFAULT_OBSERVATION_CONVENTION, () -> context, this.observationRegistry).start(); + 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()) { request.setAttribute(CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE, observation.getContext()); @@ -160,9 +157,15 @@ public class ServerHttpObservationFilter extends OncePerRequestFilter { return observation; } - @Nullable - static Throwable unwrapServletException(Throwable ex) { - return (ex instanceof ServletException) ? ex.getCause() : ex; + + /** + * Get the current {@link ServerRequestObservationContext observation context} from the given request, if available. + * @param request the current request + * @return the current observation context + */ + public static Optional findObservationContext(HttpServletRequest request) { + return Optional.ofNullable( + (ServerRequestObservationContext) request.getAttribute(CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE)); } @Nullable @@ -170,6 +173,17 @@ public class ServerHttpObservationFilter extends OncePerRequestFilter { return (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION); } + static Throwable unwrapServletException(Throwable ex) { + if (ex instanceof ServletException) { + Throwable cause = ex.getCause(); + if (cause != null) { + return cause; + } + } + return ex; + } + + private static class ObservationAsyncListener implements AsyncListener { private final Observation currentObservation; @@ -197,7 +211,6 @@ public class ServerHttpObservationFilter extends OncePerRequestFilter { public void onError(AsyncEvent event) { this.currentObservation.error(unwrapServletException(event.getThrowable())); } - } }