GH-9335: Fix MicrometerNodeEnhancer for a primary MeterRegistry bean

Fixes: #9335

Spring Boot provides a `CompositeMeterRegistry` bean marked with a `@Primary`.
So, this one has to be autowired whenever we would like to deal with application
environment.
The `MicrometerNodeEnhancer` has a flaw to skip `MeterRegistry` injection if we have more than one `MeterRegistry` bean.

* Fix `MicrometerNodeEnhancer` logic to use `ObjectProvider.getIfUnique()` API
which is able to deal with the `primary` properly.
Otherwise, `null` as it was before

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
This commit is contained in:
Artem Bilan
2024-07-16 11:14:38 -04:00
parent 09f302cee2
commit e0472d887a
2 changed files with 13 additions and 9 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019-2023 the original author or authors.
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package org.springframework.integration.graph;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import io.micrometer.common.docs.KeyName;
@@ -26,6 +25,7 @@ import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.search.Search;
import io.micrometer.observation.ObservationConvention;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.support.management.IntegrationManagement;
import org.springframework.integration.support.management.observation.DefaultMessageReceiverObservationConvention;
@@ -58,13 +58,8 @@ public class MicrometerNodeEnhancer {
private final MeterRegistry registry;
MicrometerNodeEnhancer(ApplicationContext applicationContext) {
Map<String, MeterRegistry> registries = applicationContext.getBeansOfType(MeterRegistry.class, false, false);
if (registries.size() == 1) {
this.registry = registries.values().iterator().next();
}
else {
this.registry = null;
}
ObjectProvider<MeterRegistry> meterRegistryProvider = applicationContext.getBeanProvider(MeterRegistry.class);
this.registry = meterRegistryProvider.getIfUnique();
}
/**

View File

@@ -39,6 +39,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.context.annotation.Primary;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.integration.annotation.Filter;
import org.springframework.integration.annotation.InboundChannelAdapter;
@@ -80,6 +81,7 @@ import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.mockito.Mockito.mock;
/**
* @author Gary Russell
@@ -296,10 +298,17 @@ public class IntegrationGraphServerTests {
public static class Config {
@Bean
@Primary
public static MeterRegistry meterRegistry() {
return new SimpleMeterRegistry();
}
// To be sure that @Primary one wins for the MicrometerNodeEnhancer
@Bean
public static MeterRegistry mockRegistry() {
return mock();
}
@Bean
public ObservationRegistry observationRegistry(MeterRegistry meterRegistry) {
ObservationRegistry registry = ObservationRegistry.create();