Skip to content

Commit

Permalink
Declare order for ServerHttpObservationFilter WebFilter
Browse files Browse the repository at this point in the history
This commit declares an `@Order` for the `ServerHttpObservationFilter`
bean declaration in the Observation WebFlux auto-configuration.

This allows developers to consistently order other `WebFilter` instances
relatively to this one. Here, `@Order(Ordered.HIGHEST_PRECEDENCE + 1)`
has been chosen to align with the order of its MVC counterpart.

Fixes gh-33444
  • Loading branch information
bclozel committed Dec 19, 2022
1 parent fcf1207 commit 28f9f20
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
Expand Up @@ -42,6 +42,7 @@
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.server.reactive.observation.DefaultServerRequestObservationConvention;
import org.springframework.http.server.reactive.observation.ServerRequestObservationConvention;
Expand Down Expand Up @@ -77,6 +78,7 @@ public WebFluxObservationAutoConfiguration(MetricsProperties metricsProperties,

@Bean
@ConditionalOnMissingBean
@Order(Ordered.HIGHEST_PRECEDENCE + 1)
public ServerHttpObservationFilter webfluxObservationFilter(ObservationRegistry registry,
ObjectProvider<ServerRequestObservationConvention> customConvention,
ObjectProvider<WebFluxTagsProvider> tagConfigurer,
Expand Down
Expand Up @@ -16,11 +16,14 @@

package org.springframework.boot.actuate.autoconfigure.observation.web.reactive;

import java.util.List;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Tags;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import reactor.core.publisher.Mono;

import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun;
Expand All @@ -37,10 +40,14 @@
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.server.reactive.observation.DefaultServerRequestObservationConvention;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.filter.reactive.ServerHttpObservationFilter;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;

import static org.assertj.core.api.Assertions.assertThat;

Expand All @@ -64,6 +71,16 @@ void shouldProvideWebFluxObservationFilter() {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ServerHttpObservationFilter.class));
}

@Test
void shouldProvideWebFluxObservationFilterOrdered() {
this.contextRunner.withBean(FirstWebFilter.class).withBean(ThirdWebFilter.class).run((context) -> {
List<WebFilter> webFilters = context.getBeanProvider(WebFilter.class).orderedStream().toList();
assertThat(webFilters.get(0)).isInstanceOf(FirstWebFilter.class);
assertThat(webFilters.get(1)).isInstanceOf(ServerHttpObservationFilter.class);
assertThat(webFilters.get(2)).isInstanceOf(ThirdWebFilter.class);
});
}

@Test
void shouldUseConventionAdapterWhenCustomTagsProvider() {
this.contextRunner.withUserConfiguration(CustomTagsProviderConfiguration.class).run((context) -> {
Expand Down Expand Up @@ -207,4 +224,24 @@ static class CustomConvention extends DefaultServerRequestObservationConvention

}

@Order(Ordered.HIGHEST_PRECEDENCE)
static class FirstWebFilter implements WebFilter {

@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return chain.filter(exchange);
}

}

@Order(Ordered.HIGHEST_PRECEDENCE + 2)
static class ThirdWebFilter implements WebFilter {

@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return chain.filter(exchange);
}

}

}
Expand Up @@ -207,6 +207,9 @@ When it does so, the orders shown in the following table will be used:
|===
| Web Filter | Order

| `ServerHttpObservationFilter` (Micrometer Observability)
| `Ordered.HIGHEST_PRECEDENCE + 1`

| `WebFilterChainProxy` (Spring Security)
| `-100`

Expand Down

0 comments on commit 28f9f20

Please sign in to comment.