diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/DatabasePropertyMappers.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/DatabasePropertyMappers.java index 85b398e24f..a62e28d22f 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/DatabasePropertyMappers.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/DatabasePropertyMappers.java @@ -23,10 +23,11 @@ final class DatabasePropertyMappers { .transformer((db, context) -> Database.getDialect(db).orElse(Database.getDialect("h2-file").get())) .hidden(true) .build(), - builder().from("db-driver") + builder().from("db.driver") .mapFrom("db") + .defaultValue(Database.getDriver("h2-file").get()) .to("quarkus.datasource.jdbc.driver") - .transformer((db, context) -> Database.getDriver(db).orElse(Database.getDriver("h2-file").get())) + .transformer((db, context) -> Database.getDriver(db).orElse(db)) .hidden(true) .build(), builder().from("db"). @@ -37,10 +38,9 @@ final class DatabasePropertyMappers { .paramLabel("vendor") .expectedValues(asList(Database.getAliases())) .build(), - builder().from("db-tx-type") - .mapFrom("db") + builder().from("db.tx-type") + .defaultValue("xa") .to("quarkus.datasource.jdbc.transactions") - .transformer((db, context) -> "xa") .hidden(true) .build(), builder().from("db.url") diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/PropertyMapper.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/PropertyMapper.java index ece3d24629..064b769df6 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/PropertyMapper.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/PropertyMapper.java @@ -121,10 +121,15 @@ public class PropertyMapper { } } + if (defaultValue != null) { + return transformValue(defaultValue, context); + } + + // now tries any defaults from quarkus ConfigValue current = context.proceed(name); - if (current == null) { - return transformValue(defaultValue, context); + if (current != null) { + return transformValue(current.getValue(), context); } return current; diff --git a/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/ConfigurationTest.java b/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/ConfigurationTest.java index a8e7427f61..bbf129cabc 100644 --- a/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/ConfigurationTest.java +++ b/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/ConfigurationTest.java @@ -28,6 +28,7 @@ import java.util.Map; import java.util.Properties; import io.quarkus.hibernate.orm.runtime.dialect.QuarkusH2Dialect; +import io.quarkus.hibernate.orm.runtime.dialect.QuarkusPostgreSQL10Dialect; import io.quarkus.runtime.LaunchMode; import io.smallrye.config.SmallRyeConfig; import org.eclipse.microprofile.config.ConfigProvider; @@ -44,6 +45,8 @@ import io.quarkus.runtime.configuration.ConfigUtils; import io.smallrye.config.SmallRyeConfigProviderResolver; import org.keycloak.quarkus.runtime.Environment; import org.keycloak.vault.FilesPlainTextVaultProviderFactory; +import org.mariadb.jdbc.MySQLDataSource; +import org.postgresql.xa.PGXADataSource; public class ConfigurationTest { @@ -281,11 +284,25 @@ public class ConfigurationTest { SmallRyeConfig config = createConfig(); 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("xa", config.getConfigValue("quarkus.datasource.jdbc.transactions").getValue()); + + System.setProperty(CLI_ARGS, ""); + config = createConfig(); + 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()); System.setProperty("kc.db.url.properties", "?test=test&test1=test1"); System.setProperty(CLI_ARGS, "--db=mariadb"); config = createConfig(); assertEquals("jdbc:mariadb://localhost/keycloak?test=test&test1=test1", config.getConfigValue("quarkus.datasource.jdbc.url").getValue()); + assertEquals(MariaDBDialect.class.getName(), config.getConfigValue("quarkus.hibernate-orm.dialect").getValue()); + assertEquals(MySQLDataSource.class.getName(), config.getConfigValue("quarkus.datasource.jdbc.driver").getValue()); + + System.setProperty(CLI_ARGS, "--db=postgres"); + config = createConfig(); + assertEquals("jdbc:postgresql://localhost/keycloak?test=test&test1=test1", config.getConfigValue("quarkus.datasource.jdbc.url").getValue()); + assertEquals(QuarkusPostgreSQL10Dialect.class.getName(), config.getConfigValue("quarkus.hibernate-orm.dialect").getValue()); + assertEquals(PGXADataSource.class.getName(), config.getConfigValue("quarkus.datasource.jdbc.driver").getValue()); } // KEYCLOAK-15632 @@ -342,6 +359,19 @@ public class ConfigurationTest { assertEquals("http://foo.unittest", initConfig("hostname-default").get("frontend-url")); } + @Test + public void testDatabaseDriverSetExplicitly() { + System.setProperty(CLI_ARGS, "--db=mssql" + ARG_SEPARATOR + "--db-url=jdbc:sqlserver://localhost/keycloak"); + System.setProperty("kc.db.driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver"); + System.setProperty("kc.db.tx-type", "enabled"); + assertTrue(System.getProperty(CLI_ARGS, "").contains("mssql")); + SmallRyeConfig config = createConfig(); + assertEquals("jdbc:sqlserver://localhost/keycloak", config.getConfigValue("quarkus.datasource.jdbc.url").getValue()); + assertEquals("mssql", config.getConfigValue("quarkus.datasource.db-kind").getValue()); + assertEquals("com.microsoft.sqlserver.jdbc.SQLServerDriver", config.getConfigValue("quarkus.datasource.jdbc.driver").getValue()); + assertEquals("enabled", config.getConfigValue("quarkus.datasource.jdbc.transactions").getValue()); + } + private Config.Scope initConfig(String... scope) { Config.init(new MicroProfileConfigProvider(createConfig())); return Config.scope(scope); diff --git a/quarkus/tests/integration/src/main/java/org/keycloak/it/junit5/extension/CLIResult.java b/quarkus/tests/integration/src/main/java/org/keycloak/it/junit5/extension/CLIResult.java index 631fca658d..a036bee541 100644 --- a/quarkus/tests/integration/src/main/java/org/keycloak/it/junit5/extension/CLIResult.java +++ b/quarkus/tests/integration/src/main/java/org/keycloak/it/junit5/extension/CLIResult.java @@ -77,4 +77,8 @@ public interface CLIResult extends LaunchResult { default void assertMessage(String message) { assertTrue(getOutput().contains(message)); } + + default void assertBuild() { + assertMessage("Server configuration updated and persisted"); + } } diff --git a/quarkus/tests/integration/src/main/java/org/keycloak/it/junit5/extension/CLITestExtension.java b/quarkus/tests/integration/src/main/java/org/keycloak/it/junit5/extension/CLITestExtension.java index a6d18a37eb..882a15d232 100644 --- a/quarkus/tests/integration/src/main/java/org/keycloak/it/junit5/extension/CLITestExtension.java +++ b/quarkus/tests/integration/src/main/java/org/keycloak/it/junit5/extension/CLITestExtension.java @@ -41,6 +41,7 @@ import io.quarkus.test.junit.QuarkusMainTestExtension; import io.quarkus.test.junit.main.Launch; import io.quarkus.test.junit.main.LaunchResult; import org.keycloak.quarkus.runtime.configuration.KeycloakPropertiesConfigSource; +import org.keycloak.quarkus.runtime.configuration.test.TestConfigArgsConfigSource; public class CLITestExtension extends QuarkusMainTestExtension { @@ -96,6 +97,7 @@ public class CLITestExtension extends QuarkusMainTestExtension { System.getProperties().remove(KeycloakPropertiesConfigSource.KEYCLOAK_CONFIG_FILE_PROP); System.getProperties().remove(Environment.PROFILE); System.getProperties().remove("quarkus.profile"); + TestConfigArgsConfigSource.setCliArgs(new String[0]); } @Override diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/OptionValidationTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/OptionValidationTest.java index 0076af2e37..b66839300b 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/OptionValidationTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/OptionValidationTest.java @@ -35,12 +35,6 @@ public class OptionValidationTest { Assertions.assertTrue(result.getErrorOutput().contains("Missing required value for option '--db' (vendor). Expected values are: h2-file, h2-mem, mariadb, mssql, mssql-2012, mysql, oracle, postgres, postgres-95")); } - @Test - @Launch({"build", "--db=invalid"}) - 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, mssql-2012, mysql, oracle, postgres, postgres-95")); - } - @Test @Launch({"build", "--db", "foo", "bar"}) public void failMultipleOptionValue(LaunchResult result) { diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/OptionValidationDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/OptionValidationDistTest.java new file mode 100644 index 0000000000..9ff3148305 --- /dev/null +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/OptionValidationDistTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.it.cli.dist; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.keycloak.it.junit5.extension.CLITest; +import org.keycloak.it.junit5.extension.DistributionTest; + +import io.quarkus.test.junit.main.Launch; +import io.quarkus.test.junit.main.LaunchResult; + +@DistributionTest +public class OptionValidationDistTest { + + @Test + @Launch({"build", "--db=invalid"}) + 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, mssql-2012, mysql, oracle, postgres, postgres-95")); + } +} diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/database/dist/CustomTransactionTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/database/dist/CustomTransactionTest.java new file mode 100644 index 0000000000..69a8596360 --- /dev/null +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/database/dist/CustomTransactionTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.it.database.dist; + +import org.junit.jupiter.api.Test; +import org.keycloak.it.junit5.extension.CLIResult; +import org.keycloak.it.junit5.extension.DistributionTest; + +import io.quarkus.test.junit.main.Launch; +import io.quarkus.test.junit.main.LaunchResult; + +@DistributionTest +public class CustomTransactionTest { + + @Test + @Launch({ "-Dkc.db.tx-type=enabled", "-Dkc.db.driver=org.postgresql.xa.PGXADataSource", "build", "--db=postgres" }) + void failNoXAUsingXADriver(LaunchResult result) { + CLIResult cliResult = (CLIResult) result; + cliResult.assertError("Driver org.postgresql.xa.PGXADataSource is an XA datasource, but XA transactions have not been enabled on the default datasource"); + } + + @Test + @Launch({ "-Dkc.db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver", "build", "--db=mssql" }) + void failXAUsingNonXADriver(LaunchResult result) { + CLIResult cliResult = (CLIResult) result; + cliResult.assertError("Driver is not an XA dataSource, while XA has been enabled in the configuration of the default datasource"); + } + + @Test + @Launch({ "-Dkc.db.tx-type=enabled", "-Dkc.db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver", "build", "--db=mssql" }) + void testNoXa(LaunchResult result) { + CLIResult cliResult = (CLIResult) result; + cliResult.assertBuild(); + } +} diff --git a/testsuite/integration-arquillian/servers/auth-server/quarkus/ant/configure.xml b/testsuite/integration-arquillian/servers/auth-server/quarkus/ant/configure.xml index e90fb2ccd0..9e1cec9ba8 100644 --- a/testsuite/integration-arquillian/servers/auth-server/quarkus/ant/configure.xml +++ b/testsuite/integration-arquillian/servers/auth-server/quarkus/ant/configure.xml @@ -5,8 +5,9 @@ Re-augmenting... - + +