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?