diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/licenses/keycloak/licenses.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/licenses/keycloak/licenses.xml index 6717a701c5..7be0c2395f 100644 --- a/distribution/feature-packs/server-feature-pack/src/main/resources/licenses/keycloak/licenses.xml +++ b/distribution/feature-packs/server-feature-pack/src/main/resources/licenses/keycloak/licenses.xml @@ -81,11 +81,11 @@ org.liquibase liquibase-core - 3.5.5 + 4.6.2 Apache Software License 2.0 - https://raw.githubusercontent.com/liquibase/liquibase/liquibase-parent-3.5.5/LICENSE.txt + https://raw.githubusercontent.com/liquibase/liquibase/v4.6.2/LICENSE.txt diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/licenses/keycloak/org.liquibase,liquibase-core,3.5.5,Apache Software License 2.0.txt b/distribution/feature-packs/server-feature-pack/src/main/resources/licenses/keycloak/org.liquibase,liquibase-core,4.6.2,Apache Software License 2.0.txt similarity index 100% rename from distribution/feature-packs/server-feature-pack/src/main/resources/licenses/keycloak/org.liquibase,liquibase-core,3.5.5,Apache Software License 2.0.txt rename to distribution/feature-packs/server-feature-pack/src/main/resources/licenses/keycloak/org.liquibase,liquibase-core,4.6.2,Apache Software License 2.0.txt diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/licenses/rh-sso/licenses.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/licenses/rh-sso/licenses.xml index ace445c79e..90b9c040b5 100644 --- a/distribution/feature-packs/server-feature-pack/src/main/resources/licenses/rh-sso/licenses.xml +++ b/distribution/feature-packs/server-feature-pack/src/main/resources/licenses/rh-sso/licenses.xml @@ -81,11 +81,11 @@ org.liquibase liquibase-core - 3.5.5.redhat-1 + 4.6.2.redhat-00001 Apache Software License 2.0 - https://raw.githubusercontent.com/liquibase/liquibase/liquibase-parent-3.5.5/LICENSE.txt + https://raw.githubusercontent.com/liquibase/liquibase/v4.6.2/LICENSE.txt diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/licenses/rh-sso/org.liquibase,liquibase-core,3.5.5.redhat-1,Apache Software License 2.0.txt b/distribution/feature-packs/server-feature-pack/src/main/resources/licenses/rh-sso/org.liquibase,liquibase-core,4.6.2.redhat-00001,Apache Software License 2.0.txt similarity index 100% rename from distribution/feature-packs/server-feature-pack/src/main/resources/licenses/rh-sso/org.liquibase,liquibase-core,3.5.5.redhat-1,Apache Software License 2.0.txt rename to distribution/feature-packs/server-feature-pack/src/main/resources/licenses/rh-sso/org.liquibase,liquibase-core,4.6.2.redhat-00001,Apache Software License 2.0.txt diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-model-jpa/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-model-jpa/main/module.xml index 88cae4fee5..2306ba9f39 100755 --- a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-model-jpa/main/module.xml +++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-model-jpa/main/module.xml @@ -32,7 +32,7 @@ - + diff --git a/distribution/galleon-feature-packs/server-galleon-pack/src/license/keycloak-server-galleon-pack-licenses.xml b/distribution/galleon-feature-packs/server-galleon-pack/src/license/keycloak-server-galleon-pack-licenses.xml index f06357f4ae..9a2df23d2d 100644 --- a/distribution/galleon-feature-packs/server-galleon-pack/src/license/keycloak-server-galleon-pack-licenses.xml +++ b/distribution/galleon-feature-packs/server-galleon-pack/src/license/keycloak-server-galleon-pack-licenses.xml @@ -96,11 +96,11 @@ org.liquibase liquibase-core - 3.5.5 + 3.6.2 Apache Software License 2.0 - https://raw.githubusercontent.com/liquibase/liquibase/liquibase-parent-3.5.5/LICENSE.txt + https://raw.githubusercontent.com/liquibase/liquibase/v4.6.2/LICENSE.txt diff --git a/distribution/galleon-feature-packs/server-galleon-pack/src/license/rh-sso-server-galleon-pack-licenses.xml b/distribution/galleon-feature-packs/server-galleon-pack/src/license/rh-sso-server-galleon-pack-licenses.xml index e871c024d7..3466f26090 100644 --- a/distribution/galleon-feature-packs/server-galleon-pack/src/license/rh-sso-server-galleon-pack-licenses.xml +++ b/distribution/galleon-feature-packs/server-galleon-pack/src/license/rh-sso-server-galleon-pack-licenses.xml @@ -81,11 +81,11 @@ org.liquibase liquibase-core - 3.5.5.redhat-1 + 4.6.2.redhat-00001 Apache Software License 2.0 - https://raw.githubusercontent.com/liquibase/liquibase/liquibase-parent-3.5.5/LICENSE.txt + https://raw.githubusercontent.com/liquibase/liquibase/v4.6.2/LICENSE.txt diff --git a/distribution/galleon-feature-packs/server-galleon-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-model-jpa/main/module.xml b/distribution/galleon-feature-packs/server-galleon-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-model-jpa/main/module.xml index 88cae4fee5..2306ba9f39 100755 --- a/distribution/galleon-feature-packs/server-galleon-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-model-jpa/main/module.xml +++ b/distribution/galleon-feature-packs/server-galleon-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-model-jpa/main/module.xml @@ -32,7 +32,7 @@ - + diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/LiquibaseConstants.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/LiquibaseConstants.java new file mode 100644 index 0000000000..acd1dc1169 --- /dev/null +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/LiquibaseConstants.java @@ -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"; +} diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/LiquibaseJpaUpdaterProvider.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/LiquibaseJpaUpdaterProvider.java index 0563515227..27a7a570ec 100755 --- a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/LiquibaseJpaUpdaterProvider.java +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/LiquibaseJpaUpdaterProvider.java @@ -20,6 +20,7 @@ package org.keycloak.connections.jpa.updater.liquibase; import liquibase.Contexts; import liquibase.LabelExpression; import liquibase.Liquibase; +import liquibase.Scope; import liquibase.changelog.ChangeLogHistoryService; import liquibase.changelog.ChangeLogHistoryServiceFactory; import liquibase.changelog.ChangeSet; @@ -79,15 +80,19 @@ public class LiquibaseJpaUpdaterProvider implements JpaUpdaterProvider { @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 @@ -100,7 +105,7 @@ public class LiquibaseJpaUpdaterProvider implements JpaUpdaterProvider { if (file != null) { exportWriter = new FileWriter(file); } - updateChangeSet(liquibase, connection, exportWriter); + updateChangeSet(liquibase, exportWriter); // Run update for each custom JpaEntityProvider Set jpaProviders = session.getAllProviders(JpaEntityProvider.class); @@ -110,7 +115,7 @@ public class LiquibaseJpaUpdaterProvider implements JpaUpdaterProvider { 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) { @@ -128,7 +133,7 @@ public class LiquibaseJpaUpdaterProvider implements JpaUpdaterProvider { } } - 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); @@ -152,8 +157,8 @@ public class LiquibaseJpaUpdaterProvider implements JpaUpdaterProvider { 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); @@ -179,7 +184,7 @@ public class LiquibaseJpaUpdaterProvider implements JpaUpdaterProvider { 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); } @@ -197,26 +202,34 @@ public class LiquibaseJpaUpdaterProvider implements JpaUpdaterProvider { 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); @@ -279,13 +292,8 @@ public class LiquibaseJpaUpdaterProvider implements JpaUpdaterProvider { ChangeLogHistoryServiceFactory.getInstance().register(new CustomChangeLogHistoryService()); } - @SuppressWarnings("unchecked") - private List 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 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 getLiquibaseUnrunChangeSets(Liquibase liquibase) throws LiquibaseException { + return liquibase.listUnrunChangeSets(null, new LabelExpression(), false); } private Liquibase getLiquibaseForKeycloakUpdate(Connection connection, String defaultSchema) throws LiquibaseException { diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/PostgresPlusDatabase.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/PostgresPlusDatabase.java index 604613df5a..b721f8bd71 100644 --- a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/PostgresPlusDatabase.java +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/PostgresPlusDatabase.java @@ -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; @@ -61,9 +62,8 @@ public class PostgresPlusDatabase extends PostgresDatabase { @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); diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/conn/DefaultLiquibaseConnectionProvider.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/conn/DefaultLiquibaseConnectionProvider.java index 75acb6724c..896136584a 100644 --- a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/conn/DefaultLiquibaseConnectionProvider.java +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/conn/DefaultLiquibaseConnectionProvider.java @@ -18,40 +18,24 @@ package org.keycloak.connections.jpa.updater.liquibase.conn; import liquibase.Liquibase; -import liquibase.change.ChangeFactory; -import liquibase.changelog.ChangeSet; -import liquibase.changelog.DatabaseChangeLog; +import liquibase.Scope; import liquibase.database.AbstractJdbcDatabase; import liquibase.database.Database; import liquibase.database.DatabaseFactory; import liquibase.database.jvm.JdbcConnection; -import liquibase.datatype.DataTypeFactory; import liquibase.exception.LiquibaseException; -import liquibase.logging.LogFactory; -import liquibase.logging.LogLevel; import liquibase.resource.ClassLoaderResourceAccessor; import liquibase.resource.ResourceAccessor; -import liquibase.servicelocator.ServiceLocator; -import liquibase.sqlgenerator.SqlGeneratorFactory; import org.jboss.logging.Logger; import org.keycloak.Config; -import org.keycloak.connections.jpa.updater.liquibase.CustomForeignKeySnapshotGenerator; import org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterProvider; -import org.keycloak.connections.jpa.updater.liquibase.PostgresPlusDatabase; -import org.keycloak.connections.jpa.updater.liquibase.MySQL8VarcharType; -import org.keycloak.connections.jpa.updater.liquibase.UpdatedMariaDBDatabase; -import org.keycloak.connections.jpa.updater.liquibase.UpdatedMySqlDatabase; -import org.keycloak.connections.jpa.updater.liquibase.custom.CustomCreateIndexChange; -import org.keycloak.connections.jpa.updater.liquibase.lock.CustomInsertLockRecordGenerator; -import org.keycloak.connections.jpa.updater.liquibase.lock.CustomLockDatabaseChangeLogGenerator; -import org.keycloak.connections.jpa.updater.liquibase.lock.DummyLockService; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; import java.sql.Connection; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; -import liquibase.changelog.ChangeLogHistoryServiceFactory; -import liquibase.snapshot.SnapshotGeneratorFactory; /** * @author Marek Posolda @@ -83,54 +67,25 @@ public class DefaultLiquibaseConnectionProvider implements LiquibaseConnectionPr } protected void baseLiquibaseInitialization() { - ServiceLocator sl = ServiceLocator.getInstance(); - sl.setResourceAccessor(new ClassLoaderResourceAccessor(getClass().getClassLoader())); - - if (!System.getProperties().containsKey("liquibase.scan.packages")) { - if (sl.getPackages().remove("liquibase.core")) { - sl.addPackageToScan("liquibase.core.xml"); - } - - if (sl.getPackages().remove("liquibase.parser")) { - sl.addPackageToScan("liquibase.parser.core.xml"); - } - - if (sl.getPackages().remove("liquibase.serializer")) { - sl.addPackageToScan("liquibase.serializer.core.xml"); - } - - sl.getPackages().remove("liquibase.ext"); - sl.getPackages().remove("liquibase.sdk"); - - String lockPackageName = DummyLockService.class.getPackage().getName(); - logger.debugf("Added package %s to liquibase", lockPackageName); - sl.addPackageToScan(lockPackageName); + // we need to initialize the scope using the right classloader, or else Liquibase won't be able to locate the extensions. + ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); + Scope.getCurrentScope(); + } finally { + Thread.currentThread().setContextClassLoader(currentClassLoader); } - LogFactory.setInstance(new LogWrapper()); - - // Adding PostgresPlus support to liquibase - DatabaseFactory.getInstance().register(new PostgresPlusDatabase()); - // Adding newer version of MySQL/MariaDB support to liquibase - DatabaseFactory.getInstance().register(new UpdatedMySqlDatabase()); - DatabaseFactory.getInstance().register(new UpdatedMariaDBDatabase()); - - // Adding CustomVarcharType for MySQL 8 and newer - DataTypeFactory.getInstance().register(MySQL8VarcharType.class); - - // Change command for creating lock and drop DELETE lock record from it - SqlGeneratorFactory.getInstance().register(new CustomInsertLockRecordGenerator()); - - // Use "SELECT FOR UPDATE" for locking database - SqlGeneratorFactory.getInstance().register(new CustomLockDatabaseChangeLogGenerator()); - - ChangeLogHistoryServiceFactory.getInstance().register(new CustomChangeLogHistoryService()); - - // Adding CustomCreateIndexChange for handling conditional indices creation - ChangeFactory.getInstance().register(CustomCreateIndexChange.class); - - // Contains fix for https://liquibase.jira.com/browse/CORE-3141 - SnapshotGeneratorFactory.getInstance().register(new CustomForeignKeySnapshotGenerator()); + // using the initialized scope, create a child scope that sets the classloader and resource accessor so that any attempt + // by Liquibase to load a class (e.g. custom change) using the scope's classloader uses the correct classloader. + final Map scopeValues = new HashMap<>(); + scopeValues.put(Scope.Attr.resourceAccessor.name(), new ClassLoaderResourceAccessor(this.getClass().getClassLoader())); + scopeValues.put(Scope.Attr.classLoader.name(), this.getClass().getClassLoader()); + try { + Scope.enter(scopeValues); + } catch (Exception e) { + throw new RuntimeException("Failed to initialize Liquibase: " + e.getMessage(), e); + } } @Override @@ -184,109 +139,4 @@ public class DefaultLiquibaseConnectionProvider implements LiquibaseConnectionPr return new Liquibase(changelogLocation, resourceAccessor, database); } - private static class LogWrapper extends LogFactory { - - private static final liquibase.logging.Logger logger = new liquibase.logging.Logger() { - @Override - public void setName(String name) { - } - - @Override - public void setLogLevel(String level) { - } - - @Override - public void setLogLevel(LogLevel level) { - } - - @Override - public void setLogLevel(String logLevel, String logFile) { - } - - @Override - public void severe(String message) { - DefaultLiquibaseConnectionProvider.logger.error(message); - } - - @Override - public void severe(String message, Throwable e) { - DefaultLiquibaseConnectionProvider.logger.error(message, e); - } - - @Override - public void warning(String message) { - // Ignore this warning as cascaded drops doesn't work anyway with all DBs, which we need to support - if ("Database does not support drop with cascade".equals(message)) { - DefaultLiquibaseConnectionProvider.logger.debug(message); - } else { - DefaultLiquibaseConnectionProvider.logger.warn(message); - } - } - - @Override - public void warning(String message, Throwable e) { - DefaultLiquibaseConnectionProvider.logger.warn(message, e); - } - - @Override - public void info(String message) { - DefaultLiquibaseConnectionProvider.logger.debug(message); - } - - @Override - public void info(String message, Throwable e) { - DefaultLiquibaseConnectionProvider.logger.debug(message, e); - } - - @Override - public void debug(String message) { - if (DefaultLiquibaseConnectionProvider.logger.isTraceEnabled()) { - DefaultLiquibaseConnectionProvider.logger.trace(message); - } - } - - @Override - public LogLevel getLogLevel() { - if (DefaultLiquibaseConnectionProvider.logger.isTraceEnabled()) { - return LogLevel.DEBUG; - } else if (DefaultLiquibaseConnectionProvider.logger.isDebugEnabled()) { - return LogLevel.INFO; - } else { - return LogLevel.WARNING; - } - } - - @Override - public void debug(String message, Throwable e) { - DefaultLiquibaseConnectionProvider.logger.trace(message, e); - } - - @Override - public void setChangeLog(DatabaseChangeLog databaseChangeLog) { - } - - @Override - public void setChangeSet(ChangeSet changeSet) { - } - - @Override - public int getPriority() { - return 0; - } - - @Override - public void closeLogFile() {} - }; - - @Override - public liquibase.logging.Logger getLog(String name) { - return logger; - } - - @Override - public liquibase.logging.Logger getLog() { - return logger; - } - - } } diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/CustomCreateIndexChange.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/CustomCreateIndexChange.java index 404c3e74fe..3daaa64790 100644 --- a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/CustomCreateIndexChange.java +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/CustomCreateIndexChange.java @@ -18,7 +18,9 @@ package org.keycloak.connections.jpa.updater.liquibase.custom; import java.io.StringWriter; +import liquibase.Scope; import org.jboss.logging.Logger; +import org.keycloak.connections.jpa.updater.liquibase.LiquibaseConstants; import org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterProvider; import org.keycloak.connections.jpa.updater.liquibase.conn.DefaultLiquibaseConnectionProvider; @@ -57,7 +59,7 @@ public class CustomCreateIndexChange extends CreateIndexChange { @Override public SqlStatement[] generateStatements(Database database) { // This check is for manual migration - if (ExecutorService.getInstance().getExecutor(database) instanceof LoggingExecutor) + if (Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor(LiquibaseConstants.JDBC_EXECUTOR, database) instanceof LoggingExecutor) return super.generateStatements(database); Object indexCreationThreshold = ((AbstractJdbcDatabase) database) @@ -76,8 +78,8 @@ public class CustomCreateIndexChange extends CreateIndexChange { .has(new Table().setName(getTableName()).setSchema(new Schema(getCatalogName(), getSchemaName())), database)) return super.generateStatements(database); - int result = ExecutorService.getInstance().getExecutor(database).queryForInt( - new RawSqlStatement("SELECT COUNT(*) FROM " + getTableNameForSqlSelects(database, getTableName()))); + int result = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor(LiquibaseConstants.JDBC_EXECUTOR, database) + .queryForInt(new RawSqlStatement("SELECT COUNT(*) FROM " + getTableNameForSqlSelects(database, getTableName()))); if (result > this.indexCreationThreshold) { String loggingString = createLoggingString(database); @@ -100,10 +102,10 @@ public class CustomCreateIndexChange extends CreateIndexChange { private String createLoggingString(Database database) throws DatabaseException { StringWriter writer = new StringWriter(); - LoggingExecutor loggingExecutor = new LoggingExecutor(ExecutorService.getInstance().getExecutor(database), writer, - database); + LoggingExecutor loggingExecutor = new LoggingExecutor(Scope.getCurrentScope().getSingleton(ExecutorService.class) + .getExecutor(LiquibaseConstants.JDBC_EXECUTOR, database), writer, database); SqlStatement sqlStatement = new CreateIndexStatement(getIndexName(), getCatalogName(), getSchemaName(), getTableName(), - this.isUnique(), getAssociatedWith(), getColumns().toArray(new AddColumnConfig[getColumns().size()])) + this.isUnique(), getAssociatedWith(), getColumns().toArray(new AddColumnConfig[0])) .setTablespace(getTablespace()).setClustered(getClustered()); loggingExecutor.execute(sqlStatement); @@ -140,8 +142,8 @@ public class CustomCreateIndexChange extends CreateIndexChange { if (SqlGeneratorFactory.getInstance().supports(statement, database)) { warnings.addAll(SqlGeneratorFactory.getInstance().warn(statement, database)); } else if (statement.skipOnUnsupported()) { - warnings.addWarning(statement.getClass().getName() + " is not supported on " + database.getShortName() - + ", but " + ChangeFactory.getInstance().getChangeMetaData(this).getName() + " will still execute"); + warnings.addWarning(statement.getClass().getName() + " is not supported on " + database.getShortName() + ", but " + + Scope.getCurrentScope().getSingleton(ChangeFactory.class).getChangeMetaData(this).getName() + " will still execute"); } } @@ -152,10 +154,11 @@ public class CustomCreateIndexChange extends CreateIndexChange { public ValidationErrors validate(Database database) { ValidationErrors changeValidationErrors = new ValidationErrors(); - for (ChangeParameterMetaData param : ChangeFactory.getInstance().getChangeMetaData(this).getParameters().values()) { + ChangeFactory changeFactory = Scope.getCurrentScope().getSingleton(ChangeFactory.class); + for (ChangeParameterMetaData param : changeFactory.getChangeMetaData(this).getParameters().values()) { if (param.isRequiredFor(database) && param.getCurrentValue(this) == null) { changeValidationErrors.addError(param.getParameterName() + " is required for " - + ChangeFactory.getInstance().getChangeMetaData(this).getName() + " on " + database.getShortName()); + + changeFactory.getChangeMetaData(this).getName() + " on " + database.getShortName()); } } if (changeValidationErrors.hasErrors()) { @@ -163,7 +166,7 @@ public class CustomCreateIndexChange extends CreateIndexChange { } if (!generateStatementsVolatile(database)) { - String unsupportedWarning = ChangeFactory.getInstance().getChangeMetaData(this).getName() + " is not supported on " + String unsupportedWarning = changeFactory.getChangeMetaData(this).getName() + " is not supported on " + database.getShortName(); boolean sawUnsupportedError = false; diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/lock/CustomLockService.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/lock/CustomLockService.java index a21f12660e..1210a043fa 100644 --- a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/lock/CustomLockService.java +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/lock/CustomLockService.java @@ -17,6 +17,7 @@ package org.keycloak.connections.jpa.updater.liquibase.lock; +import liquibase.Scope; import liquibase.database.core.DerbyDatabase; import liquibase.exception.DatabaseException; import liquibase.exception.UnexpectedLiquibaseException; @@ -31,6 +32,7 @@ import liquibase.statement.core.RawSqlStatement; import org.jboss.logging.Logger; import org.keycloak.common.util.Time; import org.keycloak.common.util.reflections.Reflections; +import org.keycloak.connections.jpa.updater.liquibase.LiquibaseConstants; import org.keycloak.models.dblock.DBLockProvider; import java.lang.reflect.Field; @@ -52,7 +54,7 @@ public class CustomLockService extends StandardLockService { @Override public void init() throws DatabaseException { - Executor executor = ExecutorService.getInstance().getExecutor(database); + Executor executor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor(LiquibaseConstants.JDBC_EXECUTOR, database); if (!hasDatabaseChangeLogLockTable()) { @@ -119,7 +121,7 @@ public class CustomLockService extends StandardLockService { private Set currentIdsInDatabaseChangeLogLockTable() throws DatabaseException { try { - Executor executor = ExecutorService.getInstance().getExecutor(database); + Executor executor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor(LiquibaseConstants.JDBC_EXECUTOR, database); String idColumnName = database.escapeColumnName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogLockTableName(), @@ -143,20 +145,6 @@ public class CustomLockService extends StandardLockService { } } - @Override - public boolean isDatabaseChangeLogLockTableInitialized(boolean tableJustCreated) throws DatabaseException { - try { - return super.isDatabaseChangeLogLockTableInitialized(tableJustCreated); - } catch (UnexpectedLiquibaseException ulie) { - // It can happen with MariaDB Galera 10.1 that UnexpectedLiquibaseException is rethrown due the DB lock. It is sufficient to just rollback transaction and retry in that case. - if (ulie.getCause() != null && ulie.getCause() instanceof DatabaseException) { - throw (DatabaseException) ulie.getCause(); - } else { - throw ulie; - } - } - } - @Override public void waitForLock() { waitForLock(new LockDatabaseChangeLogStatement()); @@ -203,7 +191,7 @@ public class CustomLockService extends StandardLockService { return true; } - Executor executor = ExecutorService.getInstance().getExecutor(database); + Executor executor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor(LiquibaseConstants.JDBC_EXECUTOR, database); try { database.rollback(); @@ -249,8 +237,7 @@ public class CustomLockService extends StandardLockService { hasChangeLogLock = false; database.setCanCacheLiquibaseTableInfo(false); database.rollback(); - } catch (DatabaseException e) { - ; + } catch (DatabaseException ignored) { } } } diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/log/KeycloakLogService.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/log/KeycloakLogService.java new file mode 100644 index 0000000000..9ea781f78c --- /dev/null +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/log/KeycloakLogService.java @@ -0,0 +1,39 @@ +/* + * 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.log; + +import liquibase.logging.Logger; +import liquibase.logging.core.AbstractLogService; + +/** + * A {@link liquibase.logging.LogService} implementation that creates instances of {@link KeycloakLogger}. + * + * @author Stefan Guilhen + */ +public class KeycloakLogService extends AbstractLogService { + + @Override + public int getPriority() { + return PRIORITY_DEFAULT + 1; + } + + @Override + public Logger getLog(Class clazz) { + return new KeycloakLogger(clazz); + } +} diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/log/KeycloakLogger.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/log/KeycloakLogger.java new file mode 100644 index 0000000000..277b6bd4a5 --- /dev/null +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/log/KeycloakLogger.java @@ -0,0 +1,102 @@ +/* + * 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.log; + +import java.util.logging.Level; + +import liquibase.logging.core.AbstractLogger; +import liquibase.logging.core.DefaultLogMessageFilter; +import org.jboss.logging.Logger; + +/** + * A {@link liquibase.logging.Logger} implementation that delegates to a JBoss {@link Logger}. + * + * @author Stefan Guilhen + */ +public class KeycloakLogger extends AbstractLogger { + + private final Logger delegate; + + public KeycloakLogger(final Class clazz) { + super(new DefaultLogMessageFilter()); + this.delegate = Logger.getLogger(clazz); + } + + @Override + public void severe(String message) { + this.delegate.error(message); + } + + @Override + public void severe(String message, Throwable e) { + this.delegate.error(message, e); + } + + @Override + public void warning(String message) { + // Ignore this warning as cascaded drops doesn't work anyway with all DBs, which we need to support + if ("Database does not support drop with cascade".equals(message)) { + this.delegate.debug(message); + } else { + this.delegate.warn(message); + } + } + + @Override + public void warning(String message, Throwable e) { + this.delegate.warn(message, e); + } + + @Override + public void info(String message) { + this.delegate.debug(message); + } + + @Override + public void info(String message, Throwable e) { + this.delegate.debug(message, e); + } + + @Override + public void debug(String message) { + if (this.delegate.isTraceEnabled()) { + this.delegate.trace(message); + } + } + + @Override + public void debug(String message, Throwable e) { + this.delegate.trace(message, e); + } + + @Override + public void log(Level level, String message, Throwable e) { + if (level.equals(Level.OFF)) { + return; + } else if (level.equals(Level.SEVERE)) { + this.delegate.error(message, e); + } else if (level.equals(Level.WARNING)) { + this.delegate.warn(message, e); + } else if (level.equals(Level.INFO)) { + this.delegate.debug(message, e); + } else if (level.equals(Level.FINE) | level.equals(Level.FINER) | level.equals(Level.FINEST)) { + if (this.delegate.isTraceEnabled()) + this.delegate.trace(message, e); + } + } +} diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.0.0.Final-db2.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.0.0.Final-db2.xml index 4e1cbc7a5c..b2ea517887 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.0.0.Final-db2.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.0.0.Final-db2.xml @@ -18,6 +18,7 @@ + 7:cb16724583e9675711801c6875114f28 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.0.0.Final.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.0.0.Final.xml index fb1afc153c..ee37a445a4 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.0.0.Final.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.0.0.Final.xml @@ -18,6 +18,7 @@ + 7:4e70412f24a3f382c82183742ec79317 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.1.0.Beta1.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.1.0.Beta1.xml index 26d01947b5..a0d7198431 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.1.0.Beta1.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.1.0.Beta1.xml @@ -18,6 +18,7 @@ + 7:0310eb8ba07cec616460794d42ade0fa diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.1.0.Final.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.1.0.Final.xml index 2bea27887e..57bc67b6f8 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.1.0.Final.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.1.0.Final.xml @@ -18,6 +18,7 @@ + 7:5d25857e708c3233ef4439df1f93f012 \ No newline at end of file diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1-db2.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1-db2.xml index 41abd07729..cd5bedca67 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1-db2.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1-db2.xml @@ -18,6 +18,7 @@ + 7:2e01012df20974c1c2a605ef8afe25b7 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml index 4e072673c8..191ae35b43 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml @@ -18,6 +18,7 @@ + 7:c7a54a1041d58eb3817a4a883b4d4e84 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.CR1-db2.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.CR1-db2.xml index 49e647c6f5..08f8792975 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.CR1-db2.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.CR1-db2.xml @@ -18,6 +18,7 @@ + 7:a77ea2ad226b345e7d689d366f185c8c diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.CR1.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.CR1.xml index 5c9b676ac1..3aeeb80eaf 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.CR1.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.CR1.xml @@ -18,6 +18,7 @@ + 7:0f08df48468428e0f30ee59a8ec01a41 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.Final.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.Final.xml index 91d9723f59..cac7a62bf5 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.Final.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.2.0.Final.xml @@ -18,6 +18,7 @@ + 7:a3377a2059aefbf3b90ebb4c4cc8e2ab diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.3.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.3.0.xml index 6361c953ec..fb1d2c7f12 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.3.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.3.0.xml @@ -18,6 +18,7 @@ + 7:04c1dbedc2aa3e9756d1a1668e003451 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.4.0-db2.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.4.0-db2.xml index b16fbbedf4..59f74ceebc 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.4.0-db2.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.4.0-db2.xml @@ -18,6 +18,7 @@ + 7:d909180b2530479a716d3f9c9eaea3d7 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.4.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.4.0.xml index a8bfc97e6a..b069162fbd 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.4.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.4.0.xml @@ -18,6 +18,7 @@ + 7:36ef39ed560ad07062d956db861042ba diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.5.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.5.0.xml index 81689ce6ef..5191228e10 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.5.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.5.0.xml @@ -18,6 +18,7 @@ + 7:cf12b04b79bea5152f165eb41f3955f6 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.6.1.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.6.1.xml index 4b2066f4c8..96f5048740 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.6.1.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.6.1.xml @@ -18,6 +18,7 @@ + 7:7e32c8f05c755e8675764e7d5f514509 @@ -83,6 +84,7 @@ + 7:980ba23cc0ec39cab731ce903dd01291 @@ -100,6 +102,7 @@ + 7:2fa220758991285312eb84f3b4ff5336 @@ -134,6 +137,7 @@ + 7:d41d8cd98f00b204e9800998ecf8427e \ No newline at end of file diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.7.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.7.0.xml index da10347efd..b09e367696 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.7.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.7.0.xml @@ -18,6 +18,7 @@ + 7:91ace540896df890cc00a0490ee52bbc diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.8.0-db2.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.8.0-db2.xml index f43b8a4fa8..9a1ebbb03d 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.8.0-db2.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.8.0-db2.xml @@ -18,6 +18,7 @@ + 7:f987971fe6b37d963bc95fee2b27f8df @@ -137,6 +138,7 @@ + 7:df8bc21027a4f7cbbb01f6344e89ce07 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.8.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.8.0.xml index 5ebd8d40f7..c77b7f3883 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.8.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.8.0.xml @@ -18,6 +18,7 @@ + 7:c31d1646dfa2618a9335c00e07f89f24 @@ -135,6 +136,7 @@ + 7:df8bc21027a4f7cbbb01f6344e89ce07 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.0.xml index d86b502168..e5eb5b2619 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.0.xml @@ -18,6 +18,7 @@ + 7:ed2dc7f799d19ac452cbcda56c929e47 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.1-db2.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.1-db2.xml index 42558a7063..11514d9ac9 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.1-db2.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.1-db2.xml @@ -18,6 +18,7 @@ + 7:1437310ed1305a9b93f8848f301726ce diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.1.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.1.xml index c083bc9a2b..7623a8eaef 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.1.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.1.xml @@ -18,6 +18,7 @@ + 7:80b5db88a5dda36ece5f235be8757615 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.2.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.2.xml index 4a9ce9a873..88b3a11574 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.2.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-1.9.2.xml @@ -18,6 +18,7 @@ + 7:b82ffb34850fa0836be16deefc6a87c4 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-11.0.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-11.0.0.xml index 34c4c9cd22..fd2df947d4 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-11.0.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-11.0.0.xml @@ -18,6 +18,7 @@ + 7:3dace6b144c11f53f1ad2c0361279b86 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-12.0.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-12.0.0.xml index b0f14f244b..ebdce99adb 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-12.0.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-12.0.0.xml @@ -18,6 +18,7 @@ + 7:578d0b92077eaf2ab95ad0ec087aa903 @@ -27,6 +28,7 @@ + 7:c95abe90d962c57a09ecaee57972835d diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-13.0.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-13.0.0.xml index 0868fd1f34..a1515ef4fd 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-13.0.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-13.0.0.xml @@ -18,6 +18,7 @@ + 7:f1313bcc2994a5c4dc1062ed6d8282d3 @@ -26,11 +27,13 @@ + 7:90d763b52eaffebefbcbde55f269508b + 7:d554f0cb92b764470dccfa5e0014a7dd @@ -39,6 +42,7 @@ + 7:73193e3ab3c35cf0f37ccea3bf783764 @@ -48,6 +52,7 @@ + 7:90a1e74f92e9cbaa0c5eab80b8a037f3 @@ -58,11 +63,13 @@ + 7:5b9248f29cd047c200083cc6d8388b16 + 7:64db59e44c374f13955489e8990d17a1 @@ -79,6 +86,7 @@ + 7:329a578cdb43262fff975f0a7f6cda60 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-14.0.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-14.0.0.xml index 47665d0bbb..42654d5cdb 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-14.0.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-14.0.0.xml @@ -18,6 +18,7 @@ + 7:fae0de241ac0fd0bbc2b380b85e4f567 @@ -37,6 +38,7 @@ + 7:075d54e9180f49bb0c64ca4218936e81 @@ -47,6 +49,7 @@ + 7:06499836520f4f6b3d05e35a59324910 @@ -58,6 +61,9 @@ + 7:fad08e83c77d0171ec166bc9bc5d390a + 7:72553fac2d2281052acbbbb14aa22ccf + 7:b558ad47ea0e4d3c3514225a49cc0d65 @@ -79,6 +85,7 @@ + 7:3d2b23076e59c6f70bae703aa01be35b @@ -96,6 +103,7 @@ + 7:1a7f28ff8d9e53aeb879d76ea3d9341a @@ -103,6 +111,7 @@ + 7:2fd554456fed4a82c698c555c5b751b6 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-15.0.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-15.0.0.xml index 6215dd4a59..7748acb931 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-15.0.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-15.0.0.xml @@ -19,6 +19,7 @@ + 7:b06356d66c2790ecc2ae54ba0458397a diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-17.0.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-17.0.0.xml index ba034fbb02..511b8c6b8a 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-17.0.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-17.0.0.xml @@ -18,6 +18,7 @@ + 7:467c7f7d35d0697dde968b1be60730a6 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.1.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.1.0.xml index a65a323f67..c2f8fd8b9a 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.1.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.1.0.xml @@ -18,6 +18,7 @@ + 7:f1f9fd8710399d725b780f463c6b21cd diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.2.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.2.0.xml index adc49fbf3d..f1ff268302 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.2.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.2.0.xml @@ -19,6 +19,7 @@ + 7:53188c3eb1107546e6f765835705b6c1 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.3.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.3.0.xml index 579aa04088..ef9905839d 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.3.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.3.0.xml @@ -19,6 +19,7 @@ + 7:d6e6f3bc57a0c5586737d1351725d4d4 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.4.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.4.0.xml index 0aebd9a0d2..c18168c046 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.4.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.4.0.xml @@ -19,6 +19,7 @@ + 7:454d604fbd755d9df3fd9c6329043aa5 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.5.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.5.0.xml index 0c0a8d038b..fcadd4ea2a 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.5.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.5.0.xml @@ -19,12 +19,14 @@ + 7:57e98a3077e29caf562f7dbf80c72600 + 7:e4c7e8f2256210aee71ddc42f538b57a @@ -62,6 +64,7 @@ + 7:09a43c97e49bc626460480aa1379b522 @@ -100,6 +103,7 @@ + 7:26bfc7c74fefa9126f2ce702fb775553 @@ -111,6 +115,7 @@ + 7:a161e2ae671a9020fff61e996a207377 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.5.1.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.5.1.xml index 3184134695..bd11c52302 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-2.5.1.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-2.5.1.xml @@ -19,6 +19,7 @@ + 7:37fc1781855ac5388c494f1442b3f717 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-3.0.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-3.0.0.xml index 5ac745cd71..0c4c7184ee 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-3.0.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-3.0.0.xml @@ -19,6 +19,7 @@ + 7:13a27db0dae6049541136adad7261d27 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-3.2.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-3.2.0.xml index a5303e1b14..c87dd8f520 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-3.2.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-3.2.0.xml @@ -25,6 +25,7 @@ --> + 7:550300617e3b59e8af3a6294df8248a3 @@ -36,6 +37,7 @@ + 7:e3a9482b8931481dc2772a5c07c44f17 @@ -49,6 +51,7 @@ + 7:72b07d85a2677cb257edb02b408f332d @@ -62,6 +65,7 @@ + 7:a72a7858967bd414835d19e04d880312 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-3.3.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-3.3.0.xml index e615a94ce6..174bfe40a1 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-3.3.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-3.3.0.xml @@ -18,6 +18,7 @@ + 7:94edff7cf9ce179e7e85f0cd78a3cf2c diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-3.4.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-3.4.0.xml index b220cb2e58..47a20837b6 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-3.4.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-3.4.0.xml @@ -18,6 +18,7 @@ + 7:0f88b78b7b46480eb92690cbf5e44900 @@ -48,7 +49,7 @@ - + 7:d560e43982611d936457c327f872dd59 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-3.4.1.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-3.4.1.xml index 460d53bc45..8279111b67 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-3.4.1.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-3.4.1.xml @@ -18,6 +18,7 @@ + 7:c155566c42b4d14ef07059ec3b3bbd8e diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-3.4.2.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-3.4.2.xml index 4c1e6fb4db..8f625476d8 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-3.4.2.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-3.4.2.xml @@ -18,6 +18,7 @@ + 7:b40376581f12d70f3c89ba8ddf5b7dea @@ -26,6 +27,7 @@ + 7:a1132cc395f7b95b3646146c2e38f168 PROTOCOL IS NULL diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-4.0.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-4.0.0.xml index 727852f974..83257ef433 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-4.0.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-4.0.0.xml @@ -18,6 +18,7 @@ + 7:d8dc5d89c789105cfa7ca0e82cba60af @@ -30,9 +31,11 @@ + 7:7822e0165097182e8f653c35517656a3 + 7:c6538c29b9c9a08f9e9ea2de5c2b6375 @@ -86,6 +89,7 @@ + 7:6d4893e36de22369cf73bcb051ded875 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-4.2.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-4.2.0.xml index be0202b69c..fd0de51b39 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-4.2.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-4.2.0.xml @@ -18,6 +18,7 @@ + 7:14d407c35bc4fe1976867756bcea0c36 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-4.3.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-4.3.0.xml index 14dd8eb4e4..fc077cfeda 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-4.3.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-4.3.0.xml @@ -18,6 +18,7 @@ + 7:241a8030c748c8548e346adee548fa93 PRIORITY is NULL diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-4.6.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-4.6.0.xml index 64ac38f8da..bddc2844e5 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-4.6.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-4.6.0.xml @@ -18,6 +18,7 @@ + 7:7d3182f65a34fcc61e8d23def037dc3f NAME LIKE 'group.resource.%' @@ -25,6 +26,7 @@ + 7:b30039e00a0b9715d430d1b0636728fa @@ -45,6 +47,7 @@ + 7:3797315ca61d531780f8e6f82f258159 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-4.7.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-4.7.0.xml index 43a98713c8..a4bb9ed5fd 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-4.7.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-4.7.0.xml @@ -18,6 +18,7 @@ + 7:c7aa4c8d9573500c2d347c1941ff0301 @@ -26,6 +27,7 @@ + 7:b207faee394fc074a442ecd42185a5dd diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-4.8.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-4.8.0.xml index 9af26f46ce..7a7a7b41fe 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-4.8.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-4.8.0.xml @@ -18,6 +18,7 @@ + 7:ab9a9762faaba4ddfa35514b212c4922 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-8.0.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-8.0.0.xml index 655e455175..32f5db79c3 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-8.0.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-8.0.0.xml @@ -19,6 +19,7 @@ + 7:ec9707ae4d4f0b7452fee20128083879 @@ -53,6 +54,7 @@ + 7:3979a0ae07ac465e920ca696532fc736 @@ -117,6 +119,7 @@ + 7:5abfde4c259119d143bd2fbf49ac2bca @@ -178,6 +181,7 @@ + 7:b48da8c11a3d83ddd6b7d0c8c2219345 @@ -219,6 +223,7 @@ + 7:a73379915c23bfad3e8f5c6d5c0aa4bd diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-9.0.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-9.0.0.xml index 0444502723..ef17b6b1e6 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-9.0.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-9.0.0.xml @@ -18,6 +18,7 @@ + 7:39e0073779aba192646291aa2332493d @@ -26,6 +27,7 @@ + 7:81f87368f00450799b4bf42ea0b3ec34 @@ -37,6 +39,7 @@ + 7:20b37422abb9fb6571c618148f013a15 @@ -49,6 +52,7 @@ + 7:1970bb6cfb5ee800736b95ad3fb3c78a diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-9.0.1.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-9.0.1.xml index 4019502d39..516d24d36e 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-9.0.1.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-9.0.1.xml @@ -18,12 +18,14 @@ + 7:45d9b25fc3b455d522d8dcc10a0f4c80 + 7:890ae73712bc187a66c2813a724d037f @@ -32,12 +34,14 @@ + 7:0a211980d27fafe3ff50d19a3a29b538 + 7:a161e2ae671a9020fff61e996a207377 @@ -46,6 +50,7 @@ + 7:01c49302201bdf815b0a18d1f98a55dc diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-2.0.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-2.0.0.xml index 6e7d6068c8..b5123ea984 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-2.0.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-2.0.0.xml @@ -19,6 +19,7 @@ + 7:9cc98082921330d8d9266decdd4bd658 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-2.5.1.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-2.5.1.xml index cb0e7ccf1d..a0a024b59a 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-2.5.1.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-2.5.1.xml @@ -18,6 +18,7 @@ + 7:03d64aeed9cb52b969bd30a7ac0db57e TYPE = :value diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-3.4.0.CR1.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-3.4.0.CR1.xml index 0318049f7f..28e64c2353 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-3.4.0.CR1.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-3.4.0.CR1.xml @@ -18,6 +18,7 @@ + 7:6a48ce645a3525488a90fbf76adf3bb3 @@ -31,6 +32,7 @@ + 7:e64b5dcea7db06077c6e57d3b9e5ca14 @@ -41,6 +43,7 @@ + 7:fd8cf02498f8b1e72496a20afc75178c @@ -54,6 +57,7 @@ + 7:542794f25aa2b1fbabb7e577d6646319 @@ -117,6 +121,7 @@ + 7:edad604c882df12f74941dac3cc6d650 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-4.0.0.Beta3.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-4.0.0.Beta3.xml index e5073da4ba..3cb77697bc 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-4.0.0.Beta3.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-4.0.0.Beta3.xml @@ -18,6 +18,7 @@ + 7:2b4b8bff39944c7097977cc18dbceb3b diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-4.0.0.CR1.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-4.0.0.CR1.xml index 6666052cf7..c59954a788 100755 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-4.0.0.CR1.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-4.0.0.CR1.xml @@ -18,6 +18,7 @@ + 7:57960fc0b0f0dd0563ea6f8b2e4a1707 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-4.2.0.Final.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-4.2.0.Final.xml index 900a751473..78824050b3 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-4.2.0.Final.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-4.2.0.Final.xml @@ -18,6 +18,7 @@ + 7:2aa42a964c59cd5b8ca9822340ba33a8 @@ -35,6 +36,7 @@ + 7:9ac9e58545479929ba23f4a3087a0346 diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-7.0.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-7.0.0.xml index c67315cab6..676843e228 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-7.0.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-authz-7.0.0.xml @@ -18,6 +18,7 @@ + 7:b9710f74515a6ccb51b72dc0d19df8c4 diff --git a/model/jpa/src/main/resources/META-INF/services/liquibase.change.Change b/model/jpa/src/main/resources/META-INF/services/liquibase.change.Change new file mode 100644 index 0000000000..526e8c6f76 --- /dev/null +++ b/model/jpa/src/main/resources/META-INF/services/liquibase.change.Change @@ -0,0 +1,18 @@ +# +# 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. +# + +org.keycloak.connections.jpa.updater.liquibase.custom.CustomCreateIndexChange \ No newline at end of file diff --git a/model/jpa/src/main/resources/META-INF/services/liquibase.changelog.ChangeLogHistoryService b/model/jpa/src/main/resources/META-INF/services/liquibase.changelog.ChangeLogHistoryService new file mode 100644 index 0000000000..4ff1eb6cb7 --- /dev/null +++ b/model/jpa/src/main/resources/META-INF/services/liquibase.changelog.ChangeLogHistoryService @@ -0,0 +1,18 @@ +# +# 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. +# + +org.keycloak.connections.jpa.updater.liquibase.conn.CustomChangeLogHistoryService \ No newline at end of file diff --git a/model/jpa/src/main/resources/META-INF/services/liquibase.database.Database b/model/jpa/src/main/resources/META-INF/services/liquibase.database.Database new file mode 100644 index 0000000000..238e52b6de --- /dev/null +++ b/model/jpa/src/main/resources/META-INF/services/liquibase.database.Database @@ -0,0 +1,20 @@ +# +# 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. +# + +org.keycloak.connections.jpa.updater.liquibase.PostgresPlusDatabase +org.keycloak.connections.jpa.updater.liquibase.UpdatedMariaDBDatabase +org.keycloak.connections.jpa.updater.liquibase.UpdatedMySqlDatabase \ No newline at end of file diff --git a/model/jpa/src/main/resources/META-INF/services/liquibase.datatype.LiquibaseDataType b/model/jpa/src/main/resources/META-INF/services/liquibase.datatype.LiquibaseDataType new file mode 100644 index 0000000000..cd6d9012e2 --- /dev/null +++ b/model/jpa/src/main/resources/META-INF/services/liquibase.datatype.LiquibaseDataType @@ -0,0 +1,18 @@ +# +# 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. +# + +org.keycloak.connections.jpa.updater.liquibase.MySQL8VarcharType \ No newline at end of file diff --git a/model/jpa/src/main/resources/META-INF/services/liquibase.lockservice.LockService b/model/jpa/src/main/resources/META-INF/services/liquibase.lockservice.LockService new file mode 100644 index 0000000000..6ba4df9901 --- /dev/null +++ b/model/jpa/src/main/resources/META-INF/services/liquibase.lockservice.LockService @@ -0,0 +1,18 @@ +# +# 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. +# + +org.keycloak.connections.jpa.updater.liquibase.lock.DummyLockService \ No newline at end of file diff --git a/model/jpa/src/main/resources/META-INF/services/liquibase.logging.LogService b/model/jpa/src/main/resources/META-INF/services/liquibase.logging.LogService new file mode 100644 index 0000000000..56b9b3901c --- /dev/null +++ b/model/jpa/src/main/resources/META-INF/services/liquibase.logging.LogService @@ -0,0 +1,18 @@ +# +# 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. +# + +org.keycloak.connections.jpa.updater.liquibase.log.KeycloakLogService \ No newline at end of file diff --git a/model/jpa/src/main/resources/META-INF/services/liquibase.sqlgenerator.SqlGenerator b/model/jpa/src/main/resources/META-INF/services/liquibase.sqlgenerator.SqlGenerator new file mode 100644 index 0000000000..198224d3b9 --- /dev/null +++ b/model/jpa/src/main/resources/META-INF/services/liquibase.sqlgenerator.SqlGenerator @@ -0,0 +1,19 @@ +# +# 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. +# + +org.keycloak.connections.jpa.updater.liquibase.lock.CustomInsertLockRecordGenerator +org.keycloak.connections.jpa.updater.liquibase.lock.CustomLockDatabaseChangeLogGenerator \ No newline at end of file diff --git a/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/liquibase/connection/DefaultLiquibaseConnectionProvider.java b/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/liquibase/connection/DefaultLiquibaseConnectionProvider.java index 4085c50d8f..4220c9f4ce 100644 --- a/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/liquibase/connection/DefaultLiquibaseConnectionProvider.java +++ b/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/liquibase/connection/DefaultLiquibaseConnectionProvider.java @@ -18,25 +18,16 @@ package org.keycloak.models.map.storage.jpa.liquibase.connection; import java.sql.Connection; -import java.util.concurrent.atomic.AtomicBoolean; import liquibase.Liquibase; -import liquibase.change.ChangeFactory; import liquibase.database.Database; import liquibase.database.DatabaseFactory; import liquibase.database.jvm.JdbcConnection; -import liquibase.datatype.DataTypeFactory; import liquibase.exception.LiquibaseException; import liquibase.resource.ClassLoaderResourceAccessor; import liquibase.resource.ResourceAccessor; -import liquibase.sqlgenerator.SqlGeneratorFactory; import org.jboss.logging.Logger; import org.keycloak.models.KeycloakSession; -import org.keycloak.models.map.storage.jpa.liquibase.extension.GeneratedColumnSqlGenerator; -import org.keycloak.models.map.storage.jpa.liquibase.extension.CreateJsonIndexChange; -import org.keycloak.models.map.storage.jpa.liquibase.extension.CreateJsonIndexGenerator; -import org.keycloak.models.map.storage.jpa.liquibase.extension.GeneratedColumnChange; -import org.keycloak.models.map.storage.jpa.liquibase.extension.JsonDataType; /** * A {@link MapLiquibaseConnectionProvider} implementation for the map-jpa module. This provider registers the custom {@code Liquibase} @@ -53,35 +44,8 @@ public class DefaultLiquibaseConnectionProvider implements MapLiquibaseConnectio private static final Logger logger = Logger.getLogger(DefaultLiquibaseConnectionProvider.class); - private static final AtomicBoolean INITIALIZED = new AtomicBoolean(false); - + @SuppressWarnings("unused") public DefaultLiquibaseConnectionProvider(final KeycloakSession session) { - if (! INITIALIZED.get()) { - // TODO: all liquibase providers should probably synchronize on the same object. - synchronized (INITIALIZED) { - if (! INITIALIZED.get()) { - initializeLiquibase(); - INITIALIZED.set(true); - } - } - } - } - - /** - * Registers the custom changes/types so we can work with data stored in JSON format. - */ - protected void initializeLiquibase() { - - // Add custom JSON data type - DataTypeFactory.getInstance().register(JsonDataType.class); - - // Add custom change to generate columns from properties in JSON files stored in the DB. - ChangeFactory.getInstance().register(GeneratedColumnChange.class); - SqlGeneratorFactory.getInstance().register(new GeneratedColumnSqlGenerator()); - - // Add custom change to create indexes for properties in JSON files stored in the DB. - ChangeFactory.getInstance().register(CreateJsonIndexChange.class); - SqlGeneratorFactory.getInstance().register(new CreateJsonIndexGenerator()); } @Override diff --git a/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/liquibase/extension/CreateJsonIndexGenerator.java b/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/liquibase/extension/CreateJsonIndexGenerator.java index 021fade57d..d08a4bde6b 100644 --- a/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/liquibase/extension/CreateJsonIndexGenerator.java +++ b/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/liquibase/extension/CreateJsonIndexGenerator.java @@ -31,7 +31,7 @@ import liquibase.sqlgenerator.core.AbstractSqlGenerator; import liquibase.statement.core.CreateIndexStatement; import liquibase.structure.core.Index; import liquibase.structure.core.Table; -import liquibase.util.StringUtils; +import liquibase.util.StringUtil; /** * A {@link SqlGenerator} implementation that supports {@link CreateJsonIndexStatement}s. It generates the SQL required @@ -88,7 +88,7 @@ public class CreateJsonIndexGenerator extends AbstractSqlGenerator returnSql = new ArrayList<>(); returnSql.add(new UnparsedSql(sqlBuilder.toString(), super.getAffectedColumn(statement))); - super.addUniqueConstrantStatements(statement, database, returnSql); + super.addUniqueConstraintStatements(statement, database, returnSql); super.addForeignKeyStatements(statement, database, returnSql); return returnSql.toArray(new Sql[0]); diff --git a/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/liquibase/extension/JsonDataType.java b/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/liquibase/extension/JsonDataType.java index 8e6a10796f..58b7c446db 100644 --- a/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/liquibase/extension/JsonDataType.java +++ b/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/liquibase/extension/JsonDataType.java @@ -17,6 +17,7 @@ package org.keycloak.models.map.storage.jpa.liquibase.extension; +import liquibase.change.core.LoadDataChange; import liquibase.database.Database; import liquibase.database.core.PostgresDatabase; import liquibase.datatype.DataTypeInfo; @@ -39,4 +40,9 @@ public class JsonDataType extends LiquibaseDataType { } return super.toDatabaseDataType(database); } + + @Override + public LoadDataChange.LOAD_DATA_TYPE getLoadTypeName() { + return LoadDataChange.LOAD_DATA_TYPE.UNKNOWN; + } } diff --git a/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/liquibase/updater/MapJpaLiquibaseUpdaterProvider.java b/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/liquibase/updater/MapJpaLiquibaseUpdaterProvider.java index 1a79a8842e..b23a1b20d1 100644 --- a/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/liquibase/updater/MapJpaLiquibaseUpdaterProvider.java +++ b/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/liquibase/updater/MapJpaLiquibaseUpdaterProvider.java @@ -22,7 +22,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.List; @@ -33,7 +32,6 @@ import liquibase.changelog.ChangeSet; import liquibase.changelog.RanChangeSet; import liquibase.exception.LiquibaseException; import org.jboss.logging.Logger; -import org.keycloak.common.util.reflections.Reflections; import org.keycloak.connections.jpa.updater.liquibase.ThreadLocalSessionContext; import org.keycloak.models.KeycloakSession; import org.keycloak.models.map.storage.ModelEntityUtil; @@ -72,7 +70,7 @@ public class MapJpaLiquibaseUpdaterProvider implements MapJpaUpdaterProvider { exportWriter = new FileWriter(file); } - updateChangeSet(liquibase, connection); + updateChangeSet(liquibase); } catch (LiquibaseException | IOException | SQLException e) { logger.error("Error has occurred while updating the database", e); @@ -89,9 +87,9 @@ public class MapJpaLiquibaseUpdaterProvider implements MapJpaUpdaterProvider { } } - protected void updateChangeSet(Liquibase liquibase, Connection connection) throws LiquibaseException, SQLException { + protected void updateChangeSet(Liquibase liquibase) throws LiquibaseException, SQLException { String changelog = liquibase.getChangeLogFile(); - List changeSets = getLiquibaseUnrunChangeSets(liquibase); + List changeSets = this.getLiquibaseUnrunChangeSets(liquibase); if (!changeSets.isEmpty()) { List ranChangeSets = liquibase.getDatabase().getRanChangeSetList(); if (ranChangeSets.isEmpty()) { @@ -135,7 +133,7 @@ public class MapJpaLiquibaseUpdaterProvider implements MapJpaUpdaterProvider { protected Status validateChangeSet(Liquibase liquibase, String changelog) throws LiquibaseException { final Status result; - List changeSets = getLiquibaseUnrunChangeSets(liquibase); + List changeSets = this.getLiquibaseUnrunChangeSets(liquibase); if (!changeSets.isEmpty()) { if (changeSets.size() == liquibase.getDatabaseChangeLog().getChangeSets().size()) { @@ -152,13 +150,8 @@ public class MapJpaLiquibaseUpdaterProvider implements MapJpaUpdaterProvider { return result; } - @SuppressWarnings("unchecked") - private List 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 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 getLiquibaseUnrunChangeSets(Liquibase liquibase) throws LiquibaseException { + return liquibase.listUnrunChangeSets(null, new LabelExpression(), false); } private Liquibase getLiquibase(Class modelType, Connection connection, String defaultSchema) throws LiquibaseException { diff --git a/model/map-jpa/src/main/resources/META-INF/services/liquibase.change.Change b/model/map-jpa/src/main/resources/META-INF/services/liquibase.change.Change new file mode 100644 index 0000000000..c4cc8ec7ae --- /dev/null +++ b/model/map-jpa/src/main/resources/META-INF/services/liquibase.change.Change @@ -0,0 +1,19 @@ +# +# 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. +# + +org.keycloak.models.map.storage.jpa.liquibase.extension.CreateJsonIndexChange +org.keycloak.models.map.storage.jpa.liquibase.extension.GeneratedColumnChange \ No newline at end of file diff --git a/model/map-jpa/src/main/resources/META-INF/services/liquibase.datatype.LiquibaseDataType b/model/map-jpa/src/main/resources/META-INF/services/liquibase.datatype.LiquibaseDataType new file mode 100644 index 0000000000..26617e188e --- /dev/null +++ b/model/map-jpa/src/main/resources/META-INF/services/liquibase.datatype.LiquibaseDataType @@ -0,0 +1,18 @@ +# +# 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. +# + +org.keycloak.models.map.storage.jpa.liquibase.extension.JsonDataType \ No newline at end of file diff --git a/model/map-jpa/src/main/resources/META-INF/services/liquibase.sqlgenerator.SqlGenerator b/model/map-jpa/src/main/resources/META-INF/services/liquibase.sqlgenerator.SqlGenerator new file mode 100644 index 0000000000..b882dd0a75 --- /dev/null +++ b/model/map-jpa/src/main/resources/META-INF/services/liquibase.sqlgenerator.SqlGenerator @@ -0,0 +1,19 @@ +# +# 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. +# + +org.keycloak.models.map.storage.jpa.liquibase.extension.CreateJsonIndexGenerator +org.keycloak.models.map.storage.jpa.liquibase.extension.GeneratedColumnSqlGenerator \ No newline at end of file diff --git a/pom.xml b/pom.xml index b85e376308..54a4eb10e0 100644 --- a/pom.xml +++ b/pom.xml @@ -131,7 +131,7 @@ 2.3.31 ${jetty92.version} - 3.5.5 + 4.6.2 4.2.0 7.1.0 1.0.2.Final diff --git a/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/LiquibaseProcessor.java b/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/LiquibaseProcessor.java index 0920818410..7ddb23c864 100644 --- a/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/LiquibaseProcessor.java +++ b/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/LiquibaseProcessor.java @@ -15,17 +15,13 @@ import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.jboss.jandex.IndexView; -import org.keycloak.connections.jpa.updater.liquibase.lock.CustomInsertLockRecordGenerator; -import org.keycloak.connections.jpa.updater.liquibase.lock.CustomLockDatabaseChangeLogGenerator; import org.keycloak.connections.jpa.updater.liquibase.lock.DummyLockService; -import org.keycloak.quarkus.runtime.storage.database.liquibase.KeycloakLogger; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.annotations.ExecutionTime; import io.quarkus.deployment.annotations.Record; import liquibase.database.Database; import liquibase.lockservice.LockService; -import liquibase.logging.Logger; import liquibase.parser.ChangeLogParser; import liquibase.parser.core.xml.XMLChangeLogSAXParser; import liquibase.servicelocator.LiquibaseService; @@ -47,13 +43,11 @@ class LiquibaseProcessor { liquibase.parser.NamespaceDetails.class, liquibase.precondition.Precondition.class, Database.class, - ChangeLogParser.class, liquibase.change.Change.class, liquibase.snapshot.SnapshotGenerator.class, liquibase.changelog.ChangeLogHistoryService.class, liquibase.datatype.LiquibaseDataType.class, liquibase.executor.Executor.class, - LockService.class, SqlGenerator.class)) { List impls = new ArrayList<>(); services.put(c.getName(), impls); @@ -78,11 +72,8 @@ class LiquibaseProcessor { } } - services.put(Logger.class.getName(), Arrays.asList(KeycloakLogger.class.getName())); services.put(LockService.class.getName(), Arrays.asList(DummyLockService.class.getName())); services.put(ChangeLogParser.class.getName(), Arrays.asList(XMLChangeLogSAXParser.class.getName())); - services.get(SqlGenerator.class.getName()).add(CustomInsertLockRecordGenerator.class.getName()); - services.get(SqlGenerator.class.getName()).add(CustomLockDatabaseChangeLogGenerator.class.getName()); recorder.configureLiquibase(services); } diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakRecorder.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakRecorder.java index 0b3003993d..65b0ea138c 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakRecorder.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakRecorder.java @@ -20,6 +20,7 @@ package org.keycloak.quarkus.runtime; import java.util.List; import java.util.Map; +import liquibase.Scope; import org.infinispan.configuration.parsing.ConfigurationBuilderHolder; import org.infinispan.configuration.parsing.ParserRegistry; import org.infinispan.jboss.marshalling.core.JBossUserMarshaller; @@ -31,7 +32,6 @@ import org.keycloak.common.Profile; import org.keycloak.quarkus.runtime.configuration.Configuration; import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory; import org.keycloak.quarkus.runtime.storage.database.liquibase.FastServiceLocator; -import org.keycloak.quarkus.runtime.storage.database.liquibase.KeycloakLogger; import org.keycloak.provider.Provider; import org.keycloak.provider.ProviderFactory; import org.keycloak.provider.Spi; @@ -40,34 +40,15 @@ import org.keycloak.quarkus.runtime.storage.infinispan.CacheManagerFactory; import io.quarkus.runtime.RuntimeValue; import io.quarkus.runtime.ShutdownContext; import io.quarkus.runtime.annotations.Recorder; -import liquibase.logging.LogFactory; import liquibase.servicelocator.ServiceLocator; @Recorder public class KeycloakRecorder { public void configureLiquibase(Map> services) { - LogFactory.setInstance(new LogFactory() { - final KeycloakLogger logger = new KeycloakLogger(); - - @Override - public liquibase.logging.Logger getLog(String name) { - return logger; - } - - @Override - public liquibase.logging.Logger getLog() { - return logger; - } - }); - - // we set this property to avoid Liquibase to lookup resources from the classpath and access JAR files - // we already index the packages we want so Liquibase will still be able to load these services - // for uber-jar, this is not a problem because everything is inside the JAR, but once we move to fast-jar we'll have performance penalties - // it seems that v4 of liquibase provides a more smart way of initialization the ServiceLocator that may allow us to remove this - System.setProperty("liquibase.scan.packages", "org.liquibase.core"); - - ServiceLocator.setInstance(new FastServiceLocator(services)); + ServiceLocator locator = Scope.getCurrentScope().getServiceLocator(); + if (locator instanceof FastServiceLocator) + ((FastServiceLocator) locator).initServices(services); } public void configSessionFactory( diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/FastServiceLocator.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/FastServiceLocator.java index cb16345fee..2e6eda8c9c 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/FastServiceLocator.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/FastServiceLocator.java @@ -17,108 +17,48 @@ package org.keycloak.quarkus.runtime.storage.database.liquibase; -import java.util.HashSet; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; -import liquibase.database.DatabaseFactory; import liquibase.exception.ServiceNotFoundException; +import liquibase.servicelocator.StandardServiceLocator; -import liquibase.database.Database; -import liquibase.logging.Logger; -import liquibase.servicelocator.DefaultPackageScanClassResolver; -import liquibase.servicelocator.ServiceLocator; +public class FastServiceLocator extends StandardServiceLocator { -public class FastServiceLocator extends ServiceLocator { + private Map> services = new HashMap<>(); - private final Map> services; - - public FastServiceLocator(Map> services) { - super(new DefaultPackageScanClassResolver() { - @Override - public Set> findImplementations(Class parent, String... packageNames) { - List found = services.get(parent.getName()); - - if (found == null) { - return super.findImplementations(parent, packageNames); - } - - Set> ret = new HashSet<>(); - for (String i : found) { - try { - ret.add(Class.forName(i, false, Thread.currentThread().getContextClassLoader())); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - } - return ret; - } - }); - - if (!System.getProperties().containsKey("liquibase.scan.packages")) { - if (getPackages().remove("liquibase.core")) { - addPackageToScan("liquibase.core.xml"); - } - - if (getPackages().remove("liquibase.parser")) { - addPackageToScan("liquibase.parser.core.xml"); - } - - if (getPackages().remove("liquibase.serializer")) { - addPackageToScan("liquibase.serializer.core.xml"); - } - - getPackages().remove("liquibase.ext"); - getPackages().remove("liquibase.sdk"); - } - - // we only need XML parsers - getPackages().remove("liquibase.parser.core.yaml"); - getPackages().remove("liquibase.serializer.core.yaml"); - getPackages().remove("liquibase.parser.core.json"); - getPackages().remove("liquibase.serializer.core.json"); - - // register only the implementations related to the chosen db - for (String databaseImpl : services.get(Database.class.getName())) { - try { - register((Database) getClass().getClassLoader().loadClass(databaseImpl).getDeclaredConstructor().newInstance()); - } catch (Exception cause) { - throw new RuntimeException("Failed to load database implementation", cause); - } - } - - this.services = services; + @Override + public int getPriority() { + return super.getPriority() + 1; } @Override - public Object newInstance(Class requiredInterface) throws ServiceNotFoundException { - if (Logger.class.equals(requiredInterface)) { - return new KeycloakLogger(); - } - return super.newInstance(requiredInterface); - } - - @Override - public Class[] findClasses(Class requiredInterface) throws ServiceNotFoundException { - List found = services.get(requiredInterface.getName()); + @SuppressWarnings("unchecked") + public List findInstances(Class interfaceType) throws ServiceNotFoundException { + List found = services.get(interfaceType.getName()); if (found == null) { - return super.findClasses(requiredInterface); + return super.findInstances(interfaceType); } - Set> ret = new HashSet<>(); + List ret = new ArrayList<>(); for (String i : found) { try { - ret.add(Class.forName(i, false, Thread.currentThread().getContextClassLoader())); - } catch (ClassNotFoundException e) { - e.printStackTrace(); + ret.add((T) Class.forName(i, false, Thread.currentThread().getContextClassLoader()) + .getDeclaredConstructor().newInstance()); + } catch (Exception e) { + throw new RuntimeException("Failed to find Liquibase implementation", e); } } - return ret.toArray(new Class[ret.size()]); + return ret; } - public void register(Database database) { - DatabaseFactory.getInstance().register(database); + public FastServiceLocator() { } -} + + public void initServices(final Map> services) { + this.services = services; + } +} \ No newline at end of file diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/KeycloakLogService.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/KeycloakLogService.java new file mode 100644 index 0000000000..fbf8a01b00 --- /dev/null +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/KeycloakLogService.java @@ -0,0 +1,39 @@ +/* + * 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.quarkus.runtime.storage.database.liquibase; + +import liquibase.logging.Logger; +import liquibase.logging.core.AbstractLogService; + +/** + * A {@link liquibase.logging.LogService} implementation that creates instances of {@link org.keycloak.connections.jpa.updater.liquibase.log.KeycloakLogger}. + * + * @author Stefan Guilhen + */ +public class KeycloakLogService extends AbstractLogService { + + @Override + public int getPriority() { + return PRIORITY_DEFAULT + 1; + } + + @Override + public Logger getLog(Class clazz) { + return new KeycloakLogger(clazz); + } +} diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/KeycloakLogger.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/KeycloakLogger.java index 69d05404ac..65963713bb 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/KeycloakLogger.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/KeycloakLogger.java @@ -17,104 +17,86 @@ package org.keycloak.quarkus.runtime.storage.database.liquibase; -import liquibase.changelog.ChangeSet; -import liquibase.changelog.DatabaseChangeLog; -import liquibase.logging.LogLevel; -import liquibase.logging.Logger; +import java.util.logging.Level; -public class KeycloakLogger implements Logger { +import liquibase.logging.core.AbstractLogger; +import liquibase.logging.core.DefaultLogMessageFilter; +import org.jboss.logging.Logger; - private static final org.jboss.logging.Logger logger = org.jboss.logging.Logger.getLogger(KeycloakLogger.class); - - @Override - public void setName(String name) { - } +/** + * A {@link liquibase.logging.Logger} implementation that delegates to a JBoss {@link Logger}. + * + * @author Stefan Guilhen + */ +public class KeycloakLogger extends AbstractLogger { - @Override - public void setLogLevel(String logLevel, String logFile) { + private final Logger delegate; + + public KeycloakLogger(final Class clazz) { + super(new DefaultLogMessageFilter()); + this.delegate = Logger.getLogger(clazz); } @Override public void severe(String message) { - logger.error(message); + this.delegate.error(message); } @Override public void severe(String message, Throwable e) { - logger.error(message, e); + this.delegate.error(message, e); } @Override public void warning(String message) { // Ignore this warning as cascaded drops doesn't work anyway with all DBs, which we need to support if ("Database does not support drop with cascade".equals(message)) { - logger.debug(message); + this.delegate.debug(message); } else { - logger.warn(message); + this.delegate.warn(message); } } @Override public void warning(String message, Throwable e) { - logger.warn(message, e); + this.delegate.warn(message, e); } @Override public void info(String message) { - logger.debug(message); + this.delegate.debug(message); } @Override public void info(String message, Throwable e) { - logger.debug(message, e); + this.delegate.debug(message, e); } @Override public void debug(String message) { - if (logger.isTraceEnabled()) { - logger.trace(message); + if (this.delegate.isTraceEnabled()) { + this.delegate.trace(message); } } - @Override - public LogLevel getLogLevel() { - if (logger.isTraceEnabled()) { - return LogLevel.DEBUG; - } else if (logger.isDebugEnabled()) { - return LogLevel.INFO; - } else { - return LogLevel.WARNING; - } - } - - @Override - public void setLogLevel(String level) { - } - - @Override - public void setLogLevel(LogLevel level) { - } - @Override public void debug(String message, Throwable e) { - logger.trace(message, e); + this.delegate.trace(message, e); } @Override - public void setChangeLog(DatabaseChangeLog databaseChangeLog) { + public void log(Level level, String message, Throwable e) { + if (level.equals(Level.OFF)) { + return; + } else if (level.equals(Level.SEVERE)) { + this.delegate.error(message, e); + } else if (level.equals(Level.WARNING)) { + this.delegate.warn(message, e); + } else if (level.equals(Level.INFO)) { + this.delegate.debug(message, e); + } else if (level.equals(Level.FINE) | level.equals(Level.FINER) | level.equals(Level.FINEST)) { + if (this.delegate.isTraceEnabled()) + this.delegate.trace(message, e); + } } - - @Override - public void setChangeSet(ChangeSet changeSet) { - } - - @Override - public int getPriority() { - return 0; - } - - @Override - public void closeLogFile() { - } - } diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/QuarkusJpaUpdaterProvider.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/QuarkusJpaUpdaterProvider.java index 80cfe115f9..2eb00d15d4 100755 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/QuarkusJpaUpdaterProvider.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/QuarkusJpaUpdaterProvider.java @@ -28,12 +28,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Function; +import liquibase.Scope; import org.jboss.logging.Logger; import org.keycloak.common.util.reflections.Reflections; import org.keycloak.connections.jpa.entityprovider.JpaEntityProvider; import org.keycloak.connections.jpa.updater.JpaUpdaterProvider; +import org.keycloak.connections.jpa.updater.liquibase.LiquibaseConstants; import org.keycloak.connections.jpa.updater.liquibase.ThreadLocalSessionContext; import org.keycloak.connections.jpa.updater.liquibase.conn.CustomChangeLogHistoryService; import org.keycloak.connections.jpa.updater.liquibase.conn.LiquibaseConnectionProvider; @@ -159,8 +160,8 @@ public class QuarkusJpaUpdaterProvider implements JpaUpdaterProvider { 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); @@ -186,7 +187,7 @@ public class QuarkusJpaUpdaterProvider implements JpaUpdaterProvider { 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); } @@ -204,22 +205,23 @@ public class QuarkusJpaUpdaterProvider implements JpaUpdaterProvider { 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(executorService.getExecutor(LiquibaseConstants.JDBC_EXECUTOR, database), 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 @@ -288,19 +290,13 @@ public class QuarkusJpaUpdaterProvider implements JpaUpdaterProvider { ChangeLogHistoryServiceFactory.getInstance().register(new CustomChangeLogHistoryService()); } - @SuppressWarnings("unchecked") private List getLiquibaseUnrunChangeSets(Liquibase liquibase) { // we don't need to fetch change sets if they were previously obtained - return changeSets.computeIfAbsent(liquibase.getChangeLogFile(), new Function>() { - @Override - public List apply(String s) { - // 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 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); + return changeSets.computeIfAbsent(liquibase.getChangeLogFile(), s -> { + try { + return liquibase.listUnrunChangeSets(null, new LabelExpression(), false); + } catch (LiquibaseException e) { + throw new RuntimeException(e); } }); } @@ -321,8 +317,4 @@ public class QuarkusJpaUpdaterProvider implements JpaUpdaterProvider { changeSets = null; } - public static String getTable(String table, String defaultSchema) { - return defaultSchema != null ? defaultSchema + "." + table : table; - } - } diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/QuarkusLiquibaseConnectionProvider.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/QuarkusLiquibaseConnectionProvider.java index e50351888c..097be18343 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/QuarkusLiquibaseConnectionProvider.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/database/liquibase/QuarkusLiquibaseConnectionProvider.java @@ -22,32 +22,23 @@ import java.sql.Connection; import javax.xml.parsers.SAXParserFactory; -import liquibase.database.core.MariaDBDatabase; -import liquibase.database.core.MySQLDatabase; import org.jboss.logging.Logger; import org.keycloak.Config; -import org.keycloak.connections.jpa.JpaConnectionProvider; -import org.keycloak.connections.jpa.JpaConnectionProviderFactory; -import org.keycloak.connections.jpa.updater.liquibase.MySQL8VarcharType; -import org.keycloak.connections.jpa.updater.liquibase.conn.CustomChangeLogHistoryService; import org.keycloak.connections.jpa.updater.liquibase.conn.LiquibaseConnectionProvider; import org.keycloak.connections.jpa.updater.liquibase.conn.LiquibaseConnectionProviderFactory; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; import liquibase.Liquibase; -import liquibase.changelog.ChangeLogHistoryServiceFactory; import liquibase.database.Database; import liquibase.database.DatabaseFactory; import liquibase.database.jvm.JdbcConnection; -import liquibase.datatype.DataTypeFactory; import liquibase.exception.LiquibaseException; import liquibase.parser.ChangeLogParser; import liquibase.parser.ChangeLogParserFactory; import liquibase.parser.core.xml.XMLChangeLogSAXParser; import liquibase.resource.ClassLoaderResourceAccessor; import liquibase.resource.ResourceAccessor; -import liquibase.servicelocator.ServiceLocator; public class QuarkusLiquibaseConnectionProvider implements LiquibaseConnectionProviderFactory, LiquibaseConnectionProvider { @@ -71,30 +62,6 @@ public class QuarkusLiquibaseConnectionProvider implements LiquibaseConnectionPr protected void baseLiquibaseInitialization(KeycloakSession session) { resourceAccessor = new ClassLoaderResourceAccessor(getClass().getClassLoader()); - FastServiceLocator locator = (FastServiceLocator) ServiceLocator.getInstance(); - - JpaConnectionProviderFactory jpaConnectionProvider = (JpaConnectionProviderFactory) session - .getKeycloakSessionFactory().getProviderFactory(JpaConnectionProvider.class); - - // registers only the database we are using - try (Connection connection = jpaConnectionProvider.getConnection()) { - Database database = DatabaseFactory.getInstance() - .findCorrectDatabaseImplementation(new JdbcConnection(connection)); - if (database.getDatabaseProductName().equals(MySQLDatabase.PRODUCT_NAME)) { - // Adding CustomVarcharType for MySQL 8 and newer - DataTypeFactory.getInstance().register(MySQL8VarcharType.class); - - ChangeLogHistoryServiceFactory.getInstance().register(new CustomChangeLogHistoryService()); - } else if (database.getDatabaseProductName().equals(MariaDBDatabase.PRODUCT_NAME)) { - // Adding CustomVarcharType for MySQL 8 and newer - DataTypeFactory.getInstance().register(MySQL8VarcharType.class); - } - - DatabaseFactory.getInstance().clearRegistry(); - locator.register(database); - } catch (Exception cause) { - throw new RuntimeException("Failed to configure Liquibase database", cause); - } // disables XML validation for (ChangeLogParser parser : ChangeLogParserFactory.getInstance().getParsers()) { diff --git a/quarkus/runtime/src/main/resources/META-INF/services/liquibase.logging.LogService b/quarkus/runtime/src/main/resources/META-INF/services/liquibase.logging.LogService new file mode 100644 index 0000000000..4aa4e92cd3 --- /dev/null +++ b/quarkus/runtime/src/main/resources/META-INF/services/liquibase.logging.LogService @@ -0,0 +1,18 @@ +# +# 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. +# + +org.keycloak.quarkus.runtime.storage.database.liquibase.KeycloakLogService \ No newline at end of file diff --git a/quarkus/runtime/src/main/resources/META-INF/services/liquibase.servicelocator.ServiceLocator b/quarkus/runtime/src/main/resources/META-INF/services/liquibase.servicelocator.ServiceLocator new file mode 100644 index 0000000000..719f9a3a22 --- /dev/null +++ b/quarkus/runtime/src/main/resources/META-INF/services/liquibase.servicelocator.ServiceLocator @@ -0,0 +1,18 @@ +# +# 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. +# + +org.keycloak.quarkus.runtime.storage.database.liquibase.FastServiceLocator \ No newline at end of file