KEYCLOAK-3141 Fix DB2 and some other DB issues
This commit is contained in:
parent
e2082ce29f
commit
f7a2ad021e
4 changed files with 89 additions and 58 deletions
|
@ -48,16 +48,17 @@ public class LiquibaseDBLockProvider implements DBLockProvider {
|
|||
|
||||
private CustomLockService lockService;
|
||||
private Connection dbConnection;
|
||||
private boolean initialized = false;
|
||||
|
||||
private int maxAttempts = DEFAULT_MAX_ATTEMPTS;
|
||||
|
||||
public LiquibaseDBLockProvider(LiquibaseDBLockProviderFactory factory, KeycloakSession session) {
|
||||
this.factory = factory;
|
||||
this.session = session;
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
private void lazyInit() {
|
||||
if (!initialized) {
|
||||
LiquibaseConnectionProvider liquibaseProvider = session.getProvider(LiquibaseConnectionProvider.class);
|
||||
JpaConnectionProviderFactory jpaProviderFactory = (JpaConnectionProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(JpaConnectionProvider.class);
|
||||
|
||||
|
@ -70,24 +71,29 @@ public class LiquibaseDBLockProvider implements DBLockProvider {
|
|||
this.lockService = new CustomLockService();
|
||||
lockService.setChangeLogLockWaitTime(factory.getLockWaitTimeoutMillis());
|
||||
lockService.setDatabase(liquibase.getDatabase());
|
||||
initialized = true;
|
||||
} catch (LiquibaseException exception) {
|
||||
safeRollbackConnection();
|
||||
safeCloseConnection();
|
||||
throw new IllegalStateException(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assumed transaction was rolled-back and we want to start with new DB connection
|
||||
private void restart() {
|
||||
safeCloseConnection();
|
||||
this.dbConnection = null;
|
||||
this.lockService = null;
|
||||
init();
|
||||
initialized = false;
|
||||
lazyInit();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void waitForLock() {
|
||||
lazyInit();
|
||||
|
||||
while (maxAttempts > 0) {
|
||||
try {
|
||||
lockService.waitForLock();
|
||||
|
@ -110,6 +116,8 @@ public class LiquibaseDBLockProvider implements DBLockProvider {
|
|||
|
||||
@Override
|
||||
public void releaseLock() {
|
||||
lazyInit();
|
||||
|
||||
lockService.releaseLock();
|
||||
lockService.reset();
|
||||
factory.setHasLock(false);
|
||||
|
@ -128,6 +136,8 @@ public class LiquibaseDBLockProvider implements DBLockProvider {
|
|||
|
||||
@Override
|
||||
public void destroyLockInfo() {
|
||||
lazyInit();
|
||||
|
||||
try {
|
||||
this.lockService.destroy();
|
||||
dbConnection.commit();
|
||||
|
@ -154,7 +164,7 @@ public class LiquibaseDBLockProvider implements DBLockProvider {
|
|||
}
|
||||
|
||||
private void safeCloseConnection() {
|
||||
// Close after creating EntityManagerFactory to prevent in-mem databases from closing
|
||||
// Close to prevent in-mem databases from closing
|
||||
if (dbConnection != null) {
|
||||
try {
|
||||
dbConnection.close();
|
||||
|
|
|
@ -32,4 +32,6 @@
|
|||
<include file="META-INF/jpa-changelog-1.9.0.xml"/>
|
||||
<include file="META-INF/db2-jpa-changelog-1.9.1.xml"/>
|
||||
<include file="META-INF/jpa-changelog-1.9.2.xml"/>
|
||||
|
||||
<include file="META-INF/jpa-changelog-authz-master.xml"/>
|
||||
</databaseChangeLog>
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.keycloak.migration.MigrationModelManager;
|
|||
import org.keycloak.models.*;
|
||||
import org.keycloak.models.dblock.DBLockProvider;
|
||||
import org.keycloak.models.dblock.DBLockManager;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.models.utils.PostMigrationEvent;
|
||||
import org.keycloak.models.utils.RepresentationToModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
@ -91,13 +92,52 @@ public class KeycloakApplication extends Application {
|
|||
|
||||
singletons.add(new ObjectMapperResolver(Boolean.parseBoolean(System.getProperty("keycloak.jsonPrettyPrint", "false"))));
|
||||
|
||||
ExportImportManager exportImportManager;
|
||||
ExportImportManager[] exportImportManager = new ExportImportManager[1];
|
||||
|
||||
DBLockManager dbLockManager = new DBLockManager(sessionFactory.create());
|
||||
KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
|
||||
|
||||
@Override
|
||||
public void run(KeycloakSession lockSession) {
|
||||
DBLockManager dbLockManager = new DBLockManager(lockSession);
|
||||
dbLockManager.checkForcedUnlock();
|
||||
DBLockProvider dbLock = dbLockManager.getDBLock();
|
||||
dbLock.waitForLock();
|
||||
try {
|
||||
exportImportManager[0] = migrateAndBootstrap();
|
||||
} finally {
|
||||
dbLock.releaseLock();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
if (exportImportManager[0].isRunExport()) {
|
||||
exportImportManager[0].runExport();
|
||||
}
|
||||
|
||||
boolean bootstrapAdminUser = false;
|
||||
KeycloakSession session = sessionFactory.create();
|
||||
try {
|
||||
session.getTransaction().begin();
|
||||
bootstrapAdminUser = new ApplianceBootstrap(session).isNoMasterUser();
|
||||
|
||||
session.getTransaction().commit();
|
||||
} finally {
|
||||
session.close();
|
||||
}
|
||||
|
||||
sessionFactory.publish(new PostMigrationEvent());
|
||||
|
||||
singletons.add(new WelcomeResource(bootstrapAdminUser));
|
||||
|
||||
setupScheduledTasks(sessionFactory);
|
||||
}
|
||||
|
||||
|
||||
// Migrate model, bootstrap master realm, import realms and create admin user. This is done with acquired dbLock
|
||||
protected ExportImportManager migrateAndBootstrap() {
|
||||
ExportImportManager exportImportManager;
|
||||
migrateModel();
|
||||
|
||||
KeycloakSession session = sessionFactory.create();
|
||||
|
@ -132,31 +172,10 @@ public class KeycloakApplication extends Application {
|
|||
}
|
||||
|
||||
importAddUser();
|
||||
} finally {
|
||||
dbLock.releaseLock();
|
||||
|
||||
return exportImportManager;
|
||||
}
|
||||
|
||||
if (exportImportManager.isRunExport()) {
|
||||
exportImportManager.runExport();
|
||||
}
|
||||
|
||||
boolean bootstrapAdminUser = false;
|
||||
KeycloakSession session = sessionFactory.create();
|
||||
try {
|
||||
session.getTransaction().begin();
|
||||
bootstrapAdminUser = new ApplianceBootstrap(session).isNoMasterUser();
|
||||
|
||||
session.getTransaction().commit();
|
||||
} finally {
|
||||
session.close();
|
||||
}
|
||||
|
||||
sessionFactory.publish(new PostMigrationEvent());
|
||||
|
||||
singletons.add(new WelcomeResource(bootstrapAdminUser));
|
||||
|
||||
setupScheduledTasks(sessionFactory);
|
||||
}
|
||||
|
||||
protected void migrateModel() {
|
||||
KeycloakSession session = sessionFactory.create();
|
||||
|
|
|
@ -49,7 +49,7 @@ log4j.logger.org.keycloak.connections.jpa.updater.liquibase=${keycloak.liquibase
|
|||
|
||||
# Enable to view database updates
|
||||
# log4j.logger.org.keycloak.connections.mongo.updater.DefaultMongoUpdaterProvider=debug
|
||||
# log4j.logger.org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory=debug
|
||||
log4j.logger.org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory=${keycloak.liquibase.logging.level}
|
||||
# log4j.logger.org.keycloak.migration.MigrationModelManager=debug
|
||||
|
||||
# Enable to view hibernate statistics
|
||||
|
|
Loading…
Reference in a new issue