2

I want to have the ability to change the connected database during runtime. In other words, the %prod.quarkus.datasource.jdbc.url in application.properties file.

Requirements:

  • The change must be done programmatically, in other words it cannot be the case where someone need to manually stop the application, change the application.properties file then run the again.
  • Having said that, I am ok with losing connection for a brief period of time when switching connection.
  • Multi-tenancy does not work in my case for 2 reasons: At any time I only need to access 1 connection. Also the application need to work with maybe 10-20 different combinations of server and database name, all of which except the default connection will only be known during runtime.
  • The solution needs to be for production environment, in other words, I cannot deploy a solution that requires dev or test profile (such as the fact that hot-reload in dev profile).

Any help is greatly appreciated.

My question is related to Dynamic datasource connection in Quarkus but unfortunately there's no clear answer on that thread.

My progress: application.properties

...
%prod.quarkus.datasource.jdbc.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
%prod.quarkus.datasource.jdbc.url=jdbc:sqlserver://${SQL_DB_URL:localhost}:${SQL_DB_PORT:1433};databaseName=${SQL_DB_NAME:db};encrypt=${SQL_DB_ENCRYPT:false};
%prod.quarkus.datasource.jdbc.additional-jdbc-properties.authenticationScheme=${SQL_AUTHENTICATIONSCHEME:NTLM}
%prod.quarkus.datasource.jdbc.additional-jdbc-properties.trustservercertificate=${SQL_DB_TRUST_SERVER_CERT:true}
%prod.quarkus.datasource.jdbc.additional-jdbc-properties.integratedsecurity=${SQL_DB_INTEGRATED_SECURITY:true}
...

I tried injecting the environment variables then change those environment variables but it seems not working well, as in print out shows that the new connection string is correct, but the app is still connected to the old connection:

@ApplicationScoped
public class ConnectionString {  
    @ConfigProperty(name = "quarkus.datasource.jdbc.url")
    public String quarkusDataSourceString;
    @ConfigProperty(name = "SQL_DB_URL", defaultValue = "localhost")
    String dbUrlEnvVar;
    @ConfigProperty(name = "SQL_DB_NAME", defaultValue = "db")
    String dbNameEnvVar;
    @ConfigProperty(name = "SQL_DB_PORT", defaultValue = "1433")
    String dbPortEnvVar;
    @ConfigProperty(name = "SQL_DB_ENCRYPT", defaultValue = "false")
    String dbEncryptEnvVar;

    public void SetNewConnectionString() {
       // Do something to get new server (save as local variable newServ), db name (save as newDBname), and build the new connection string (save as newString)
       dbUrlEnvVar = newServ;
       dbNameEnvVar = newDBname;
       quarkusDataSourceString = newString;
  }
}

I think what I'm missing might be a way to restart the application so new configuration can be loaded. Please let me know if this understanding is incorrect. Also nny suggestions will be greatly appreciated.

Btw, I also tried to use something suggested by ChatGPT but it seems to be giving me stuff related to HikariDataSource:

 DataSource dataSource = Arc.container().instance(DataSource.class).get();
 String newJdbcUrl = "jdbc:sqlserver://localhost:1433;databaseName=db2;encrypt:false;"
 dataSource.setJdbcUrl(newJdbcUrl);

Update: On another thought, I was wondering if it's possible to override connection details in the default EntityManager but I don't have much success. Anyone can help?

ABDev
  • 21
  • 2
  • Have you seen https://quarkus.io/guides/credentials-provider? – geoand Mar 22 '23 at 09:06
  • @geoand I believe that's related to setting username and password dynamically, but I need to set the jdbc connection url. – ABDev Mar 22 '23 at 15:58
  • Ah okay, correct. There is no out of the box way to do what you are asking – geoand Mar 23 '23 at 09:46
  • what is the need - is it for failover databases? you write as you only need one database at one time but 10-20 databases over time? – Max Rydahl Andersen Mar 23 '23 at 15:40
  • @MaxRydahlAndersen I have quite a few Microsoft SQL server databases of which the connection server and database names are stored in one table on something like the "main database". Hence I'll need to read from one database for the connection details of the "data" database. I believe multitenancy might be what I need? – ABDev Mar 23 '23 at 18:07
  • Were you able to do this programmatically? – Roya Aug 21 '23 at 03:55

0 Answers0