spring-cloud / spring-cloud-consul

Spring Cloud Consul
http://cloud.spring.io/spring-cloud-consul/
Apache License 2.0
813 stars 541 forks source link

Circular dependencies between consul and mongodb health contributor #837

Open ghimisradu opened 5 months ago

ghimisradu commented 5 months ago

Description If consul heartbeat it's configured to use actuator health(the default configuration) and we have some mongo repositories on classpath a circular dependency it's created between them:

The dependencies of some of the beans in the application context form a cycle:

   apiController (field private com.sample.service.ReactiveAutenticationService com.sample.controller.ApiController.reactiveAutenticationService)
      ↓
   reactiveAuthenticationServiceImpl (field private com.sample.repository.AccountRepository com.sample.service.ReactiveAuthenticationServiceImpl.accountRepository)
      ↓
   accountRepository defined in com.sample.repository.AccountRepository defined in @EnableReactiveMongoRepositories declared on ApplicationEntryPoint
┌─────┐
|  reactiveMongoTemplate defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.class]
↑     ↓
|  mappingMongoConverter defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.class]
↑     ↓
|  mongoMappingContext defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDataConfiguration.class]
↑     ↓
|  consulAutoServiceRegistrationListener defined in class path resource [org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationAutoConfiguration.class]
↑     ↓
|  consulAutoServiceRegistration defined in class path resource [org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationAutoConfiguration.class]
↑     ↓
|  consulServiceRegistry defined in class path resource [org/springframework/cloud/consul/serviceregistry/ConsulServiceRegistryAutoConfiguration.class]
↑     ↓
|  ttlScheduler defined in class path resource [org/springframework/cloud/consul/support/ConsulHeartbeatAutoConfiguration.class]
↑     ↓
|  actuatorHealthStatusProvider defined in class path resource [org/springframework/cloud/consul/support/ConsulHeartbeatAutoConfiguration$ActuatorBasedApplicationStatusProviderConfig.class]
↑     ↓
|  healthEndpoint defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.class]
↑     ↓
|  healthContributorRegistry defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.class]
↑     ↓
|  mongoHealthContributor defined in class path resource [org/springframework/boot/actuate/autoconfigure/data/mongo/MongoReactiveHealthContributorAutoConfiguration.class]
└─────┘

If spring.cloud.consul.discovery.heartbeat.use-actuator-health it's set to false then the dependency chain it's broken and everything works.

Sample Please check the repository here

Versions Spring boot: 3.1.5 Spring cloud: 2022.0.4 Java: 17

iromu commented 4 months ago

Another "solution" is to remove the Mongo health configuraiton. e.g.: when using spring-boot-starter-data-mongodb-reactive

@SpringBootApplication(exclude = MongoReactiveHealthContributorAutoConfiguration.class) public class MongoStorageApplication