Rename h2-file and h2-mem and removing defaults from production databases
Closes #9973
This commit is contained in:
parent
d82122b982
commit
f107f0596e
16 changed files with 62 additions and 35 deletions
|
@ -27,8 +27,8 @@ The list of supported databases and their corresponding versions are:
|
||||||
|postgres| 10
|
|postgres| 10
|
||||||
|===
|
|===
|
||||||
|
|
||||||
By default, the server uses the `h2-file` database. This is the default database that the server will use to persist data and
|
By default, the server uses the `dev-file` database. This is the default database that the server will use to persist data and
|
||||||
only exists for development use-cases. The `h2-file` database is not suitable for production use-cases, and must be replaced before deploying to production.
|
only exists for development use-cases. The `dev-file` database is not suitable for production use-cases, and must be replaced before deploying to production.
|
||||||
|
|
||||||
== Configuring a database
|
== Configuring a database
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ http-enabled=true
|
||||||
cluster=local
|
cluster=local
|
||||||
hostname-strict=false
|
hostname-strict=false
|
||||||
hostname-strict-https=false
|
hostname-strict-https=false
|
||||||
db=h2-mem
|
db=dev-mem
|
||||||
db-username = sa
|
db-username = sa
|
||||||
db-password = keycloak
|
db-password = keycloak
|
||||||
metrics-enabled=true
|
metrics-enabled=true
|
|
@ -1,5 +1,6 @@
|
||||||
package org.keycloak.quarkus.runtime.configuration.mappers;
|
package org.keycloak.quarkus.runtime.configuration.mappers;
|
||||||
|
|
||||||
|
import io.quarkus.datasource.common.runtime.DatabaseKind;
|
||||||
import io.smallrye.config.ConfigSourceInterceptorContext;
|
import io.smallrye.config.ConfigSourceInterceptorContext;
|
||||||
import org.keycloak.quarkus.runtime.storage.database.Database;
|
import org.keycloak.quarkus.runtime.storage.database.Database;
|
||||||
|
|
||||||
|
@ -20,12 +21,12 @@ final class DatabasePropertyMappers {
|
||||||
.mapFrom("db")
|
.mapFrom("db")
|
||||||
.to("quarkus.hibernate-orm.dialect")
|
.to("quarkus.hibernate-orm.dialect")
|
||||||
.isBuildTimeProperty(true)
|
.isBuildTimeProperty(true)
|
||||||
.transformer((db, context) -> Database.getDialect(db).orElse(Database.getDialect("h2-file").get()))
|
.transformer((db, context) -> Database.getDialect(db).orElse(Database.getDialect("dev-file").get()))
|
||||||
.hidden(true)
|
.hidden(true)
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("db-driver")
|
builder().from("db-driver")
|
||||||
.mapFrom("db")
|
.mapFrom("db")
|
||||||
.defaultValue(Database.getDriver("h2-file").get())
|
.defaultValue(Database.getDriver("dev-file").get())
|
||||||
.to("quarkus.datasource.jdbc.driver")
|
.to("quarkus.datasource.jdbc.driver")
|
||||||
.transformer((db, context) -> Database.getDriver(db).orElse(db))
|
.transformer((db, context) -> Database.getDriver(db).orElse(db))
|
||||||
.hidden(true)
|
.hidden(true)
|
||||||
|
@ -68,11 +69,15 @@ final class DatabasePropertyMappers {
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("db-username")
|
builder().from("db-username")
|
||||||
.to("quarkus.datasource.username")
|
.to("quarkus.datasource.username")
|
||||||
|
.mapFrom("db")
|
||||||
|
.transformer(DatabasePropertyMappers::resolveUsername)
|
||||||
.description("The username of the database user.")
|
.description("The username of the database user.")
|
||||||
.paramLabel("username")
|
.paramLabel("username")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("db-password")
|
builder().from("db-password")
|
||||||
.to("quarkus.datasource.password")
|
.to("quarkus.datasource.password")
|
||||||
|
.mapFrom("db")
|
||||||
|
.transformer(DatabasePropertyMappers::resolvePassword)
|
||||||
.description("The password of the database user.")
|
.description("The password of the database user.")
|
||||||
.paramLabel("password")
|
.paramLabel("password")
|
||||||
.isMasked(true)
|
.isMasked(true)
|
||||||
|
@ -118,4 +123,25 @@ final class DatabasePropertyMappers {
|
||||||
private static PropertyMapper.Builder builder() {
|
private static PropertyMapper.Builder builder() {
|
||||||
return PropertyMapper.builder(ConfigCategory.DATABASE);
|
return PropertyMapper.builder(ConfigCategory.DATABASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String resolveUsername(String value, ConfigSourceInterceptorContext context) {
|
||||||
|
if (isDevModeDatabase(context)) {
|
||||||
|
return "sa";
|
||||||
|
}
|
||||||
|
|
||||||
|
return Database.getDatabaseKind(value).isEmpty() ? value : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String resolvePassword(String value, ConfigSourceInterceptorContext context) {
|
||||||
|
if (isDevModeDatabase(context)) {
|
||||||
|
return "password";
|
||||||
|
}
|
||||||
|
|
||||||
|
return Database.getDatabaseKind(value).isEmpty() ? value : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isDevModeDatabase(ConfigSourceInterceptorContext context) {
|
||||||
|
String db = context.proceed("kc.db").getValue();
|
||||||
|
return Database.getDatabaseKind(db).get().equals(DatabaseKind.H2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,13 +117,7 @@ public class PropertyMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parentValue != null) {
|
if (parentValue != null) {
|
||||||
ConfigValue value = transformValue(parentValue.getValue(), context);
|
return transformValue(parentValue.getValue(), context);
|
||||||
|
|
||||||
if (value != null) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return parentValue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ public final class Database {
|
||||||
new Function<String, String>() {
|
new Function<String, String>() {
|
||||||
@Override
|
@Override
|
||||||
public String apply(String alias) {
|
public String apply(String alias) {
|
||||||
if ("h2-file".equalsIgnoreCase(alias)) {
|
if ("dev-file".equalsIgnoreCase(alias)) {
|
||||||
return "jdbc:h2:file:${kc.home.dir:${kc.db-url-path:~}}" + File.separator + "${kc.data.dir:data}"
|
return "jdbc:h2:file:${kc.home.dir:${kc.db-url-path:~}}" + File.separator + "${kc.data.dir:data}"
|
||||||
+ File.separator + "h2" + File.separator
|
+ File.separator + "h2" + File.separator
|
||||||
+ "keycloakdb${kc.db-url-properties:;;AUTO_SERVER=TRUE}";
|
+ "keycloakdb${kc.db-url-properties:;;AUTO_SERVER=TRUE}";
|
||||||
|
@ -108,7 +108,7 @@ public final class Database {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
asList("liquibase.database.core.H2Database"),
|
asList("liquibase.database.core.H2Database"),
|
||||||
"h2-mem", "h2-file"
|
"dev-mem", "dev-file"
|
||||||
),
|
),
|
||||||
MYSQL("mysql",
|
MYSQL("mysql",
|
||||||
"com.mysql.cj.jdbc.MysqlXADataSource",
|
"com.mysql.cj.jdbc.MysqlXADataSource",
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# Default and non-production grade database vendor
|
# Default and non-production grade database vendor
|
||||||
db=h2-file
|
db=dev-file
|
||||||
db-username = sa
|
|
||||||
db-password = keycloak
|
|
||||||
|
|
||||||
# Insecure requests are disabled by default
|
# Insecure requests are disabled by default
|
||||||
http-enabled=false
|
http-enabled=false
|
||||||
|
|
|
@ -234,16 +234,28 @@ public class ConfigurationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDatabaseDefaults() {
|
public void testDatabaseDefaults() {
|
||||||
System.setProperty(CLI_ARGS, "--db=h2-file");
|
System.setProperty(CLI_ARGS, "--db=dev-file");
|
||||||
SmallRyeConfig config = createConfig();
|
SmallRyeConfig config = createConfig();
|
||||||
assertEquals(QuarkusH2Dialect.class.getName(), config.getConfigValue("quarkus.hibernate-orm.dialect").getValue());
|
assertEquals(QuarkusH2Dialect.class.getName(), config.getConfigValue("quarkus.hibernate-orm.dialect").getValue());
|
||||||
assertEquals("jdbc:h2:file:~/data/h2/keycloakdb;;AUTO_SERVER=TRUE", config.getConfigValue("quarkus.datasource.jdbc.url").getValue());
|
assertEquals("jdbc:h2:file:~/data/h2/keycloakdb;;AUTO_SERVER=TRUE", config.getConfigValue("quarkus.datasource.jdbc.url").getValue());
|
||||||
|
|
||||||
System.setProperty(CLI_ARGS, "--db=h2-mem");
|
System.setProperty(CLI_ARGS, "--db=dev-mem");
|
||||||
config = createConfig();
|
config = createConfig();
|
||||||
assertEquals(QuarkusH2Dialect.class.getName(), config.getConfigValue("quarkus.hibernate-orm.dialect").getValue());
|
assertEquals(QuarkusH2Dialect.class.getName(), config.getConfigValue("quarkus.hibernate-orm.dialect").getValue());
|
||||||
assertEquals("jdbc:h2:mem:keycloakdb", config.getConfigValue("quarkus.datasource.jdbc.url").getValue());
|
assertEquals("jdbc:h2:mem:keycloakdb", config.getConfigValue("quarkus.datasource.jdbc.url").getValue());
|
||||||
assertEquals("h2", config.getConfigValue("quarkus.datasource.db-kind").getValue());
|
assertEquals("h2", config.getConfigValue("quarkus.datasource.db-kind").getValue());
|
||||||
|
|
||||||
|
System.setProperty(CLI_ARGS, "--db=dev-mem" + ARG_SEPARATOR + "--db-username=other");
|
||||||
|
config = createConfig();
|
||||||
|
assertEquals("sa", config.getConfigValue("quarkus.datasource.username").getValue());
|
||||||
|
|
||||||
|
System.setProperty(CLI_ARGS, "--db=postgres" + ARG_SEPARATOR + "--db-username=other");
|
||||||
|
config = createConfig();
|
||||||
|
assertEquals("other", config.getConfigValue("quarkus.datasource.username").getValue());
|
||||||
|
|
||||||
|
System.setProperty(CLI_ARGS, "--db=postgres");
|
||||||
|
config = createConfig();
|
||||||
|
assertEquals(null, config.getConfigValue("quarkus.datasource.username").getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -280,7 +292,7 @@ public class ConfigurationTest {
|
||||||
public void testDatabaseProperties() {
|
public void testDatabaseProperties() {
|
||||||
System.setProperty("kc.db-url-properties", ";;test=test;test1=test1");
|
System.setProperty("kc.db-url-properties", ";;test=test;test1=test1");
|
||||||
System.setProperty("kc.db-url-path", "test-dir");
|
System.setProperty("kc.db-url-path", "test-dir");
|
||||||
System.setProperty(CLI_ARGS, "--db=h2-file");
|
System.setProperty(CLI_ARGS, "--db=dev-file");
|
||||||
SmallRyeConfig config = createConfig();
|
SmallRyeConfig config = createConfig();
|
||||||
assertEquals(QuarkusH2Dialect.class.getName(), config.getConfigValue("quarkus.hibernate-orm.dialect").getValue());
|
assertEquals(QuarkusH2Dialect.class.getName(), config.getConfigValue("quarkus.hibernate-orm.dialect").getValue());
|
||||||
assertEquals("jdbc:h2:file:test-dir" + File.separator + "data" + File.separator + "h2" + File.separator + "keycloakdb;;test=test;test1=test1", config.getConfigValue("quarkus.datasource.jdbc.url").getValue());
|
assertEquals("jdbc:h2:file:test-dir" + File.separator + "data" + File.separator + "h2" + File.separator + "keycloakdb;;test=test;test1=test1", config.getConfigValue("quarkus.datasource.jdbc.url").getValue());
|
||||||
|
@ -398,9 +410,6 @@ public class ConfigurationTest {
|
||||||
|
|
||||||
Environment.setProfile("prod");
|
Environment.setProfile("prod");
|
||||||
assertEquals("true", createConfig().getConfigValue("kc.hostname-strict").getValue());
|
assertEquals("true", createConfig().getConfigValue("kc.hostname-strict").getValue());
|
||||||
|
|
||||||
Environment.setProfile("prod");
|
|
||||||
assertEquals("false", createConfig().getConfigValue("kc.spi-sticky-session-encoder-infinispan-should-attach-route").getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Config.Scope initConfig(String... scope) {
|
private Config.Scope initConfig(String... scope) {
|
||||||
|
|
|
@ -32,13 +32,13 @@ public class OptionValidationTest {
|
||||||
@Test
|
@Test
|
||||||
@Launch({"build", "--db"})
|
@Launch({"build", "--db"})
|
||||||
public void failMissingOptionValue(LaunchResult result) {
|
public void failMissingOptionValue(LaunchResult result) {
|
||||||
assertTrue(result.getErrorOutput().contains("Missing required value for option '--db' (vendor). Expected values are: h2-file, h2-mem, mariadb, mssql, mysql, oracle, postgres"));
|
assertTrue(result.getErrorOutput().contains("Missing required value for option '--db' (vendor). Expected values are: dev-file, dev-mem, mariadb, mssql, mysql, oracle, postgres"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Launch({"build", "--db", "foo", "bar"})
|
@Launch({"build", "--db", "foo", "bar"})
|
||||||
public void failMultipleOptionValue(LaunchResult result) {
|
public void failMultipleOptionValue(LaunchResult result) {
|
||||||
assertTrue(result.getErrorOutput().contains("Option '--db' expects a single value (vendor) Expected values are: h2-file, h2-mem, mariadb, mssql, mysql, oracle, postgres"));
|
assertTrue(result.getErrorOutput().contains("Option '--db' expects a single value (vendor) Expected values are: dev-file, dev-mem, mariadb, mssql, mysql, oracle, postgres"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -51,9 +51,9 @@ public class StartCommandTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Launch({ "-v", "start", "--db=h2-mem" })
|
@Launch({ "-v", "start", "--db=dev-mem" })
|
||||||
void failBuildPropertyNotAvailable(LaunchResult result) {
|
void failBuildPropertyNotAvailable(LaunchResult result) {
|
||||||
CLIResult cliResult = (CLIResult) result;
|
CLIResult cliResult = (CLIResult) result;
|
||||||
cliResult.assertError("Unknown option: '--db=h2-mem'");
|
cliResult.assertError("Unknown option: '--db=dev-mem'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ public class StartDevCommandTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Launch({ "start-dev", "--db=h2-mem" })
|
@Launch({ "start-dev", "--db=dev-mem" })
|
||||||
void testBuildPropertyAvailable(LaunchResult result) {
|
void testBuildPropertyAvailable(LaunchResult result) {
|
||||||
CLIResult cliResult = (CLIResult) result;
|
CLIResult cliResult = (CLIResult) result;
|
||||||
cliResult.assertStartedDevMode();
|
cliResult.assertStartedDevMode();
|
||||||
|
|
|
@ -31,6 +31,6 @@ public class OptionValidationDistTest {
|
||||||
@Test
|
@Test
|
||||||
@Launch({"build", "--db=invalid"})
|
@Launch({"build", "--db=invalid"})
|
||||||
public void failInvalidOptionValue(LaunchResult result) {
|
public void failInvalidOptionValue(LaunchResult result) {
|
||||||
Assertions.assertTrue(result.getErrorOutput().contains("Invalid value for option '--db': invalid. Expected values are: h2-file, h2-mem, mariadb, mssql, mysql, oracle, postgres"));
|
Assertions.assertTrue(result.getErrorOutput().contains("Invalid value for option '--db': invalid. Expected values are: dev-file, dev-mem, mariadb, mssql, mysql, oracle, postgres"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class StartAutoBuildDistTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Launch({ "start", "--auto-build", "--db=h2-mem", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
|
@Launch({ "start", "--auto-build", "--db=dev-mem", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
|
||||||
@Order(3)
|
@Order(3)
|
||||||
void testShouldReAugIfConfigChanged(LaunchResult result) {
|
void testShouldReAugIfConfigChanged(LaunchResult result) {
|
||||||
CLIResult cliResult = (CLIResult) result;
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
@ -70,7 +70,7 @@ public class StartAutoBuildDistTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Launch({ "start", "--auto-build", "--db=h2-mem", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
|
@Launch({ "start", "--auto-build", "--db=dev-mem", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
|
||||||
@Order(4)
|
@Order(4)
|
||||||
void testShouldNotReAugIfSameDatabase(LaunchResult result) {
|
void testShouldNotReAugIfSameDatabase(LaunchResult result) {
|
||||||
CLIResult cliResult = (CLIResult) result;
|
CLIResult cliResult = (CLIResult) result;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Default and non-production grade database vendor
|
# Default and non-production grade database vendor
|
||||||
db=h2-file
|
db=dev-file
|
||||||
db-username = sa
|
db-username = sa
|
||||||
db-password = keycloak
|
db-password = keycloak
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ Cluster:
|
||||||
|
|
||||||
Database:
|
Database:
|
||||||
|
|
||||||
--db <vendor> The database vendor. Possible values are: h2-file, h2-mem, mariadb, mssql,
|
--db <vendor> The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
||||||
mysql, oracle, postgres
|
mysql, oracle, postgres
|
||||||
|
|
||||||
Feature:
|
Feature:
|
||||||
|
|
|
@ -26,7 +26,7 @@ Cluster:
|
||||||
|
|
||||||
Database:
|
Database:
|
||||||
|
|
||||||
--db <vendor> The database vendor. Possible values are: h2-file, h2-mem, mariadb, mssql,
|
--db <vendor> The database vendor. Possible values are: dev-file, dev-mem, mariadb, mssql,
|
||||||
mysql, oracle, postgres
|
mysql, oracle, postgres
|
||||||
--db-password <password>
|
--db-password <password>
|
||||||
The password of the database user.
|
The password of the database user.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# H2
|
# H2
|
||||||
db=h2-file
|
db=dev-file
|
||||||
db-username = sa
|
db-username = sa
|
||||||
db-password = keycloak
|
db-password = keycloak
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue