liquibase / liquibase-gradle-plugin

A Gradle plugin for Liquibase
Other
197 stars 57 forks source link

Error while connection to a Google Cloud SQL instance (requires a secure socket) #109

Closed luisospina-sealed closed 1 year ago

luisospina-sealed commented 1 year ago

I'm trying to use the plugin to perform the migrations using liquibase against a Postgres DB inside Google Cloud (Google cloud SQL instance). This connection requires to setup a secure socket which is provided by Gradle dependency com.google.cloud.sql:postgres-socket-factory:1.7.0

I'm able to connect to the DB using my application, but when trying to use liquibase plugin the following error occurs:

 liquibase.exception.CommandExecutionException: liquibase.exception.LiquibaseException: Unexpected error running Liquibase: liquibase.exception.DatabaseException: liquibase.exception.DatabaseException: Connection could not be created to jdbc:postgresql:///db-name?cloudSqlInstance=project:region:db&socketFactory=com.google.cloud.sql.postgres.SocketFactory with driver org.postgresql.Driver.  Something unusual has occurred to cause the driver to fail. Please report this exception.
    at liquibase.command.CommandScope.execute(CommandScope.java:153)
    at liquibase.integration.commandline.CommandRunner.call(CommandRunner.java:45)
    at liquibase.integration.commandline.CommandRunner.call(CommandRunner.java:15)
    at picocli.CommandLine.executeUserObject(CommandLine.java:1953)
    at picocli.CommandLine.access$1300(CommandLine.java:145)
    at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2358)
    at picocli.CommandLine$RunLast.handle(CommandLine.java:2352)
    at picocli.CommandLine$RunLast.handle(CommandLine.java:2314)
    at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2179)
    at picocli.CommandLine$RunLast.execute(CommandLine.java:2316)
    at picocli.CommandLine.execute(CommandLine.java:2078)
    at liquibase.integration.commandline.LiquibaseCommandLine.lambda$execute$1(LiquibaseCommandLine.java:315)
    at liquibase.Scope.child(Scope.java:186)
    at liquibase.Scope.child(Scope.java:162)
    at liquibase.integration.commandline.LiquibaseCommandLine.execute(LiquibaseCommandLine.java:287)
    at liquibase.integration.commandline.LiquibaseCommandLine.main(LiquibaseCommandLine.java:81)
Caused by: liquibase.exception.LiquibaseException: Unexpected error running Liquibase: liquibase.exception.DatabaseException: liquibase.exception.DatabaseException: Connection could not be created to jdbc:postgresql:///db-name?cloudSqlInstance=project:region:db&socketFactory=com.google.cloud.sql.postgres.SocketFactory  with driver org.postgresql.Driver.  Something unusual has occurred to cause the driver to fail. Please report this exception.
    at liquibase.integration.commandline.Main$1.run(Main.java:447)
    at liquibase.integration.commandline.Main$1.run(Main.java:225)
    at liquibase.Scope.child(Scope.java:186)
    at liquibase.Scope.child(Scope.java:162)
    at liquibase.integration.commandline.Main.run(Main.java:225)
    at liquibase.command.AbstractCliWrapperCommandStep.run(AbstractCliWrapperCommandStep.java:32)
    at liquibase.command.CommandScope.execute(CommandScope.java:147)
    ... 15 more
Caused by: liquibase.exception.DatabaseException: liquibase.exception.DatabaseException: liquibase.exception.DatabaseException: liquibase.exception.DatabaseException: Connection could not be created to jdbc:postgresql:///db-name?cloudSqlInstance=project:region:db&socketFactory=com.google.cloud.sql.postgres.SocketFactory  with driver org.postgresql.Driver.  Something unusual has occurred to cause the driver to fail. Please report this exception.
    at liquibase.integration.commandline.CommandLineUtils.createDatabaseObject(CommandLineUtils.java:125)
    at liquibase.integration.commandline.Main.doMigration(Main.java:1523)
    at liquibase.integration.commandline.Main$1.lambda$run$0(Main.java:402)
    at liquibase.Scope.lambda$child$0(Scope.java:177)
    at liquibase.Scope.child(Scope.java:186)
    at liquibase.Scope.child(Scope.java:176)
    at liquibase.Scope.child(Scope.java:155)
    at liquibase.integration.commandline.Main$1.run(Main.java:401)
    ... 21 more
Caused by: liquibase.exception.DatabaseException: liquibase.exception.DatabaseException: liquibase.exception.DatabaseException: Connection could not be created to jdbc:postgresql:///db-name?cloudSqlInstance=project:region:db&socketFactory=com.google.cloud.sql.postgres.SocketFactory  with driver org.postgresql.Driver.  Something unusual has occurred to cause the driver to fail. Please report this exception.
    at liquibase.database.DatabaseFactory.openConnection(DatabaseFactory.java:217)
    at liquibase.database.DatabaseFactory.openConnection(DatabaseFactory.java:176)
    at liquibase.database.DatabaseFactory.openDatabase(DatabaseFactory.java:141)
    at liquibase.integration.commandline.CommandLineUtils.createDatabaseObject(CommandLineUtils.java:90)
    ... 28 more
