Avoid actuator beans being ineligible for post-processing
Closes gh-33110
This commit is contained in:
@@ -21,10 +21,12 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
|
||||
@@ -67,6 +69,7 @@ import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.http.server.reactive.HttpHandler;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.function.SingletonSupplier;
|
||||
import org.springframework.web.reactive.DispatcherHandler;
|
||||
|
||||
/**
|
||||
@@ -134,8 +137,9 @@ public class WebFluxEndpointManagementContextConfiguration {
|
||||
@ConditionalOnBean(EndpointObjectMapper.class)
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
static ServerCodecConfigurerEndpointObjectMapperBeanPostProcessor serverCodecConfigurerEndpointObjectMapperBeanPostProcessor(
|
||||
EndpointObjectMapper endpointObjectMapper) {
|
||||
return new ServerCodecConfigurerEndpointObjectMapperBeanPostProcessor(endpointObjectMapper);
|
||||
ObjectProvider<EndpointObjectMapper> endpointObjectMapper) {
|
||||
return new ServerCodecConfigurerEndpointObjectMapperBeanPostProcessor(
|
||||
SingletonSupplier.of(endpointObjectMapper::getObject));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,9 +151,10 @@ public class WebFluxEndpointManagementContextConfiguration {
|
||||
private static final List<MediaType> MEDIA_TYPES = Collections
|
||||
.unmodifiableList(Arrays.asList(MediaType.APPLICATION_JSON, new MediaType("application", "*+json")));
|
||||
|
||||
private final EndpointObjectMapper endpointObjectMapper;
|
||||
private final Supplier<EndpointObjectMapper> endpointObjectMapper;
|
||||
|
||||
ServerCodecConfigurerEndpointObjectMapperBeanPostProcessor(EndpointObjectMapper endpointObjectMapper) {
|
||||
ServerCodecConfigurerEndpointObjectMapperBeanPostProcessor(
|
||||
Supplier<EndpointObjectMapper> endpointObjectMapper) {
|
||||
this.endpointObjectMapper = endpointObjectMapper;
|
||||
}
|
||||
|
||||
@@ -173,7 +178,7 @@ public class WebFluxEndpointManagementContextConfiguration {
|
||||
if (encoder instanceof Jackson2JsonEncoder) {
|
||||
Jackson2JsonEncoder jackson2JsonEncoder = (Jackson2JsonEncoder) encoder;
|
||||
jackson2JsonEncoder.registerObjectMappersForType(OperationResponseBody.class, (associations) -> {
|
||||
ObjectMapper objectMapper = this.endpointObjectMapper.get();
|
||||
ObjectMapper objectMapper = this.endpointObjectMapper.get().get();
|
||||
MEDIA_TYPES.forEach((mimeType) -> associations.put(mimeType, objectMapper));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ class MeterRegistryPostProcessor implements BeanPostProcessor, SmartInitializing
|
||||
|
||||
private final boolean hasNoCompositeMeterRegistryBeans;
|
||||
|
||||
private final boolean useGlobalRegistry;
|
||||
private final ObjectProvider<MetricsProperties> properties;
|
||||
|
||||
private final ObjectProvider<MeterRegistryCustomizer<?>> customizers;
|
||||
|
||||
@@ -56,22 +56,21 @@ class MeterRegistryPostProcessor implements BeanPostProcessor, SmartInitializing
|
||||
|
||||
private final Set<MeterRegistry> deferredBindings = new LinkedHashSet<>();
|
||||
|
||||
MeterRegistryPostProcessor(ApplicationContext applicationContext, MetricsProperties metricsProperties,
|
||||
ObjectProvider<MeterRegistryCustomizer<?>> customizers, ObjectProvider<MeterFilter> filters,
|
||||
ObjectProvider<MeterBinder> binders) {
|
||||
this(hasNoCompositeMeterRegistryBeans(applicationContext), metricsProperties.isUseGlobalRegistry(), customizers,
|
||||
filters, binders);
|
||||
MeterRegistryPostProcessor(ApplicationContext applicationContext,
|
||||
ObjectProvider<MetricsProperties> metricsProperties, ObjectProvider<MeterRegistryCustomizer<?>> customizers,
|
||||
ObjectProvider<MeterFilter> filters, ObjectProvider<MeterBinder> binders) {
|
||||
this(hasNoCompositeMeterRegistryBeans(applicationContext), metricsProperties, customizers, filters, binders);
|
||||
}
|
||||
|
||||
private static boolean hasNoCompositeMeterRegistryBeans(ApplicationContext applicationContext) {
|
||||
return applicationContext.getBeanNamesForType(CompositeMeterRegistry.class, false, false).length == 0;
|
||||
}
|
||||
|
||||
MeterRegistryPostProcessor(boolean hasNoCompositeMeterRegistryBeans, boolean useGlobalRegistry,
|
||||
MeterRegistryPostProcessor(boolean hasNoCompositeMeterRegistryBeans, ObjectProvider<MetricsProperties> properties,
|
||||
ObjectProvider<MeterRegistryCustomizer<?>> customizers, ObjectProvider<MeterFilter> filters,
|
||||
ObjectProvider<MeterBinder> binders) {
|
||||
this.hasNoCompositeMeterRegistryBeans = hasNoCompositeMeterRegistryBeans;
|
||||
this.useGlobalRegistry = useGlobalRegistry;
|
||||
this.properties = properties;
|
||||
this.customizers = customizers;
|
||||
this.filters = filters;
|
||||
this.binders = binders;
|
||||
@@ -121,7 +120,7 @@ class MeterRegistryPostProcessor implements BeanPostProcessor, SmartInitializing
|
||||
}
|
||||
|
||||
private void addToGlobalRegistryIfNecessary(MeterRegistry meterRegistry) {
|
||||
if (this.useGlobalRegistry && !isGlobalRegistry(meterRegistry)) {
|
||||
if (this.properties.getObject().isUseGlobalRegistry() && !isGlobalRegistry(meterRegistry)) {
|
||||
Metrics.addRegistry(meterRegistry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,8 @@ public class MetricsAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public static MeterRegistryPostProcessor meterRegistryPostProcessor(ApplicationContext applicationContext,
|
||||
MetricsProperties metricsProperties, ObjectProvider<MeterRegistryCustomizer<?>> meterRegistryCustomizers,
|
||||
ObjectProvider<MetricsProperties> metricsProperties,
|
||||
ObjectProvider<MeterRegistryCustomizer<?>> meterRegistryCustomizers,
|
||||
ObjectProvider<MeterFilter> meterFilters, ObjectProvider<MeterBinder> meterBinders) {
|
||||
return new MeterRegistryPostProcessor(applicationContext, metricsProperties, meterRegistryCustomizers,
|
||||
meterFilters, meterBinders);
|
||||
|
||||
@@ -48,6 +48,8 @@ import static org.mockito.Mockito.mock;
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class MeterRegistryPostProcessorTests {
|
||||
|
||||
private final MetricsProperties properties = new MetricsProperties();
|
||||
|
||||
private List<MeterRegistryCustomizer<?>> customizers = new ArrayList<>();
|
||||
|
||||
private List<MeterFilter> filters = new ArrayList<>();
|
||||
@@ -69,12 +71,16 @@ class MeterRegistryPostProcessorTests {
|
||||
@Mock
|
||||
private Config mockConfig;
|
||||
|
||||
MeterRegistryPostProcessorTests() {
|
||||
this.properties.setUseGlobalRegistry(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
void postProcessAndInitializeWhenCompositeAppliesCustomizer() {
|
||||
this.customizers.add(this.mockCustomizer);
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(false, false,
|
||||
createObjectProvider(this.customizers), createObjectProvider(this.filters),
|
||||
createObjectProvider(this.binders));
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(false,
|
||||
createObjectProvider(this.properties), createObjectProvider(this.customizers),
|
||||
createObjectProvider(this.filters), createObjectProvider(this.binders));
|
||||
CompositeMeterRegistry composite = new CompositeMeterRegistry();
|
||||
postProcessAndInitialize(processor, composite);
|
||||
then(this.mockCustomizer).should().customize(composite);
|
||||
@@ -84,9 +90,9 @@ class MeterRegistryPostProcessorTests {
|
||||
void postProcessAndInitializeAppliesCustomizer() {
|
||||
given(this.mockRegistry.config()).willReturn(this.mockConfig);
|
||||
this.customizers.add(this.mockCustomizer);
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(true, false,
|
||||
createObjectProvider(this.customizers), createObjectProvider(this.filters),
|
||||
createObjectProvider(this.binders));
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(true,
|
||||
createObjectProvider(this.properties), createObjectProvider(this.customizers),
|
||||
createObjectProvider(this.filters), createObjectProvider(this.binders));
|
||||
postProcessAndInitialize(processor, this.mockRegistry);
|
||||
then(this.mockCustomizer).should().customize(this.mockRegistry);
|
||||
}
|
||||
@@ -95,9 +101,9 @@ class MeterRegistryPostProcessorTests {
|
||||
void postProcessAndInitializeAppliesFilter() {
|
||||
given(this.mockRegistry.config()).willReturn(this.mockConfig);
|
||||
this.filters.add(this.mockFilter);
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(true, false,
|
||||
createObjectProvider(this.customizers), createObjectProvider(this.filters),
|
||||
createObjectProvider(this.binders));
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(true,
|
||||
createObjectProvider(this.properties), createObjectProvider(this.customizers),
|
||||
createObjectProvider(this.filters), createObjectProvider(this.binders));
|
||||
postProcessAndInitialize(processor, this.mockRegistry);
|
||||
then(this.mockConfig).should().meterFilter(this.mockFilter);
|
||||
}
|
||||
@@ -106,9 +112,9 @@ class MeterRegistryPostProcessorTests {
|
||||
void postProcessAndInitializeBindsTo() {
|
||||
given(this.mockRegistry.config()).willReturn(this.mockConfig);
|
||||
this.binders.add(this.mockBinder);
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(true, false,
|
||||
createObjectProvider(this.customizers), createObjectProvider(this.filters),
|
||||
createObjectProvider(this.binders));
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(true,
|
||||
createObjectProvider(this.properties), createObjectProvider(this.customizers),
|
||||
createObjectProvider(this.filters), createObjectProvider(this.binders));
|
||||
postProcessAndInitialize(processor, this.mockRegistry);
|
||||
then(this.mockBinder).should().bindTo(this.mockRegistry);
|
||||
}
|
||||
@@ -116,9 +122,9 @@ class MeterRegistryPostProcessorTests {
|
||||
@Test
|
||||
void postProcessAndInitializeWhenCompositeBindsTo() {
|
||||
this.binders.add(this.mockBinder);
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(false, false,
|
||||
createObjectProvider(this.customizers), createObjectProvider(this.filters),
|
||||
createObjectProvider(this.binders));
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(false,
|
||||
createObjectProvider(this.properties), createObjectProvider(this.customizers),
|
||||
createObjectProvider(this.filters), createObjectProvider(this.binders));
|
||||
CompositeMeterRegistry composite = new CompositeMeterRegistry();
|
||||
postProcessAndInitialize(processor, composite);
|
||||
then(this.mockBinder).should().bindTo(composite);
|
||||
@@ -127,8 +133,9 @@ class MeterRegistryPostProcessorTests {
|
||||
@Test
|
||||
void postProcessAndInitializeWhenCompositeExistsDoesNotBindTo() {
|
||||
given(this.mockRegistry.config()).willReturn(this.mockConfig);
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(false, false,
|
||||
createObjectProvider(this.customizers), createObjectProvider(this.filters), null);
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(false,
|
||||
createObjectProvider(this.properties), createObjectProvider(this.customizers),
|
||||
createObjectProvider(this.filters), null);
|
||||
postProcessAndInitialize(processor, this.mockRegistry);
|
||||
then(this.mockBinder).shouldHaveNoInteractions();
|
||||
}
|
||||
@@ -139,9 +146,9 @@ class MeterRegistryPostProcessorTests {
|
||||
this.customizers.add(this.mockCustomizer);
|
||||
this.filters.add(this.mockFilter);
|
||||
this.binders.add(this.mockBinder);
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(true, false,
|
||||
createObjectProvider(this.customizers), createObjectProvider(this.filters),
|
||||
createObjectProvider(this.binders));
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(true,
|
||||
createObjectProvider(this.properties), createObjectProvider(this.customizers),
|
||||
createObjectProvider(this.filters), createObjectProvider(this.binders));
|
||||
postProcessAndInitialize(processor, this.mockRegistry);
|
||||
InOrder ordered = inOrder(this.mockBinder, this.mockConfig, this.mockCustomizer);
|
||||
then(this.mockCustomizer).should(ordered).customize(this.mockRegistry);
|
||||
@@ -152,9 +159,10 @@ class MeterRegistryPostProcessorTests {
|
||||
@Test
|
||||
void postProcessAndInitializeWhenUseGlobalRegistryTrueAddsToGlobalRegistry() {
|
||||
given(this.mockRegistry.config()).willReturn(this.mockConfig);
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(true, true,
|
||||
createObjectProvider(this.customizers), createObjectProvider(this.filters),
|
||||
createObjectProvider(this.binders));
|
||||
this.properties.setUseGlobalRegistry(true);
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(true,
|
||||
createObjectProvider(this.properties), createObjectProvider(this.customizers),
|
||||
createObjectProvider(this.filters), createObjectProvider(this.binders));
|
||||
try {
|
||||
postProcessAndInitialize(processor, this.mockRegistry);
|
||||
assertThat(Metrics.globalRegistry.getRegistries()).contains(this.mockRegistry);
|
||||
@@ -167,9 +175,9 @@ class MeterRegistryPostProcessorTests {
|
||||
@Test
|
||||
void postProcessAndInitializeWhenUseGlobalRegistryFalseDoesNotAddToGlobalRegistry() {
|
||||
given(this.mockRegistry.config()).willReturn(this.mockConfig);
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(true, false,
|
||||
createObjectProvider(this.customizers), createObjectProvider(this.filters),
|
||||
createObjectProvider(this.binders));
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(true,
|
||||
createObjectProvider(this.properties), createObjectProvider(this.customizers),
|
||||
createObjectProvider(this.filters), createObjectProvider(this.binders));
|
||||
postProcessAndInitialize(processor, this.mockRegistry);
|
||||
assertThat(Metrics.globalRegistry.getRegistries()).doesNotContain(this.mockRegistry);
|
||||
}
|
||||
@@ -178,9 +186,9 @@ class MeterRegistryPostProcessorTests {
|
||||
void postProcessDoesNotBindToUntilSingletonsInitialized() {
|
||||
given(this.mockRegistry.config()).willReturn(this.mockConfig);
|
||||
this.binders.add(this.mockBinder);
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(true, false,
|
||||
createObjectProvider(this.customizers), createObjectProvider(this.filters),
|
||||
createObjectProvider(this.binders));
|
||||
MeterRegistryPostProcessor processor = new MeterRegistryPostProcessor(true,
|
||||
createObjectProvider(this.properties), createObjectProvider(this.customizers),
|
||||
createObjectProvider(this.filters), createObjectProvider(this.binders));
|
||||
processor.postProcessAfterInitialization(this.mockRegistry, "meterRegistry");
|
||||
then(this.mockBinder).shouldHaveNoInteractions();
|
||||
processor.afterSingletonsInstantiated();
|
||||
@@ -199,4 +207,11 @@ class MeterRegistryPostProcessorTests {
|
||||
return objectProvider;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> ObjectProvider<T> createObjectProvider(T object) {
|
||||
ObjectProvider<T> objectProvider = mock(ObjectProvider.class);
|
||||
given(objectProvider.getObject()).willReturn(object);
|
||||
return objectProvider;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user