[fixes #9133] - Allow setting JDBC driver and transaction type

This commit is contained in:
Pedro Igor 2021-12-15 08:10:36 -03:00
parent 93aeb572bb
commit 4f568dff63
9 changed files with 136 additions and 14 deletions

View file

@ -23,10 +23,11 @@ final class DatabasePropertyMappers {
.transformer((db, context) -> Database.getDialect(db).orElse(Database.getDialect("h2-file").get())) .transformer((db, context) -> Database.getDialect(db).orElse(Database.getDialect("h2-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())
.to("quarkus.datasource.jdbc.driver") .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) .hidden(true)
.build(), .build(),
builder().from("db"). builder().from("db").
@ -37,10 +38,9 @@ final class DatabasePropertyMappers {
.paramLabel("vendor") .paramLabel("vendor")
.expectedValues(asList(Database.getAliases())) .expectedValues(asList(Database.getAliases()))
.build(), .build(),
builder().from("db-tx-type") builder().from("db.tx-type")
.mapFrom("db") .defaultValue("xa")
.to("quarkus.datasource.jdbc.transactions") .to("quarkus.datasource.jdbc.transactions")
.transformer((db, context) -> "xa")
.hidden(true) .hidden(true)
.build(), .build(),
builder().from("db.url") builder().from("db.url")

View file

@ -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); ConfigValue current = context.proceed(name);
if (current == null) { if (current != null) {
return transformValue(defaultValue, context); return transformValue(current.getValue(), context);
} }
return current; return current;

View file

@ -28,6 +28,7 @@ import java.util.Map;
import java.util.Properties; import java.util.Properties;
import io.quarkus.hibernate.orm.runtime.dialect.QuarkusH2Dialect; import io.quarkus.hibernate.orm.runtime.dialect.QuarkusH2Dialect;
import io.quarkus.hibernate.orm.runtime.dialect.QuarkusPostgreSQL10Dialect;
import io.quarkus.runtime.LaunchMode; import io.quarkus.runtime.LaunchMode;
import io.smallrye.config.SmallRyeConfig; import io.smallrye.config.SmallRyeConfig;
import org.eclipse.microprofile.config.ConfigProvider; import org.eclipse.microprofile.config.ConfigProvider;
@ -44,6 +45,8 @@ import io.quarkus.runtime.configuration.ConfigUtils;
import io.smallrye.config.SmallRyeConfigProviderResolver; import io.smallrye.config.SmallRyeConfigProviderResolver;
import org.keycloak.quarkus.runtime.Environment; import org.keycloak.quarkus.runtime.Environment;
import org.keycloak.vault.FilesPlainTextVaultProviderFactory; import org.keycloak.vault.FilesPlainTextVaultProviderFactory;
import org.mariadb.jdbc.MySQLDataSource;
import org.postgresql.xa.PGXADataSource;
public class ConfigurationTest { public class ConfigurationTest {
@ -281,11 +284,25 @@ public class ConfigurationTest {
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());
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("kc.db.url.properties", "?test=test&test1=test1");
System.setProperty(CLI_ARGS, "--db=mariadb"); System.setProperty(CLI_ARGS, "--db=mariadb");
config = createConfig(); config = createConfig();
assertEquals("jdbc:mariadb://localhost/keycloak?test=test&test1=test1", config.getConfigValue("quarkus.datasource.jdbc.url").getValue()); 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 // KEYCLOAK-15632
@ -342,6 +359,19 @@ public class ConfigurationTest {
assertEquals("http://foo.unittest", initConfig("hostname-default").get("frontend-url")); 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) { private Config.Scope initConfig(String... scope) {
Config.init(new MicroProfileConfigProvider(createConfig())); Config.init(new MicroProfileConfigProvider(createConfig()));
return Config.scope(scope); return Config.scope(scope);

View file

@ -77,4 +77,8 @@ public interface CLIResult extends LaunchResult {
default void assertMessage(String message) { default void assertMessage(String message) {
assertTrue(getOutput().contains(message)); assertTrue(getOutput().contains(message));
} }
default void assertBuild() {
assertMessage("Server configuration updated and persisted");
}
} }

View file

@ -41,6 +41,7 @@ import io.quarkus.test.junit.QuarkusMainTestExtension;
import io.quarkus.test.junit.main.Launch; import io.quarkus.test.junit.main.Launch;
import io.quarkus.test.junit.main.LaunchResult; import io.quarkus.test.junit.main.LaunchResult;
import org.keycloak.quarkus.runtime.configuration.KeycloakPropertiesConfigSource; import org.keycloak.quarkus.runtime.configuration.KeycloakPropertiesConfigSource;
import org.keycloak.quarkus.runtime.configuration.test.TestConfigArgsConfigSource;
public class CLITestExtension extends QuarkusMainTestExtension { 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(KeycloakPropertiesConfigSource.KEYCLOAK_CONFIG_FILE_PROP);
System.getProperties().remove(Environment.PROFILE); System.getProperties().remove(Environment.PROFILE);
System.getProperties().remove("quarkus.profile"); System.getProperties().remove("quarkus.profile");
TestConfigArgsConfigSource.setCliArgs(new String[0]);
} }
@Override @Override

View file

@ -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")); 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 @Test
@Launch({"build", "--db", "foo", "bar"}) @Launch({"build", "--db", "foo", "bar"})
public void failMultipleOptionValue(LaunchResult result) { public void failMultipleOptionValue(LaunchResult result) {

View file

@ -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"));
}
}

View file

@ -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();
}
}

View file

@ -5,8 +5,9 @@
<echo>Re-augmenting...</echo> <echo>Re-augmenting...</echo>
<exec osfamily="unix" dir="${auth.server.home}/bin" executable="./kc.sh" failonerror="true"> <exec osfamily="unix" dir="${auth.server.home}/bin" executable="./kc.sh" failonerror="true">
<arg value="build"/> <arg value="build"/>
<arg value="-Dquarkus.http.root-path=/auth"/>
<arg value="--http-enabled=true"/> <arg value="--http-enabled=true"/>
<arg value="--http-relative-path=/auth"/>
<arg value="--cache=local"/>
</exec> </exec>
</target> </target>