Make QuarkusLiquibaseConnectionProvider
extending DefaultLiquibaseConnectionProvider
to allow indexCreationThreshold
working
Closes #32860 Signed-off-by: vramik <vramik@redhat.com>
This commit is contained in:
parent
493252befd
commit
87fbe23270
16 changed files with 111 additions and 168 deletions
|
@ -27,7 +27,7 @@ import io.quarkus.deployment.builditem.ShutdownContextBuildItem;
|
||||||
import io.quarkus.deployment.logging.LoggingSetupBuildItem;
|
import io.quarkus.deployment.logging.LoggingSetupBuildItem;
|
||||||
import jakarta.enterprise.context.ApplicationScoped;
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
import org.keycloak.quarkus.runtime.KeycloakRecorder;
|
import org.keycloak.quarkus.runtime.KeycloakRecorder;
|
||||||
import org.keycloak.quarkus.runtime.storage.legacy.infinispan.CacheManagerFactory;
|
import org.keycloak.quarkus.runtime.storage.infinispan.CacheManagerFactory;
|
||||||
|
|
||||||
public class CacheBuildSteps {
|
public class CacheBuildSteps {
|
||||||
|
|
||||||
|
|
|
@ -162,7 +162,7 @@ import static org.keycloak.quarkus.runtime.configuration.Configuration.getProper
|
||||||
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX;
|
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX;
|
||||||
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_QUARKUS;
|
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_QUARKUS;
|
||||||
import static org.keycloak.quarkus.runtime.configuration.QuarkusPropertiesConfigSource.QUARKUS_PROPERTY_ENABLED;
|
import static org.keycloak.quarkus.runtime.configuration.QuarkusPropertiesConfigSource.QUARKUS_PROPERTY_ENABLED;
|
||||||
import static org.keycloak.quarkus.runtime.storage.legacy.database.QuarkusJpaConnectionProviderFactory.QUERY_PROPERTY_PREFIX;
|
import static org.keycloak.quarkus.runtime.storage.database.jpa.QuarkusJpaConnectionProviderFactory.QUERY_PROPERTY_PREFIX;
|
||||||
import static org.keycloak.representations.provider.ScriptProviderDescriptor.AUTHENTICATORS;
|
import static org.keycloak.representations.provider.ScriptProviderDescriptor.AUTHENTICATORS;
|
||||||
import static org.keycloak.representations.provider.ScriptProviderDescriptor.MAPPERS;
|
import static org.keycloak.representations.provider.ScriptProviderDescriptor.MAPPERS;
|
||||||
import static org.keycloak.representations.provider.ScriptProviderDescriptor.POLICIES;
|
import static org.keycloak.representations.provider.ScriptProviderDescriptor.POLICIES;
|
||||||
|
|
|
@ -44,7 +44,7 @@ import org.keycloak.quarkus.runtime.configuration.Configuration;
|
||||||
import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider;
|
import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider;
|
||||||
import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory;
|
import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory;
|
||||||
import org.keycloak.quarkus.runtime.storage.database.liquibase.FastServiceLocator;
|
import org.keycloak.quarkus.runtime.storage.database.liquibase.FastServiceLocator;
|
||||||
import org.keycloak.quarkus.runtime.storage.legacy.infinispan.CacheManagerFactory;
|
import org.keycloak.quarkus.runtime.storage.infinispan.CacheManagerFactory;
|
||||||
import org.keycloak.representations.userprofile.config.UPConfig;
|
import org.keycloak.representations.userprofile.config.UPConfig;
|
||||||
import org.keycloak.theme.ClasspathThemeProviderFactory;
|
import org.keycloak.theme.ClasspathThemeProviderFactory;
|
||||||
import org.keycloak.truststore.TruststoreBuilder;
|
import org.keycloak.truststore.TruststoreBuilder;
|
||||||
|
|
|
@ -15,10 +15,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.keycloak.quarkus.runtime.storage.legacy.database;
|
package org.keycloak.quarkus.runtime.storage.database.jpa;
|
||||||
|
|
||||||
import static org.keycloak.connections.jpa.util.JpaUtils.configureNamedQuery;
|
import static org.keycloak.connections.jpa.util.JpaUtils.configureNamedQuery;
|
||||||
import static org.keycloak.quarkus.runtime.storage.legacy.liquibase.QuarkusJpaUpdaterProvider.VERIFY_AND_RUN_MASTER_CHANGELOG;
|
import static org.keycloak.quarkus.runtime.storage.database.liquibase.QuarkusJpaUpdaterProvider.VERIFY_AND_RUN_MASTER_CHANGELOG;
|
||||||
import static org.keycloak.models.utils.KeycloakModelUtils.runJobInTransaction;
|
import static org.keycloak.models.utils.KeycloakModelUtils.runJobInTransaction;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -54,7 +54,6 @@ import org.keycloak.provider.ProviderConfigProperty;
|
||||||
import org.keycloak.provider.ProviderConfigurationBuilder;
|
import org.keycloak.provider.ProviderConfigurationBuilder;
|
||||||
import org.keycloak.provider.ServerInfoAwareProviderFactory;
|
import org.keycloak.provider.ServerInfoAwareProviderFactory;
|
||||||
import org.keycloak.quarkus.runtime.Environment;
|
import org.keycloak.quarkus.runtime.Environment;
|
||||||
import org.keycloak.quarkus.runtime.storage.database.jpa.AbstractJpaConnectionProviderFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.keycloak.quarkus.runtime.storage.legacy.liquibase;
|
package org.keycloak.quarkus.runtime.storage.database.liquibase;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.keycloak.quarkus.runtime.storage.legacy.liquibase;
|
package org.keycloak.quarkus.runtime.storage.database.liquibase;
|
||||||
|
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
import org.keycloak.connections.jpa.updater.JpaUpdaterProvider;
|
import org.keycloak.connections.jpa.updater.JpaUpdaterProvider;
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.quarkus.runtime.storage.database.liquibase;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.xml.parsers.SAXParserFactory;
|
||||||
|
import liquibase.Scope;
|
||||||
|
import liquibase.parser.ChangeLogParser;
|
||||||
|
import liquibase.parser.ChangeLogParserFactory;
|
||||||
|
import liquibase.parser.core.xml.XMLChangeLogSAXParser;
|
||||||
|
import liquibase.ui.LoggerUIService;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
import org.keycloak.connections.jpa.updater.liquibase.conn.DefaultLiquibaseConnectionProvider;
|
||||||
|
|
||||||
|
public class QuarkusLiquibaseConnectionProvider extends DefaultLiquibaseConnectionProvider {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(QuarkusLiquibaseConnectionProvider.class);
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void baseLiquibaseInitialization() {
|
||||||
|
|
||||||
|
// initialize Liquibase using a custom scope
|
||||||
|
final Map<String, Object> scopeValues = new HashMap<>();
|
||||||
|
scopeValues.put(Scope.Attr.ui.name(), new LoggerUIService());
|
||||||
|
try {
|
||||||
|
Scope.enter(scopeValues);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Failed to initialize Liquibase: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// disables XML validation
|
||||||
|
for (ChangeLogParser parser : ChangeLogParserFactory.getInstance().getParsers()) {
|
||||||
|
if (parser instanceof XMLChangeLogSAXParser) {
|
||||||
|
Method getSaxParserFactory = null;
|
||||||
|
try {
|
||||||
|
getSaxParserFactory = XMLChangeLogSAXParser.class.getDeclaredMethod("getSaxParserFactory");
|
||||||
|
getSaxParserFactory.setAccessible(true);
|
||||||
|
SAXParserFactory saxParserFactory = (SAXParserFactory) getSaxParserFactory.invoke(parser);
|
||||||
|
saxParserFactory.setValidating(false);
|
||||||
|
saxParserFactory.setSchema(null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.warnf("Failed to disable liquibase XML validations");
|
||||||
|
} finally {
|
||||||
|
if (getSaxParserFactory != null) {
|
||||||
|
getSaxParserFactory.setAccessible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return "quarkus";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int order() {
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.keycloak.quarkus.runtime.storage.legacy.infinispan;
|
package org.keycloak.quarkus.runtime.storage.infinispan;
|
||||||
|
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.keycloak.quarkus.runtime.storage.legacy.infinispan;
|
package org.keycloak.quarkus.runtime.storage.infinispan;
|
||||||
|
|
||||||
import io.quarkus.arc.Arc;
|
import io.quarkus.arc.Arc;
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.keycloak.quarkus.runtime.storage.legacy.infinispan;
|
package org.keycloak.quarkus.runtime.storage.infinispan;
|
||||||
|
|
||||||
import org.infinispan.manager.EmbeddedCacheManager;
|
import org.infinispan.manager.EmbeddedCacheManager;
|
||||||
import org.keycloak.connections.infinispan.DefaultInfinispanConnectionProviderFactory;
|
import org.keycloak.connections.infinispan.DefaultInfinispanConnectionProviderFactory;
|
|
@ -1,152 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
|
||||||
* and other contributors as indicated by the @author tags.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.keycloak.quarkus.runtime.storage.legacy.liquibase;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.xml.parsers.SAXParserFactory;
|
|
||||||
|
|
||||||
import liquibase.Scope;
|
|
||||||
import liquibase.ui.LoggerUIService;
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
import org.keycloak.Config;
|
|
||||||
import org.keycloak.connections.jpa.updater.liquibase.conn.KeycloakLiquibase;
|
|
||||||
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.database.Database;
|
|
||||||
import liquibase.database.DatabaseFactory;
|
|
||||||
import liquibase.database.jvm.JdbcConnection;
|
|
||||||
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;
|
|
||||||
|
|
||||||
public class QuarkusLiquibaseConnectionProvider implements LiquibaseConnectionProviderFactory, LiquibaseConnectionProvider {
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(QuarkusLiquibaseConnectionProvider.class);
|
|
||||||
|
|
||||||
private volatile boolean initialized = false;
|
|
||||||
private ClassLoaderResourceAccessor resourceAccessor;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LiquibaseConnectionProvider create(KeycloakSession session) {
|
|
||||||
if (!initialized) {
|
|
||||||
synchronized (this) {
|
|
||||||
if (!initialized) {
|
|
||||||
baseLiquibaseInitialization(session);
|
|
||||||
initialized = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void baseLiquibaseInitialization(KeycloakSession session) {
|
|
||||||
resourceAccessor = new ClassLoaderResourceAccessor(getClass().getClassLoader());
|
|
||||||
|
|
||||||
// initialize Liquibase using a custom scope
|
|
||||||
final Map<String, Object> scopeValues = new HashMap<>();
|
|
||||||
scopeValues.put(Scope.Attr.ui.name(), new LoggerUIService());
|
|
||||||
try {
|
|
||||||
Scope scope = Scope.getCurrentScope();
|
|
||||||
scope.enter(scopeValues);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Failed to initialize Liquibase: " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// disables XML validation
|
|
||||||
for (ChangeLogParser parser : ChangeLogParserFactory.getInstance().getParsers()) {
|
|
||||||
if (parser instanceof XMLChangeLogSAXParser) {
|
|
||||||
Method getSaxParserFactory = null;
|
|
||||||
try {
|
|
||||||
getSaxParserFactory = XMLChangeLogSAXParser.class.getDeclaredMethod("getSaxParserFactory");
|
|
||||||
getSaxParserFactory.setAccessible(true);
|
|
||||||
SAXParserFactory saxParserFactory = (SAXParserFactory) getSaxParserFactory.invoke(parser);
|
|
||||||
saxParserFactory.setValidating(false);
|
|
||||||
saxParserFactory.setSchema(null);
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.warnf("Failed to disable liquibase XML validations");
|
|
||||||
} finally {
|
|
||||||
if (getSaxParserFactory != null) {
|
|
||||||
getSaxParserFactory.setAccessible(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Config.Scope config) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postInit(KeycloakSessionFactory factory) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return "quarkus";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public KeycloakLiquibase getLiquibase(Connection connection, String defaultSchema) throws LiquibaseException {
|
|
||||||
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection));
|
|
||||||
if (defaultSchema != null) {
|
|
||||||
database.setDefaultSchemaName(defaultSchema);
|
|
||||||
}
|
|
||||||
|
|
||||||
String changelog = QuarkusJpaUpdaterProvider.CHANGELOG;
|
|
||||||
|
|
||||||
logger.debugf("Using changelog file %s and changelogTableName %s", changelog, database.getDatabaseChangeLogTableName());
|
|
||||||
|
|
||||||
return new KeycloakLiquibase(changelog, resourceAccessor, database);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public KeycloakLiquibase getLiquibaseForCustomUpdate(Connection connection, String defaultSchema, String changelogLocation, ClassLoader classloader, String changelogTableName) throws LiquibaseException {
|
|
||||||
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection));
|
|
||||||
if (defaultSchema != null) {
|
|
||||||
database.setDefaultSchemaName(defaultSchema);
|
|
||||||
}
|
|
||||||
|
|
||||||
ResourceAccessor resourceAccessor = new ClassLoaderResourceAccessor(classloader);
|
|
||||||
database.setDatabaseChangeLogTableName(changelogTableName);
|
|
||||||
|
|
||||||
logger.debugf("Using changelog file %s and changelogTableName %s", changelogLocation, database.getDatabaseChangeLogTableName());
|
|
||||||
|
|
||||||
return new KeycloakLiquibase(changelogLocation, resourceAccessor, database);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int order() {
|
|
||||||
return 100;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +1,18 @@
|
||||||
org.keycloak.quarkus.runtime.storage.legacy.infinispan.QuarkusCacheManagerProvider
|
#
|
||||||
|
# Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
# and other contributors as indicated by the @author tags.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
org.keycloak.quarkus.runtime.storage.infinispan.QuarkusCacheManagerProvider
|
|
@ -17,4 +17,4 @@
|
||||||
# */
|
# */
|
||||||
#
|
#
|
||||||
|
|
||||||
org.keycloak.quarkus.runtime.storage.legacy.infinispan.QuarkusInfinispanConnectionFactory
|
org.keycloak.quarkus.runtime.storage.infinispan.QuarkusInfinispanConnectionFactory
|
|
@ -15,4 +15,4 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
org.keycloak.quarkus.runtime.storage.legacy.database.QuarkusJpaConnectionProviderFactory
|
org.keycloak.quarkus.runtime.storage.database.jpa.QuarkusJpaConnectionProviderFactory
|
||||||
|
|
|
@ -15,4 +15,4 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
org.keycloak.quarkus.runtime.storage.legacy.liquibase.QuarkusJpaUpdaterProviderFactory
|
org.keycloak.quarkus.runtime.storage.database.liquibase.QuarkusJpaUpdaterProviderFactory
|
|
@ -15,4 +15,4 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
org.keycloak.quarkus.runtime.storage.legacy.liquibase.QuarkusLiquibaseConnectionProvider
|
org.keycloak.quarkus.runtime.storage.database.liquibase.QuarkusLiquibaseConnectionProvider
|
Loading…
Reference in a new issue