Skip to content

Commit

Permalink
× quarkus→optional/explicit; explicit config; fix default db config; …
Browse files Browse the repository at this point in the history
…√ spring compatible
  • Loading branch information
magicprinc committed Apr 14, 2024
1 parent e38478f commit 5d31638
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.magicprinc.hibean;

import io.avaje.config.Config;
import io.ebean.datasource.DataSourceConfig;
import io.ebean.datasource.DataSourceFactory;
import io.ebean.datasource.DataSourcePool;
Expand All @@ -15,6 +16,6 @@ public class HikariEbeanConnectionPoolFactory implements DataSourceFactory {

@Override
public DataSourcePool createPool (String name, DataSourceConfig config) {
return new HikariEbeanDataSourcePool(name, config);
return new HikariEbeanDataSourcePool(name, config, Config.asProperties());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ public class HikariEbeanDataSourcePool implements DataSourcePool {

final HikariDataSource ds;

public HikariEbeanDataSourcePool (String callerPoolName, DataSourceConfig config) {
public HikariEbeanDataSourcePool (String callerPoolName, DataSourceConfig config, Properties configAsProperties) {
val defaultDatabaseName = determineDefaultServerName();// usually "db"
val tmpTrimPoolName = trim(callerPoolName);
val hikariPoolName = tmpTrimPoolName.isEmpty() || tmpTrimPoolName.equals(defaultDatabaseName)
? "ebean"
: "ebean."+ tmpTrimPoolName;
val cfg = SmartConfig.of(Config.asProperties());// System.properties overwrite file.properties
val cfg = SmartConfig.of(configAsProperties);// System.properties overwrite file.properties
val databaseName = makeDatabaseNamePrefix(tmpTrimPoolName, defaultDatabaseName, cfg);
Map<String,String> aliasMap = alias();
val prefixes = collectPrefixes(cfg);
Expand Down Expand Up @@ -133,7 +133,7 @@ private static String makeDatabaseNamePrefix (String trimCallerPoolName, String
cfg.getProperty("ebean.hikari.defaultDb")));

if (db == null){
return defaultDatabaseName;// default prefix for default database (usually db)
return defaultDatabaseName +'.';// default prefix for default database (usually db)
} else {
db = trim(db);
return db.isEmpty() ? ""
Expand Down Expand Up @@ -360,7 +360,7 @@ private static List<String> collectPrefixes (SmartConfig cfg){
p[5] = "spring.datasource.%db%hikari.";
p[7] = cfg.getProperty("ebean.hikari.prefix");
p[9] = "spring.datasource.%db%";
p[11] = "quarkus.datasource.%db%";
// p[11] = "quarkus.datasource.%db%";

for (int i=0; i<p.length; i++){
String key = "ebean.hikari.prefix."+ Integer.toHexString(i);// .0..f
Expand Down Expand Up @@ -388,7 +388,8 @@ void filter (Map<String,String> aliasMap, SmartConfig src, Properties dst, Strin
val db = dbName + (dbName.isEmpty() || dbName.endsWith(".") ? "" : ".");// "", "db.", "mycoolbase.", "toosmart."

final String[] prefixes;
if ((db.isEmpty() || db.equals(defaultDatabaseName)) && !defaultDatabaseName.isEmpty()){// for default db we must generate both variants: spring.datasource.url and spring.datasource.db.url
// for default db we must generate both variants: spring.datasource.url and spring.datasource.db.url
if ((dbName.isEmpty() || dbName.equals(defaultDatabaseName) || dbName.equals(defaultDatabaseName+'.')) && !defaultDatabaseName.isEmpty()){
var set = new LinkedHashSet<String>(prefixTemplates.size() * 8 / 3 + 1);

prefixTemplates.stream()
Expand All @@ -397,7 +398,7 @@ void filter (Map<String,String> aliasMap, SmartConfig src, Properties dst, Strin
.forEach(set::add);

prefixTemplates.stream()
.map(pre->trim(pre).toLowerCase(Locale.ENGLISH).replace("%db%", defaultDatabaseName))
.map(pre->trim(pre).toLowerCase(Locale.ENGLISH).replace("%db%", defaultDatabaseName+'.'))
.filter(pre->pre.length() > 1)
.forEach(set::add);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.ebean.Database;
import io.ebean.datasource.DataSourceConfig;
import io.ebean.datasource.DataSourceFactory;
import lombok.val;
import org.junit.jupiter.api.Test;

import javax.sql.DataSource;
Expand All @@ -17,12 +18,17 @@

import static com.github.magicprinc.hibean.HikariEbeanDataSourcePool.isNumeric;
import static com.github.magicprinc.hibean.HikariEbeanDataSourcePool.normValue;
import static com.github.magicprinc.hibean.HikariEbeanDataSourcePool.trim;
import static java.util.stream.Collectors.joining;
import static org.junit.jupiter.api.Assertions.*;

/**
@see HikariEbeanDataSourcePool
@see com.zaxxer.hikari.HikariConfig
*/
class HikariEbeanDataSourcePoolTest {

@Test void numeric () {
@Test
void numeric () {
assertFalse(isNumeric(""));
assertFalse(isNumeric(" _"));

Expand Down Expand Up @@ -95,7 +101,7 @@ class HikariEbeanDataSourcePoolTest {

@Test void testAnotherPrefix () {
try {
System.setProperty("ebean.hikari.prefix", "spring.datasource.");
System.setProperty("ebean.hikari.prefix", "spring.datasource.testAnotherPrefix.");

var db = DB.byName("test_spring");
var pool = (HikariEbeanDataSourcePool) db.dataSource();
Expand All @@ -106,9 +112,9 @@ class HikariEbeanDataSourcePoolTest {
assertEquals(54321, pool.ds.getMaxLifetime());

System.setProperty("ebean.hikari.prefix.9", "");// disable spring
System.setProperty("ebean.hikari.prefix", "quarkus.datasource.");
System.setProperty("ebean.hikari.prefix", "quarkus.datasource.%db%");
System.setProperty("ebean.hikari.default-Db", "");
var dataSourcePool = (HikariEbeanDataSourcePool) new HikariEbeanConnectionPoolFactory().createPool(null, new DataSourceConfig());
var dataSourcePool = (HikariEbeanDataSourcePool) new HikariEbeanConnectionPoolFactory().createPool("myQuarkusDS", new DataSourceConfig());
assertEquals("jdbc:h2:mem:evenQuarkus", dataSourcePool.ds.getJdbcUrl());
assertEquals("org.h2.Driver", dataSourcePool.ds.getDriverClassName());
assertEquals("test", dataSourcePool.ds.getUsername());
Expand All @@ -117,21 +123,22 @@ class HikariEbeanDataSourcePoolTest {

} finally {
Properties p = System.getProperties();
p.remove("ebean.hikari.prefix.9");
p.remove("ebean.hikari.prefix");
p.remove("ebean.hikari.default-Db");
}
}


@Test void _emptyPropertyIsNotAbsentProperty () {
@Test
void _emptyPropertyIsNotAbsentProperty () {
System.setProperty("fake_empty_prop", "");
assertTrue(System.getProperties().containsKey("fake_empty_prop"));
assertEquals("", System.getProperty("fake_empty_prop"));
assertEquals("", System.getProperty("fake_empty_prop", "default"));
}


@Test void _checkDefaultDbProperties () {
@Test
void _checkDefaultDbProperties () {
var ds = (HikariEbeanDataSourcePool) DB.getDefault().dataSource();
assertEquals("jdbc:h2:mem:my_app", ds.ds.getJdbcUrl());// from ebean-test platform
assertEquals("org.h2.Driver", ds.ds.getDriverClassName());
Expand All @@ -145,4 +152,86 @@ class HikariEbeanDataSourcePoolTest {
assertEquals(61_000, ds.ds.getIdleTimeout());
assertNull(ds.ds.getConnectionInitSql());
}

@Test
void testSpringCompatability () {
// val prev = (Properties) System.getProperties().clone();
var s = """
spring.datasource.ccbbaa.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.ccbbaa.url=jdbc:h2:mem:FooBazYum
spring.datasource.ccbbaa.username=myLogin
spring.datasource.ccbbaa.password=mySecret
spring.datasource.ccbbaa.hikari.maximum-pool-size=10
spring.datasource.ccbbaa.hikari.connection-timeout=+30000
spring.datasource.ccbbaa.hikari.data-source-properties.DB_CLOSE_ON_EXIT=true
spring.datasource.ccbbaa.hikari.data-source-properties.NETWORK_TIMEOUT=42
""";
for (var line : s.split("\n")){
line = line.trim();
if (line.isEmpty()){ continue; }
var keyValue = line.split("=");
if (keyValue.length != 2){ continue; }
System.setProperty(keyValue[0].trim(), keyValue[1].trim());
}
assertEquals("10", System.getProperty("spring.datasource.ccbbaa.hikari.maximum-pool-size"));
assertEquals("jdbc:h2:mem:FooBazYum", System.getProperty("spring.datasource.ccbbaa.url"));

var db = DB.byName("CcBbAa");
assertEquals("HikariEbeanDataSourcePool:HikariDataSource (ebean.CcBbAa)", db.dataSource().toString());
assertEquals("CcBbAa", db.name());
var ds = (HikariEbeanDataSourcePool) db.dataSource();
assertEquals("ebean.CcBbAa", ds.name());
assertEquals("jdbc:h2:mem:FooBazYum", ds.ds.getJdbcUrl());
assertEquals("myLogin", ds.ds.getUsername());
assertEquals("mySecret", ds.ds.getPassword());
assertEquals(10, ds.ds.getMaximumPoolSize());
assertEquals(30_000, ds.ds.getConnectionTimeout());
assertEquals("{DB_CLOSE_ON_EXIT=true, NETWORK_TIMEOUT=42}", ds.ds.getDataSourceProperties().toString());
assertNull(ds.ds.getDataSource());
assertNull(ds.ds.getDataSourceClassName());
assertNull(ds.ds.getDriverClassName());
var sqlRow = db.sqlQuery("select 123").findOne();
assertEquals("{123=123}", sqlRow.toString());
assertNull(ds.ds.getDataSource());
assertNull(ds.ds.getDataSourceClassName());
assertNull(ds.ds.getDriverClassName());


// "default" We can't replace the already created, but we can check how it could be
var fakeConfig = new Properties();
System.getProperties().forEach((key, value)->{
var propertyName = trim(key);
if (propertyName.startsWith("spring.datasource.ccbbaa.")){
propertyName = propertyName.replace(".ccbbaa", "");
fakeConfig.setProperty(propertyName, value.toString());
}
});
assertEquals("10", fakeConfig.getProperty("spring.datasource.hikari.maximum-pool-size"));
assertEquals("jdbc:h2:mem:FooBazYum", fakeConfig.getProperty("spring.datasource.url"));

// DatabaseFactory.create("db" or "")
ds = new HikariEbeanDataSourcePool("db", new DataSourceConfig(), fakeConfig);

assertEquals("HikariEbeanDataSourcePool:HikariDataSource (ebean)", ds.toString());
assertEquals("ebean", ds.name());
assertEquals("jdbc:h2:mem:FooBazYum", ds.ds.getJdbcUrl());
assertEquals("myLogin", ds.ds.getUsername());
assertEquals("mySecret", ds.ds.getPassword());
assertEquals(10, ds.ds.getMaximumPoolSize());
assertEquals(30_000, ds.ds.getConnectionTimeout());
assertEquals("{DB_CLOSE_ON_EXIT=true, NETWORK_TIMEOUT=42}", ds.ds.getDataSourceProperties().toString());
assertNull(ds.ds.getDataSource());
assertNull(ds.ds.getDataSourceClassName());
assertNull(ds.ds.getDriverClassName());

// remove settings
System.getProperties().keySet().removeIf(k->{
val propertyName = trim(k);
return propertyName.startsWith("spring.datasource.");
});
assertNull(System.getProperty("spring.datasource.ccbbaa.hikari.maximum-pool-size"));
assertNull(System.getProperty("spring.datasource.ccbbaa.url"));
assertNull(System.getProperty("spring.datasource.hikari.maximum-pool-size"));
assertNull(System.getProperty("spring.datasource.url"));
}
}
17 changes: 9 additions & 8 deletions src/test/resources/application-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,17 @@ external:

spring:
datasource:
url: jdbc:h2:mem:fromSprng
username: ufoo
password: pbar
testAnotherPrefix:
url: jdbc:h2:mem:fromSprng
username: ufoo
password: pbar

spring.DataSource.test_spring.HiKari:
max-lifetime: 54321
ReadOnly: true

quarkus.datasource.url: jdbc:h2:mem:evenQuarkus
quarkus.datasource.driver: org.h2.Driver
quarkus.datasource.username: test
quarkus.datasource.password: 1234
quarkus.datasource.max-size: 93
quarkus.datasource.myQuarkusDS.url: jdbc:h2:mem:evenQuarkus
quarkus.datasource.myQuarkusDS.driver: org.h2.Driver
quarkus.datasource.myQuarkusDS.username: test
quarkus.datasource.myQuarkusDS.password: 1234
quarkus.datasource.myQuarkusDS.max-size: 93

0 comments on commit 5d31638

Please sign in to comment.