mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 23:12:06 -03:30
Invalid migration export for empty database
Fixes #32535 Signed-off-by: Martin Bartoš <mabartos@redhat.com>
This commit is contained in:
parent
c650984267
commit
fe40730aed
@ -35,7 +35,6 @@ import liquibase.snapshot.SnapshotControl;
|
||||
import liquibase.snapshot.SnapshotGeneratorFactory;
|
||||
import liquibase.statement.SqlStatement;
|
||||
import liquibase.statement.core.AddColumnStatement;
|
||||
import liquibase.statement.core.CreateDatabaseChangeLogTableStatement;
|
||||
import liquibase.statement.core.SetNullableStatement;
|
||||
import liquibase.statement.core.UpdateStatement;
|
||||
import liquibase.structure.core.Column;
|
||||
@ -54,7 +53,6 @@ import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
@ -211,13 +209,11 @@ public class LiquibaseJpaUpdaterProvider implements JpaUpdaterProvider {
|
||||
loggingExecutor.comment("* Keycloak database creation script - apply this script to empty DB *");
|
||||
loggingExecutor.comment("*********************************************************************" + StreamUtil.getLineSeparator());
|
||||
|
||||
loggingExecutor.execute(new CreateDatabaseChangeLogTableStatement());
|
||||
// DatabaseChangeLogTable is automatically added to the script by Liquibase
|
||||
// DatabaseChangeLogLockTable is created before this code is executed and recreated if it does not exist automatically
|
||||
// in org.keycloak.connections.jpa.updater.liquibase.lock.CustomLockService.init() called indirectly from
|
||||
// KeycloakApplication constructor (search for waitForLock() call). Hence it is not included in the creation script.
|
||||
|
||||
loggingExecutor.comment("*********************************************************************" + StreamUtil.getLineSeparator());
|
||||
|
||||
executorService.setExecutor(LiquibaseConstants.JDBC_EXECUTOR, database, oldTemplate);
|
||||
}
|
||||
|
||||
|
||||
@ -57,7 +57,6 @@ import liquibase.snapshot.SnapshotControl;
|
||||
import liquibase.snapshot.SnapshotGeneratorFactory;
|
||||
import liquibase.statement.SqlStatement;
|
||||
import liquibase.statement.core.AddColumnStatement;
|
||||
import liquibase.statement.core.CreateDatabaseChangeLogTableStatement;
|
||||
import liquibase.statement.core.SetNullableStatement;
|
||||
import liquibase.statement.core.UpdateStatement;
|
||||
import liquibase.structure.core.Column;
|
||||
@ -213,13 +212,11 @@ public class QuarkusJpaUpdaterProvider implements JpaUpdaterProvider {
|
||||
loggingExecutor.comment("* Keycloak database creation script - apply this script to empty DB *");
|
||||
loggingExecutor.comment("*********************************************************************" + StreamUtil.getLineSeparator());
|
||||
|
||||
loggingExecutor.execute(new CreateDatabaseChangeLogTableStatement());
|
||||
// DatabaseChangeLogTable is automatically added to the script by Liquibase
|
||||
// DatabaseChangeLogLockTable is created before this code is executed and recreated if it does not exist automatically
|
||||
// in org.keycloak.connections.jpa.updater.liquibase.lock.CustomLockService.init() called indirectly from
|
||||
// KeycloakApplication constructor (search for waitForLock() call). Hence it is not included in the creation script.
|
||||
|
||||
loggingExecutor.comment("*********************************************************************" + StreamUtil.getLineSeparator());
|
||||
|
||||
executorService.setExecutor(LiquibaseConstants.JDBC_EXECUTOR, database, oldTemplate);
|
||||
}
|
||||
|
||||
|
||||
@ -17,14 +17,30 @@
|
||||
|
||||
package org.keycloak.it.storage.database;
|
||||
|
||||
import io.quarkus.logging.Log;
|
||||
import io.quarkus.test.junit.main.Launch;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.jupiter.api.MethodOrderer;
|
||||
import org.junit.jupiter.api.Order;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestMethodOrder;
|
||||
import org.keycloak.it.junit5.extension.CLIResult;
|
||||
import org.keycloak.it.utils.RawDistRootPath;
|
||||
import org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand;
|
||||
|
||||
import io.quarkus.test.junit.main.Launch;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.countMatches;
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
public abstract class BasicDatabaseTest {
|
||||
@ -37,7 +53,7 @@ public abstract class BasicDatabaseTest {
|
||||
|
||||
@Test
|
||||
@Launch({ "start", AbstractStartCommand.OPTIMIZED_BUILD_OPTION_LONG, "--http-enabled=true", "--hostname-strict=false", "--db-username=wrong" })
|
||||
void testWrongUsername(CLIResult cliResult) {
|
||||
protected void testWrongUsername(CLIResult cliResult) {
|
||||
cliResult.assertMessage("ERROR: Failed to obtain JDBC connection");
|
||||
assertWrongUsername(cliResult);
|
||||
}
|
||||
@ -46,7 +62,7 @@ public abstract class BasicDatabaseTest {
|
||||
|
||||
@Test
|
||||
@Launch({ "start", AbstractStartCommand.OPTIMIZED_BUILD_OPTION_LONG, "--http-enabled=true", "--hostname-strict=false", "--db-password=wrong" })
|
||||
void testWrongPassword(CLIResult cliResult) {
|
||||
protected void testWrongPassword(CLIResult cliResult) {
|
||||
cliResult.assertMessage("ERROR: Failed to obtain JDBC connection");
|
||||
assertWrongPassword(cliResult);
|
||||
}
|
||||
@ -69,4 +85,33 @@ public abstract class BasicDatabaseTest {
|
||||
cliResult.assertMessage("Realm 'master' imported");
|
||||
cliResult.assertMessage("Import finished successfully");
|
||||
}
|
||||
|
||||
public void assertManualDbInitialization(CLIResult cliResult, RawDistRootPath rawDistRootPath) {
|
||||
cliResult.assertMessage("Database not initialized, please initialize database with");
|
||||
|
||||
var output = readKeycloakDbUpdateScript(rawDistRootPath);
|
||||
|
||||
assertThat(output, notNullValue());
|
||||
assertThat(output, containsString("Create Database Change Log Table"));
|
||||
|
||||
var outputLowerCase = output.toLowerCase();
|
||||
var count = countMatches(outputLowerCase, "create table public.databasechangelog") + countMatches(outputLowerCase, "create table keycloak.databasechangelog");
|
||||
assertThat(count, is(1));
|
||||
}
|
||||
|
||||
protected static String readKeycloakDbUpdateScript(RawDistRootPath path) {
|
||||
final String defaultScriptName = "keycloak-database-update.sql";
|
||||
Path scriptPath = Paths.get(path.getDistRootPath() + File.separator + "bin" + File.separator + defaultScriptName);
|
||||
File script = new File(scriptPath.toString());
|
||||
assertThat(String.format("Script '%s' does not exist!", defaultScriptName), script.isFile(), is(true));
|
||||
|
||||
try {
|
||||
var result = FileUtils.readFileToString(script, Charset.defaultCharset());
|
||||
Log.infof("Deleting Keycloak DB update script '%s'", defaultScriptName);
|
||||
Files.delete(scriptPath);
|
||||
return result;
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(String.format("Cannot read or delete script '%s'", defaultScriptName), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import org.keycloak.it.junit5.extension.CLIResult;
|
||||
import org.keycloak.it.junit5.extension.DistributionTest;
|
||||
import org.keycloak.it.junit5.extension.WithDatabase;
|
||||
import org.keycloak.it.storage.database.MariaDBTest;
|
||||
import org.keycloak.it.utils.RawDistRootPath;
|
||||
import org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand;
|
||||
|
||||
import io.quarkus.test.junit.main.Launch;
|
||||
@ -39,4 +40,11 @@ public class MariaDBDistTest extends MariaDBTest {
|
||||
super.testSuccessful(result);
|
||||
}
|
||||
|
||||
@Tag(DistributionTest.STORAGE)
|
||||
@Test
|
||||
@Launch({"start", AbstractStartCommand.OPTIMIZED_BUILD_OPTION_LONG, "--spi-connections-jpa-quarkus-migration-strategy=manual", "--spi-connections-jpa-quarkus-initialize-empty=false", "--http-enabled=true", "--hostname-strict=false",})
|
||||
public void testKeycloakDbUpdateScript(CLIResult cliResult, RawDistRootPath rawDistRootPath) {
|
||||
assertManualDbInitialization(cliResult, rawDistRootPath);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import org.keycloak.it.junit5.extension.CLIResult;
|
||||
import org.keycloak.it.junit5.extension.DistributionTest;
|
||||
import org.keycloak.it.junit5.extension.WithDatabase;
|
||||
import org.keycloak.it.storage.database.MySQLTest;
|
||||
import org.keycloak.it.utils.RawDistRootPath;
|
||||
import org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand;
|
||||
|
||||
import io.quarkus.test.junit.main.Launch;
|
||||
@ -21,4 +22,11 @@ public class MySQLDistTest extends MySQLTest {
|
||||
protected void testSuccessful(CLIResult result) {
|
||||
super.testSuccessful(result);
|
||||
}
|
||||
|
||||
@Tag(DistributionTest.STORAGE)
|
||||
@Test
|
||||
@Launch({"start", AbstractStartCommand.OPTIMIZED_BUILD_OPTION_LONG, "--spi-connections-jpa-quarkus-migration-strategy=manual", "--spi-connections-jpa-quarkus-initialize-empty=false", "--http-enabled=true", "--hostname-strict=false",})
|
||||
public void testKeycloakDbUpdateScript(CLIResult cliResult, RawDistRootPath rawDistRootPath) {
|
||||
assertManualDbInitialization(cliResult, rawDistRootPath);
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +28,8 @@ import org.keycloak.it.junit5.extension.WithDatabase;
|
||||
import org.keycloak.it.storage.database.PostgreSQLTest;
|
||||
|
||||
import io.quarkus.test.junit.main.Launch;
|
||||
import org.keycloak.it.utils.RawDistRootPath;
|
||||
import org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand;
|
||||
|
||||
@DistributionTest(removeBuildOptionsAfterBuild = true)
|
||||
@WithDatabase(alias = "postgres")
|
||||
@ -39,4 +41,11 @@ public class PostgreSQLDistTest extends PostgreSQLTest {
|
||||
public void testDbOptionFromPersistedConfigSource(CLIResult cliResult) {
|
||||
assertThat(cliResult.getOutput(),containsString("postgres (Persisted)"));
|
||||
}
|
||||
|
||||
@Tag(DistributionTest.STORAGE)
|
||||
@Test
|
||||
@Launch({"start", AbstractStartCommand.OPTIMIZED_BUILD_OPTION_LONG, "--spi-connections-jpa-quarkus-migration-strategy=manual", "--spi-connections-jpa-quarkus-initialize-empty=false", "--http-enabled=true", "--hostname-strict=false",})
|
||||
public void testKeycloakDbUpdateScript(CLIResult cliResult, RawDistRootPath rawDistRootPath) {
|
||||
assertManualDbInitialization(cliResult, rawDistRootPath);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user