Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dependency cycle when Use my own ConsulServiceRegistry with spring-boot-starter-actuator #831

Open
c1emon opened this issue Oct 11, 2023 · 3 comments

Comments

@c1emon
Copy link

c1emon commented Oct 11, 2023

When consul set with discovery.heartbeat.enabled=true and spring-boot-starter-actuator's health endpoint enabled.

At same time, spring-boot-starter-data-mongodb also added. Use my own ConsulServiceRegistry.

Startup and comes with dependency cycle for consul's TtlScheduler!
Here is my example with logs, spring_consul_err.

@ghimisradu
Copy link

I'm having the same issue, but without overriding anything from consul, just having spring-cloud-starter-consul-discovery, spring-boot-starter-actuator and spring-boot-starter-data-mongodb-reactive on the same classpath and enabling the spring.cloud.consul.discovery.heartbeat.enabled=true.
Here's a reproduction project

@gc-garcol
Copy link

in heartbeat, set use-actuator-health to false

        heartbeat:
            use-actuator-health: false
            enabled: true

You can check the ConsulHeartbeatAutoConfiguration to find out the issue

@ConditionalOnProperty(value = "spring.cloud.consul.discovery.heartbeat.use-actuator-health", havingValue = "true",
			matchIfMissing = true)
	static class ActuatorBasedApplicationStatusProviderConfig

@chillb0nes
Copy link

Startup and comes with dependency cycle for consul's TtlScheduler! Here is my example with logs, spring_consul_err.

Copying the cycle here for clarity

***************************
APPLICATION FAILED TO START
***************************

Description:

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

   stationController defined in file [/Users/clemon/Downloads/demo/build/classes/java/main/com/example/demo/station/StationController.class]
┌─────┐
|  mongoTemplate defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.class]
↑     ↓
|  mappingMongoConverter defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.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]
↑     ↓
|  commonConsulServiceRegistry defined in class path resource [com/example/demo/consul/CommonConsulAutoConfiguration.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/MongoHealthContributorAutoConfiguration.class]
└─────┘

Here is my analysis:

  • mongoMappingContext is a InitializingBean
  • During initialization it produces MappingContextEvents (which is subtype of ApplicationEvent)
  • consulAutoServiceRegistrationListener is a SmartApplicationListener
  • SmartApplicationListener extends ApplicationListener<ApplicationEvent>
  • So it is necessary to create consulAutoServiceRegistrationListener to handle events from mongoMappingContext, thus cycle appears

WebServerInitializedEvent is the only event type that consulAutoServiceRegistrationListener can process, so It should be enough to explicitly declare it in bean definiton to fix this issue. Either by changing implements SmartApplicationListener to implements ApplicationListener<WebServerInitializedEvent> or annotating onApplicationEvent method with @EventListener(WebServerInitializedEvent.class).

Unfortunately I don't have time to test this hypothesis, but I would be glad if someone could do it and submit a PR if everything works fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants