Skip to content

Commit

Permalink
Upgrade to Liquibase 4.6.2
Browse files Browse the repository at this point in the history
* Upgrade to Liquibase 4.6.2
* Add valid checksums to changesets to allow migration to newest liquibase
* Update liquibase licenses

Co-authored-by: Martin Kanis <mkanis@redhat.com>
  • Loading branch information
sguilhen and martin-kanis authored Feb 9, 2022
1 parent 75c7491 commit 7c1d6ea
Show file tree
Hide file tree
Showing 96 changed files with 720 additions and 527 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>3.5.5</version>
<version>4.6.2</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/liquibase/liquibase/liquibase-parent-3.5.5/LICENSE.txt</url>
<url>https://raw.githubusercontent.com/liquibase/liquibase/v4.6.2/LICENSE.txt</url>
</license>
</licenses>
</dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>3.5.5.redhat-1</version>
<version>4.6.2.redhat-00001</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/liquibase/liquibase/liquibase-parent-3.5.5/LICENSE.txt</url>
<url>https://raw.githubusercontent.com/liquibase/liquibase/v4.6.2/LICENSE.txt</url>
</license>
</licenses>
</dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<module name="org.keycloak.keycloak-server-spi-private"/>
<module name="javax.persistence.api"/>
<module name="org.jboss.logging"/>
<module name="org.liquibase"/>
<module name="org.liquibase" services="import"/>
<module name="org.javassist"/>
<module name="org.hibernate" services="import"/>
<module name="org.bouncycastle" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>3.5.5</version>
<version>3.6.2</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/liquibase/liquibase/liquibase-parent-3.5.5/LICENSE.txt</url>
<url>https://raw.githubusercontent.com/liquibase/liquibase/v4.6.2/LICENSE.txt</url>
</license>
</licenses>
</dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>3.5.5.redhat-1</version>
<version>4.6.2.redhat-00001</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/liquibase/liquibase/liquibase-parent-3.5.5/LICENSE.txt</url>
<url>https://raw.githubusercontent.com/liquibase/liquibase/v4.6.2/LICENSE.txt</url>
</license>
</licenses>
</dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<module name="org.keycloak.keycloak-server-spi-private"/>
<module name="javax.persistence.api"/>
<module name="org.jboss.logging"/>
<module name="org.liquibase"/>
<module name="org.liquibase" services="import"/>
<module name="org.javassist"/>
<module name="org.hibernate" services="import"/>
<module name="org.bouncycastle" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2022 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.connections.jpa.updater.liquibase;