Caused by: liquibase.exception.DatabaseException: liquibase.exception.DatabaseException: Connection could not be created to jdbc:postgresql:///db-name?cloudSqlInstance=project:region:db&socketFactory=com.google.cloud.sql.postgres.SocketFactory  with driver org.postgresql.Driver.  Something unusual has occurred to cause the driver to fail. Please report this exception.
    at liquibase.database.ConnectionServiceFactory.create(ConnectionServiceFactory.java:35)
    at liquibase.database.DatabaseFactory.openConnection(DatabaseFactory.java:214)
    ... 31 more
Caused by: liquibase.exception.DatabaseException: Connection could not be created to jdbc:postgresql:///db-name?cloudSqlInstance=project:region:db&socketFactory=com.google.cloud.sql.postgres.SocketFactory  with driver org.postgresql.Driver.  Something unusual has occurred to cause the driver to fail. Please report this exception.
    at liquibase.database.jvm.JdbcConnection.open(JdbcConnection.java:49)
    at com.datical.liquibase.ext.database.jvm.ProJdbcConnection.open(Unknown Source)
    at liquibase.database.ConnectionServiceFactory.create(ConnectionServiceFactory.java:32)
    ... 32 more

The error Something unusual has occurred to cause the driver to fail. Please report this exception. doesn't say much Once again, I'm able to connect to the DB using the same JDBC URL and credentials, but the error comes when trying to do so using Liquibase

luisospina-sealed commented 1 year ago

After some debugging I think this is related to missing google auth credentials. Google requires to have an environment variable GOOGLE_APPLICATION_CREDENTIALS pointing to a gcloud-service-key.json file with the credentials/key. Is there a way to specify/pass this file to the plugin?

FBurguer commented 1 year ago

Hi, Thanks for submitting this issue. Did you set this environment variables and its not working? So the driver is not picking it out? We dont have any specific code that tackles this situation, this is something the driver should manage (I think).

luisospina-sealed commented 1 year ago

Hi @FBurguer, does the plugin use Liquibase docker internally? If so, is there a way in the plugin to copy the gcloud-service-key.json and add an environment variable pointing to it in the container?

kevin-atx commented 1 year ago

@luisospina-sealed - The liquibase-gradle plugin doesn't use Docker. Gradle should have access to any environment variables you set, and those would get passed through and be available to Liquibase and the Google Cloud Service as well.

luisospina-sealed commented 1 year ago

If that's the case then I don't think the main problem I reported is related to the Google credentials. Is there a way to modify Liquibase logs level? Even if I run the task with the --debug flag Liquibase logs will still be of INFO level. I'd probably get more info from Liquibase, the error Something unusual has occurred to cause the driver to fail. Please report this exception. doesn't give much information.

tabbyf00 commented 1 year ago

Does it work if you put the driver URL in quotes? I know I have seen that be an issue with similar exception errors, but not this specific one.

kataggart commented 1 year ago

@luisospina-sealed this looks like it is likely an issue related to Gradle, and not Liquibase specifically. I am reaching out to someone over there to see how we can best help.

kataggart commented 1 year ago

notes from conversation with @nvoxland : gradle extension isn't managing log set up based on gradle level configuration like it should. This needs to be fixed on this end in the liquibase-gradle extension

stevesaliman commented 1 year ago

@luisospina-sealed The --debug option tells Gradle to log in debug mode, but not Liquibase.

The Liquibase Gradle plugin acts as a thin wrapper around the Liquibase CLI, translating any methods in the activities block of build.gradle into Liquibase CLI options, so adding logLevel 'debug' to the activity in build.gradle will turn on debug loging in Liquibase. One advantage to this approach is that we can get debug logging from Liquibase without having to also see the debug logs from Gradle itself.

I'm not sure it would make sense to automatically set the debug flag in Liquibase when using --debug. The philosophical question is this: when we run gradle in debug mode, does that mean we also want everything it runs to also be in debug mode? For example running gradlew --debug bootRun in a Spring Boot application does not enable debug logging in the application being run. I suspect that there are few things that cascade gradle's debug flag into the things it runs.

nvoxland commented 1 year ago

From the Maven plugin side, we have the Liquibase MavenLogger go through the maven-configured logger. The end result is that the -X maven setting (which seems to correspond to --debug in gradle, right?) ends up enabling FINE level logging from liquibase.

stevesaliman commented 1 year ago

I don't think the original issue is related to the Gradle plugin, so I'm going to close this issue. The question of having the this plugin inherit logging from Gradle is a separate issue.

Out of curiousity, @nvoxland Does the Maven Spring Boot plugin also inherit logging from the -X setting?