quarkus: Healthcheck not working with MongoDB (Panache)

Describe the bug

It seems that the healthcheck is not working correctly with the mongodb-client and mongodb-panache(-kotlin) extension.

Given wrong credentials/wrong connection string the healthcheck is still UP until some action, endpoint, etc tries to actively access the database. That action will fail and only then the healthcheck will switch to “DOWN”.

Expected behavior

When querying the (readiness) healthcheck, it should check the database connection and return a negative result if the connection to the mongodb could not be established.

Actual behavior

The (readiness) check returns a positive result although a wrong connection string / wrong credentials are configured

How to Reproduce?

  1. Add mongodb-panache and smallrye-health extensions
  2. Configure a wrong database connection (wrong credentials, wrong string, wrong host)
  3. Start the quarkus application
  4. Access readiness check at http://localhost:8080/q/health/ready

Output of uname -a or ver

Linux pop-os 5.15.11-76051511-generic #202112220937~1640185481~21.10~b3a2c21 SMP Wed Dec 22 15:41:49 U x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

OpenJDK 11.0.13

GraalVM version (if different from Java)

GraalVM CE 21.3.0 (build 11.0.13+7-jvmci-21.3-b05)

Quarkus version or git rev

2.6.2.Final

Build tool (ie. output of mvnw --version or gradlew --version)

6.9

Additional information

No response

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 1
  • Comments: 17 (10 by maintainers)

Most upvoted comments

@loicmathieu maybe we can provide some config option to force eager initialization?

Addendum for the answer by @pschmidt88: It’s sufficient to simply call mongoClient.getDatabase(databaseName) to initialize the mongoClient and with it the health check that properly determines whether the provided credentials (static or dynamic via Vault) are valid. You don’t need to actually run a Mongo command. That’s what the Quarkus MongoHealthCheck does.

This should work

@Startup
@ApplicationScoped
class AppLifecycleBean(
    val mongoClient: MongoClient,
) {
  
    fun pingDatabase(@Observes event: StartupEvent) {
        val databaseName = ConfigProvider.getConfig()
            .getValue("quarkus.mongodb.database", String::class.java)

        mongoClient.getDatabase(databaseName).runCommand(Document("ping", 1))
    }
}

Not directly related but I’m also looking for a way to initialize MongoDB connection pool at start. Lazy initialization mentioned here causes application to serve first requests slow. Doing all sort of things for fast serverless boot time but this hits. Will probably fire some basic query in my custom application health check.

@pschmidt88 unfortunatly, this is by design.

We instantiate MongoDB client lazilly, so when the rediness check is done but no use of the MongoDB client has been done yet, the readiness check will not find any MongoDB client instances inside our CDI container and respond OK.

The MongoDB health check is a readiness check so it’s compatible with the usage of a readiness check (if it was a liveness check, checks should have been done eagerly).

Maybe you can force the intitialization of the MongoDB client using a method listening to the StartupEvent and doing a manyal ping using the MongoDB client, this should do the trick. See https://quarkus.io/guides/lifecycle#listening-for-startup-and-shutdown-events