In quarkus application.properties
quarkus.datasource.jdbc.url=jdbc:postgresql://192.168.100.110:5432/test
quarkus.datasource.username=root
quarkus.datasource.password=root
quarkus.hibernate-orm.database.generation=update
quarkus.hibernate-orm.multitenant=DATABASE
And use TenantResolver
to resolve tenantId
@PersistenceUnitExtension
@RequestScoped
public class CustomTenantResolver implements TenantResolver {
@Override
public String getDefaultTenantId() {
return TenantUtil.NONE.toString();
}
@Override
public String resolveTenantId() {
return TenantUtil.getTenantId().toString();
}
}
Then use TenantConnectionResolver
to resolve dataSource
@ApplicationScoped
@PersistenceUnitExtension
public class DataSourceTenantConnectionResolver implements TenantConnectionResolver {
@ConfigProperty(name = "quarkus.datasource.jdbc.url")
String url;
@ConfigProperty(name = "quarkus.datasource.username")
String username;
@ConfigProperty(name = "quarkus.datasource.password")
String password;
private final Map<String, ConnectionProvider> map = new HashMap<>();
@Override
public ConnectionProvider resolve(String tenantId) {
System.out.println("resolve ConnectionProvider " + tenantId);
if (map.containsKey(tenantId)) {
return map.get(tenantId);
}
ConnectionProvider provider;
if (tenantId.equals(TenantUtil.NONE)) {
provider = new QuarkusConnectionProvider(createDataSource(url, "test", username, password));
} else {
provider =
new QuarkusConnectionProvider(
createDataSource(
"jdbc:postgresql://192.168.100.110:5432/tenant"
+ tenantId
+ "?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&createDatabaseIfNotExist=true",
"tenant" + tenantId,
"root",
"root"));
}
map.put(tenantId, provider);
return provider;
}
private AgroalDataSource createDataSource(
String url, String database, String username, String password) {
try {
AgroalDataSourceConfigurationSupplier configurationSupplier =
new AgroalDataSourceConfigurationSupplier();
AgroalConnectionPoolConfigurationSupplier connectionPoolConfig =
configurationSupplier.connectionPoolConfiguration();
connectionPoolConfig.maxSize(1000);
AgroalConnectionFactoryConfigurationSupplier connectionFactoryConfig =
connectionPoolConfig.connectionFactoryConfiguration();
connectionFactoryConfig.jdbcUrl(url);
connectionFactoryConfig.principal(new NamePrincipal(username));
connectionFactoryConfig.credential(new SimplePassword(password));
connectionFactoryConfig.initialSql("CREATE DATABASE IF NOT EXISTS " + database);
return AgroalDataSource.from(configurationSupplier.get());
} catch (SQLException | RuntimeException e) {
throw new IllegalStateException("Exception while creating datasource for " + url, e);
}
}
}
The question 1
Unable to automatically create a database through jdbcUrl of createDatabaseIfNotExist=true
. Is this the expected behavior? So i have use to connectionFactoryConfig.initialSql("CREATE DATABASE IF NOT EXISTS " + database)
The question 2
How to automatically create tables like quarkus.hibernate-orm.database.generation=update
?