public class LiquibaseConstants {

public static final String JDBC_EXECUTOR = "jdbc";
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import liquibase.Contexts;
import liquibase.LabelExpression;
import liquibase.Liquibase;
import liquibase.Scope;
import liquibase.changelog.ChangeLogHistoryService;
import liquibase.changelog.ChangeLogHistoryServiceFactory;
import liquibase.changelog.ChangeSet;
Expand Down Expand Up @@ -79,15 +80,19 @@ public LiquibaseJpaUpdaterProvider(KeycloakSession session) {

@Override
public void update(Connection connection, String defaultSchema) {
update(connection, null, defaultSchema);
synchronized (LiquibaseJpaUpdaterProvider.class) {
updateSynch(connection, null, defaultSchema);
}
}

@Override
public void export(Connection connection, String defaultSchema, File file) {
update(connection, file, defaultSchema);
synchronized (LiquibaseJpaUpdaterProvider.class) {
updateSynch(connection, file, defaultSchema);
}
}

private void update(Connection connection, File file, String defaultSchema) {
private void updateSynch(Connection connection, File file, String defaultSchema) {
logger.debug("Starting database update");

// Need ThreadLocal as liquibase doesn't seem to have API to inject custom objects into tasks
Expand All @@ -100,7 +105,7 @@ private void update(Connection connection, File file, String defaultSchema) {
if (file != null) {
exportWriter = new FileWriter(file);
}
updateChangeSet(liquibase, connection, exportWriter);
updateChangeSet(liquibase, exportWriter);

// Run update for each custom JpaEntityProvider
Set<JpaEntityProvider> jpaProviders = session.getAllProviders(JpaEntityProvider.class);
Expand All @@ -110,7 +115,7 @@ private void update(Connection connection, File file, String defaultSchema) {
String factoryId = jpaProvider.getFactoryId();
String changelogTableName = JpaUtils.getCustomChangelogTableName(factoryId);
liquibase = getLiquibaseForCustomProviderUpdate(connection, defaultSchema, customChangelog, jpaProvider.getClass().getClassLoader(), changelogTableName);
updateChangeSet(liquibase, connection, exportWriter);
updateChangeSet(liquibase, exportWriter);
}
}
} catch (LiquibaseException | IOException | SQLException e) {
Expand All @@ -128,7 +133,7 @@ private void update(Connection connection, File file, String defaultSchema) {
}
}

protected void updateChangeSet(Liquibase liquibase, Connection connection, Writer exportWriter) throws LiquibaseException, SQLException {
protected void updateChangeSet(Liquibase liquibase, Writer exportWriter) throws LiquibaseException, SQLException {
String changelog = liquibase.getChangeLogFile();
Database database = liquibase.getDatabase();
Table changelogTable = SnapshotGeneratorFactory.getInstance().getDatabaseChangeLogTable(new SnapshotControl(database, false, Table.class, Column.class), database);
Expand All @@ -152,8 +157,8 @@ protected void updateChangeSet(Liquibase liquibase, Connection connection, Write
statementsToExecute.add(new SetNullableStatement(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(),
changelogTable.getName(), DEPLOYMENT_ID_COLUMN, "VARCHAR(10)", false));

ExecutorService executorService = ExecutorService.getInstance();
Executor executor = executorService.getExecutor(liquibase.getDatabase());
ExecutorService executorService = Scope.getCurrentScope().getSingleton(ExecutorService.class);
Executor executor = executorService.getExecutor(LiquibaseConstants.JDBC_EXECUTOR, liquibase.getDatabase());

for (SqlStatement sql : statementsToExecute) {
executor.execute(sql);
Expand All @@ -179,7 +184,7 @@ protected void updateChangeSet(Liquibase liquibase, Connection connection, Write
if (ranChangeSets.isEmpty()) {
outputChangeLogTableCreationScript(liquibase, exportWriter);
}
liquibase.update((Contexts) null, new LabelExpression(), exportWriter, false);
liquibase.update(null, new LabelExpression(), exportWriter, false);
} else {
liquibase.update((Contexts) null);
}
Expand All @@ -197,26 +202,34 @@ protected void updateChangeSet(Liquibase liquibase, Connection connection, Write
private void outputChangeLogTableCreationScript(Liquibase liquibase, final Writer exportWriter) throws DatabaseException {
Database database = liquibase.getDatabase();

Executor oldTemplate = ExecutorService.getInstance().getExecutor(database);
LoggingExecutor executor = new LoggingExecutor(ExecutorService.getInstance().getExecutor(database), exportWriter, database);
ExecutorService.getInstance().setExecutor(database, executor);
ExecutorService executorService = Scope.getCurrentScope().getSingleton(ExecutorService.class);
Executor oldTemplate = executorService.getExecutor(LiquibaseConstants.JDBC_EXECUTOR, database);
LoggingExecutor loggingExecutor = new LoggingExecutor(oldTemplate, exportWriter, database);
executorService.setExecutor(LiquibaseConstants.JDBC_EXECUTOR, database, loggingExecutor);

executor.comment("*********************************************************************");
executor.comment("* Keycloak database creation script - apply this script to empty DB *");
executor.comment("*********************************************************************" + StreamUtil.getLineSeparator());
loggingExecutor.comment("*********************************************************************");
loggingExecutor.comment("* Keycloak database creation script - apply this script to empty DB *");
loggingExecutor.comment("*********************************************************************" + StreamUtil.getLineSeparator());

executor.execute(new CreateDatabaseChangeLogTableStatement());
loggingExecutor.execute(new CreateDatabaseChangeLogTableStatement());
// 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.

executor.comment("*********************************************************************" + StreamUtil.getLineSeparator());
loggingExecutor.comment("*********************************************************************" + StreamUtil.getLineSeparator());

ExecutorService.getInstance().setExecutor(database, oldTemplate);
executorService.setExecutor(LiquibaseConstants.JDBC_EXECUTOR, database, oldTemplate);
}

@Override
public Status validate(Connection connection, String defaultSchema) {
synchronized (LiquibaseJpaUpdaterProvider.class) {
return this.validateSynch(connection, defaultSchema);
}
}

protected Status validateSynch(final Connection connection, final String defaultSchema) {

logger.debug("Validating if database is updated");
ThreadLocalSessionContext.setCurrentSession(session);

Expand Down Expand Up @@ -279,13 +292,8 @@ private void resetLiquibaseServices(Liquibase liquibase) {
ChangeLogHistoryServiceFactory.getInstance().register(new CustomChangeLogHistoryService());
}

@SuppressWarnings("unchecked")
private List<ChangeSet> getLiquibaseUnrunChangeSets(Liquibase liquibase) {
// TODO tracked as: https://issues.jboss.org/browse/KEYCLOAK-3730
// TODO: When https://liquibase.jira.com/browse/CORE-2919 is resolved, replace the following two lines with:
// List<ChangeSet> changeSets = liquibase.listUnrunChangeSets((Contexts) null, new LabelExpression(), false);
Method listUnrunChangeSets = Reflections.findDeclaredMethod(Liquibase.class, "listUnrunChangeSets", Contexts.class, LabelExpression.class, boolean.class);
return Reflections.invokeMethod(true, listUnrunChangeSets, List.class, liquibase, (Contexts) null, new LabelExpression(), false);
private List<ChangeSet> getLiquibaseUnrunChangeSets(Liquibase liquibase) throws LiquibaseException {
return liquibase.listUnrunChangeSets(null, new LabelExpression(), false);
}

private Liquibase getLiquibaseForKeycloakUpdate(Connection connection, String defaultSchema) throws LiquibaseException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.keycloak.connections.jpa.updater.liquibase;

import liquibase.Scope;
import liquibase.database.DatabaseConnection;
import liquibase.database.core.PostgresDatabase;
import liquibase.exception.DatabaseException;
Expand Down Expand Up @@ -61,9 +62,8 @@ public String getDefaultDriver(String url) {
@Override
protected String getConnectionSchemaName() {
try {
String currentSchema = ExecutorService.getInstance().getExecutor(this)
return Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor(LiquibaseConstants.JDBC_EXECUTOR, this)
.queryForObject(new RawSqlStatement("select current_schema"), String.class);
return currentSchema;

} catch (Exception e) {
throw new RuntimeException("Failed to get current schema", e);
Expand Down
Loading

0 comments on commit 7c1d6ea

Please sign in to comment.