Move transaction processing into session close

Fixes: #15223
This commit is contained in:
Hynek Mlnarik 2022-10-31 18:12:07 +01:00 committed by Hynek Mlnařík
parent f7ad00270e
commit 071fc03f41
19 changed files with 157 additions and 204 deletions

View file

@ -31,7 +31,19 @@ public class StackUtil {
return getShortStackTrace("\n "); return getShortStackTrace("\n ");
} }
private static final Pattern IGNORED = Pattern.compile("sun\\.|java\\.(lang|util|stream)\\.|org\\.jboss\\.(arquillian|logging).|org.apache.maven.surefire|org\\.junit\\.|org.keycloak.testsuite.model.KeycloakModelTest\\."); private static final Pattern IGNORED = Pattern.compile("sun\\.|"
+ "java\\.(lang|util|stream)\\.|"
+ "jdk\\.internal\\.|"
+ "org\\.jboss\\.(arquillian|logging|logmanager|threads).|"
+ "org.apache.maven.surefire|"
+ "org\\.xnio\\.|"
+ "org\\.junit\\.|"
+ "org\\.infinispan\\.(interceptors|cache|notifications\\.cachelistener)\\.|"
+ "io\\.quarkus\\.|"
+ "io\\.undertow\\.|"
+ "picocli\\.|"
+ "org.keycloak.testsuite.model.KeycloakModelTest\\."
);
private static final StringBuilder EMPTY = new StringBuilder(0); private static final StringBuilder EMPTY = new StringBuilder(0);
/** /**

View file

@ -44,8 +44,6 @@ public class ClusterAwareScheduledTaskRunner extends ScheduledTaskRunner {
@Override @Override
protected void runTask(final KeycloakSession session) { protected void runTask(final KeycloakSession session) {
session.getTransactionManager().begin();
ClusterProvider clusterProvider = session.getProvider(ClusterProvider.class); ClusterProvider clusterProvider = session.getProvider(ClusterProvider.class);
String taskKey = task.getClass().getSimpleName(); String taskKey = task.getClass().getSimpleName();
@ -61,8 +59,6 @@ public class ClusterAwareScheduledTaskRunner extends ScheduledTaskRunner {
}); });
session.getTransactionManager().commit();
if (result.isExecuted()) { if (result.isExecuted()) {
logger.debugf("Executed scheduled task %s", taskKey); logger.debugf("Executed scheduled task %s", taskKey);
} else { } else {

View file

@ -98,8 +98,7 @@ public class LegacyDatastoreProviderFactory implements DatastoreProviderFactory,
public static void setupScheduledTasks(final KeycloakSessionFactory sessionFactory) { public static void setupScheduledTasks(final KeycloakSessionFactory sessionFactory) {
long interval = Config.scope("scheduled").getLong("interval", 900L) * 1000; long interval = Config.scope("scheduled").getLong("interval", 900L) * 1000;
KeycloakSession session = sessionFactory.create(); try (KeycloakSession session = sessionFactory.create()) {
try {
TimerProvider timer = session.getProvider(TimerProvider.class); TimerProvider timer = session.getProvider(TimerProvider.class);
if (timer != null) { if (timer != null) {
timer.schedule(new ClusterAwareScheduledTaskRunner(sessionFactory, new ClearExpiredEvents(), interval), interval, "ClearExpiredEvents"); timer.schedule(new ClusterAwareScheduledTaskRunner(sessionFactory, new ClearExpiredEvents(), interval), interval, "ClearExpiredEvents");
@ -108,8 +107,6 @@ public class LegacyDatastoreProviderFactory implements DatastoreProviderFactory,
timer.schedule(new ScheduledTaskRunner(sessionFactory, new ClearExpiredUserSessions()), interval, ClearExpiredUserSessions.TASK_NAME); timer.schedule(new ScheduledTaskRunner(sessionFactory, new ClearExpiredUserSessions()), interval, ClearExpiredUserSessions.TASK_NAME);
UserStorageSyncManager.bootstrapPeriodic(sessionFactory, timer); UserStorageSyncManager.bootstrapPeriodic(sessionFactory, timer);
} }
} finally {
session.close();
} }
} }

View file

@ -41,6 +41,7 @@ import org.keycloak.Config;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.KeycloakTransactionManager; import org.keycloak.models.KeycloakTransactionManager;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler; import org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler;
import org.keycloak.quarkus.runtime.cli.Picocli; import org.keycloak.quarkus.runtime.cli.Picocli;
import org.keycloak.common.Version; import org.keycloak.common.Version;
@ -159,24 +160,16 @@ public class KeycloakMain implements QuarkusApplication {
} }
KeycloakSessionFactory sessionFactory = KeycloakApplication.getSessionFactory(); KeycloakSessionFactory sessionFactory = KeycloakApplication.getSessionFactory();
KeycloakSession session = sessionFactory.create();
KeycloakTransactionManager transaction = session.getTransactionManager();
try { try {
transaction.begin(); KeycloakModelUtils.runJobInTransaction(sessionFactory, session -> {
new ApplianceBootstrap(session).createMasterRealmUser(adminUserName, adminPassword);
new ApplianceBootstrap(session).createMasterRealmUser(adminUserName, adminPassword); ServicesLogger.LOGGER.addUserSuccess(adminUserName, Config.getAdminRealm());
ServicesLogger.LOGGER.addUserSuccess(adminUserName, Config.getAdminRealm()); });
transaction.commit();
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
session.getTransactionManager().rollback();
ServicesLogger.LOGGER.addUserFailedUserExists(adminUserName, Config.getAdminRealm()); ServicesLogger.LOGGER.addUserFailedUserExists(adminUserName, Config.getAdminRealm());
} catch (Throwable t) { } catch (Throwable t) {
session.getTransactionManager().rollback();
ServicesLogger.LOGGER.addUserFailed(t, adminUserName, Config.getAdminRealm()); ServicesLogger.LOGGER.addUserFailed(t, adminUserName, Config.getAdminRealm());
} finally {
session.close();
} }
} }
} }

View file

@ -109,13 +109,12 @@ public class LegacyJpaConnectionProviderFactory extends AbstractJpaConnectionPro
public void postInit(KeycloakSessionFactory factory) { public void postInit(KeycloakSessionFactory factory) {
super.postInit(factory); super.postInit(factory);
KeycloakSession session = factory.create();
String id = null; String id = null;
String version = null; String version = null;
String schema = getSchema(); String schema = getSchema();
boolean schemaChanged; boolean schemaChanged;
try (Connection connection = getConnection()) { try (Connection connection = getConnection(); KeycloakSession session = factory.create()) {
try { try {
try (Statement statement = connection.createStatement()) { try (Statement statement = connection.createStatement()) {
try (ResultSet rs = statement.executeQuery(String.format(SQL_GET_LATEST_VERSION, getSchema(schema)))) { try (ResultSet rs = statement.executeQuery(String.format(SQL_GET_LATEST_VERSION, getSchema(schema)))) {
@ -133,8 +132,6 @@ public class LegacyJpaConnectionProviderFactory extends AbstractJpaConnectionPro
schemaChanged = createOrUpdateSchema(schema, version, connection, session); schemaChanged = createOrUpdateSchema(schema, version, connection, session);
} catch (SQLException cause) { } catch (SQLException cause) {
throw new RuntimeException("Failed to update database.", cause); throw new RuntimeException("Failed to update database.", cause);
} finally {
session.close();
} }
if (schemaChanged || Environment.isImportExportMode()) { if (schemaChanged || Environment.isImportExportMode()) {

View file

@ -39,8 +39,7 @@ public interface TransactionalSessionHandler {
default KeycloakSession create() { default KeycloakSession create() {
KeycloakSessionFactory sessionFactory = getSessionFactory(); KeycloakSessionFactory sessionFactory = getSessionFactory();
KeycloakSession session = sessionFactory.create(); KeycloakSession session = sessionFactory.create();
KeycloakTransactionManager tx = session.getTransactionManager(); session.getTransactionManager().begin();
tx.begin();
return session; return session;
} }
@ -54,18 +53,6 @@ public interface TransactionalSessionHandler {
return; return;
} }
KeycloakTransactionManager tx = session.getTransactionManager(); session.close();
try {
if (tx.isActive()) {
if (tx.getRollbackOnly()) {
tx.rollback();
} else {
tx.commit();
}
}
} finally {
session.close();
}
} }
} }

View file

@ -41,7 +41,6 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.KeycloakSessionTask; import org.keycloak.models.KeycloakSessionTask;
import org.keycloak.models.KeycloakSessionTaskWithResult; import org.keycloak.models.KeycloakSessionTaskWithResult;
import org.keycloak.models.KeycloakTransaction;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RealmProvider; import org.keycloak.models.RealmProvider;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
@ -263,27 +262,15 @@ public final class KeycloakModelUtils {
* Wrap a given callable job into a KeycloakTransaction. * Wrap a given callable job into a KeycloakTransaction.
*/ */
public static <V> V runJobInTransactionWithResult(KeycloakSessionFactory factory, final KeycloakSessionTaskWithResult<V> callable) { public static <V> V runJobInTransactionWithResult(KeycloakSessionFactory factory, final KeycloakSessionTaskWithResult<V> callable) {
KeycloakSession session = factory.create();
KeycloakTransaction tx = session.getTransactionManager();
V result; V result;
try { try (KeycloakSession session = factory.create()) {
tx.begin(); session.getTransactionManager().begin();
result = callable.run(session); try {
result = callable.run(session);
if (tx.isActive()) { } catch (Throwable t) {
if (tx.getRollbackOnly()) { session.getTransactionManager().setRollbackOnly();
tx.rollback(); throw t;
} else {
tx.commit();
}
} }
} catch (RuntimeException re) {
if (tx.isActive()) {
tx.rollback();
}
throw re;
} finally {
session.close();
} }
return result; return result;
} }
@ -306,25 +293,11 @@ public final class KeycloakModelUtils {
final int attemptsCount, final int retryIntervalMillis) { final int attemptsCount, final int retryIntervalMillis) {
int retryCount = 0; int retryCount = 0;
Random rand = new Random(); Random rand = new Random();
V result;
while (true) { while (true) {
KeycloakSession session = factory.create(); try (KeycloakSession session = factory.create()) {
KeycloakTransaction tx = session.getTransactionManager(); session.getTransactionManager().begin();
try { return callable.run(session);
tx.begin();
result = callable.run(session);
if (tx.isActive()) {
if (tx.getRollbackOnly()) {
tx.rollback();
} else {
tx.commit();
}
}
break;
} catch (RuntimeException re) { } catch (RuntimeException re) {
if (tx.isActive()) {
tx.rollback();
}
if (isExceptionRetriable(re) && ++retryCount < attemptsCount) { if (isExceptionRetriable(re) && ++retryCount < attemptsCount) {
int delay = Math.min(retryIntervalMillis * attemptsCount, (1 << retryCount) * retryIntervalMillis) int delay = Math.min(retryIntervalMillis * attemptsCount, (1 << retryCount) * retryIntervalMillis)
+ rand.nextInt(retryIntervalMillis); + rand.nextInt(retryIntervalMillis);
@ -341,11 +314,8 @@ public final class KeycloakModelUtils {
} }
throw re; throw re;
} }
} finally {
session.close();
} }
} }
return result;
} }
/** /**

View file

@ -46,32 +46,27 @@ public class ScheduledTaskRunner implements Runnable {
@Override @Override
public void run() { public void run() {
KeycloakSession session = sessionFactory.create();
try { try {
if (transactionLimit != 0) { KeycloakModelUtils.runJobInTransaction(sessionFactory, session -> {
KeycloakModelUtils.setTransactionLimit(sessionFactory, transactionLimit); try {
} if (transactionLimit != 0) {
runTask(session); KeycloakModelUtils.setTransactionLimit(sessionFactory, transactionLimit);
}
runTask(session);
} finally {
if (transactionLimit != 0) {
KeycloakModelUtils.setTransactionLimit(sessionFactory, 0);
}
}
});
} catch (Throwable t) { } catch (Throwable t) {
logger.errorf(t, "Failed to run scheduled task %s", task.getClass().getSimpleName()); logger.errorf(t, "Failed to run scheduled task %s", task.getClass().getSimpleName());
session.getTransactionManager().rollback();
} finally {
if (transactionLimit != 0) {
KeycloakModelUtils.setTransactionLimit(sessionFactory, 0);
}
try {
session.close();
} catch (Throwable t) {
logger.errorf(t, "Failed to close ProviderSession");
}
} }
} }
protected void runTask(KeycloakSession session) { protected void runTask(KeycloakSession session) {
session.getTransactionManager().begin();
task.run(session); task.run(session);
session.getTransactionManager().commit();
logger.debug("Executed scheduled task " + task.getClass().getSimpleName()); logger.debug("Executed scheduled task " + task.getClass().getSimpleName());
} }

View file

@ -32,7 +32,7 @@ import java.util.function.Function;
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $ * @version $Revision: 1 $
*/ */
public interface KeycloakSession { public interface KeycloakSession extends AutoCloseable {
KeycloakContext getContext(); KeycloakContext getContext();

View file

@ -88,13 +88,13 @@ public class DefaultKeycloakSession implements KeycloakSession {
private TokenManager tokenManager; private TokenManager tokenManager;
private VaultTranscriber vaultTranscriber; private VaultTranscriber vaultTranscriber;
private ClientPolicyManager clientPolicyManager; private ClientPolicyManager clientPolicyManager;
private boolean closed = false;
private boolean closed;
public DefaultKeycloakSession(DefaultKeycloakSessionFactory factory) { public DefaultKeycloakSession(DefaultKeycloakSessionFactory factory) {
this.factory = factory; this.factory = factory;
this.transactionManager = new DefaultKeycloakTransactionManager(this); this.transactionManager = new DefaultKeycloakTransactionManager(this);
context = createKeycloakContext(this); context = createKeycloakContext(this);
LOG.tracef("Created %s%s", this, StackUtil.getShortStackTrace());
} }
@Override @Override
@ -452,31 +452,72 @@ public class DefaultKeycloakSession implements KeycloakSession {
return clientPolicyManager; return clientPolicyManager;
} }
private static final Logger LOG = Logger.getLogger(DefaultKeycloakSession.class);
@Override @Override
public void close() { public void close() {
if (LOG.isTraceEnabled()) {
LOG.tracef("Closing %s%s%s", this,
getTransactionManager().isActive() ? " (transaction active" + (getTransactionManager().getRollbackOnly() ? ", ROLLBACK-ONLY" : "") + ")" : "",
StackUtil.getShortStackTrace());
}
if (closed) { if (closed) {
throw new IllegalStateException("Illegal call to #close() on already closed KeycloakSession"); throw new IllegalStateException("Illegal call to #close() on already closed " + this);
} }
Consumer<? super Provider> safeClose = p -> {
try { RuntimeException re = closeTransactionManager();
p.close();
} catch (Exception e) { try {
// Ignore exception Consumer<? super Provider> safeClose = p -> {
try {
p.close();
} catch (Exception e) {
// Ignore exception
}
};
providers.values().forEach(safeClose);
closable.forEach(safeClose);
for (Entry<InvalidableObjectType, Set<Object>> me : invalidationMap.entrySet()) {
factory.invalidate(this, me.getKey(), me.getValue().toArray());
} }
}; } finally {
providers.values().forEach(safeClose); this.closed = true;
closable.forEach(safeClose); }
for (Entry<InvalidableObjectType, Set<Object>> me : invalidationMap.entrySet()) {
factory.invalidate(this, me.getKey(), me.getValue().toArray()); if (re != null) {
throw re;
} }
closed = true;
} }
public boolean isClosed() { protected RuntimeException closeTransactionManager() {
return closed; if (! this.transactionManager.isActive()) {
return null;
}
try {
if (this.transactionManager.getRollbackOnly()) {
this.transactionManager.rollback();
} else {
this.transactionManager.commit();
}
} catch (RuntimeException re) {
return re;
}
return null;
}
@Override
public String toString() {
return String.format("session @ %08x", System.identityHashCode(this));
} }
protected DefaultKeycloakContext createKeycloakContext(KeycloakSession session) { protected DefaultKeycloakContext createKeycloakContext(KeycloakSession session) {
return new DefaultKeycloakContext(session); return new DefaultKeycloakContext(session);
} }
public boolean isClosed() {
return closed;
}
} }

View file

@ -18,7 +18,6 @@ package org.keycloak.services;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.keycloak.Config; import org.keycloak.Config;
import org.keycloak.common.Profile;
import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.component.ComponentFactoryProvider; import org.keycloak.component.ComponentFactoryProvider;
import org.keycloak.component.ComponentFactoryProviderFactory; import org.keycloak.component.ComponentFactoryProviderFactory;

View file

@ -56,15 +56,6 @@ public abstract class AbstractRequestFilter {
} }
protected void close(KeycloakSession session) { protected void close(KeycloakSession session) {
KeycloakTransactionManager tx = session.getTransactionManager();
if (tx.isActive()) {
if (tx.getRollbackOnly()) {
tx.rollback();
} else {
tx.commit();
}
}
session.close(); session.close();
} }

View file

@ -213,22 +213,22 @@ public class DefaultBruteForceProtector implements Runnable, BruteForceProtector
events.add(take); events.add(take);
queue.drainTo(events, TRANSACTION_SIZE); queue.drainTo(events, TRANSACTION_SIZE);
Collections.sort(events); // we sort to avoid deadlock due to ordered updates. Maybe I'm overthinking this. Collections.sort(events); // we sort to avoid deadlock due to ordered updates. Maybe I'm overthinking this.
KeycloakSession session = factory.create(); try (KeycloakSession session = factory.create()) {
session.getTransactionManager().begin(); session.getTransactionManager().begin();
try { try {
for (LoginEvent event : events) { for (LoginEvent event : events) {
if (event instanceof FailedLogin) { if (event instanceof FailedLogin) {
failure(session, event); failure(session, event);
} else if (event instanceof SuccessfulLogin) { } else if (event instanceof SuccessfulLogin) {
success(session, event); success(session, event);
} else if (event instanceof ShutdownEvent) { } else if (event instanceof ShutdownEvent) {
run = false; run = false;
}
} }
} catch (Exception e) {
session.getTransactionManager().setRollbackOnly();
throw e;
} }
session.getTransactionManager().commit();
} catch (Exception e) {
session.getTransactionManager().rollback();
throw e;
} finally { } finally {
for (LoginEvent event : events) { for (LoginEvent event : events) {
if (event instanceof FailedLogin) { if (event instanceof FailedLogin) {
@ -238,7 +238,6 @@ public class DefaultBruteForceProtector implements Runnable, BruteForceProtector
} }
} }
events.clear(); events.clear();
session.close();
} }
} catch (Exception e) { } catch (Exception e) {
ServicesLogger.LOGGER.failedProcessingType(e); ServicesLogger.LOGGER.failedProcessingType(e);

View file

@ -295,9 +295,8 @@ public class KeycloakApplication extends Application {
} }
public void importRealm(RealmRepresentation rep, String from) { public void importRealm(RealmRepresentation rep, String from) {
KeycloakSession session = sessionFactory.create();
boolean exists = false; boolean exists = false;
try { try (KeycloakSession session = sessionFactory.create()) {
session.getTransactionManager().begin(); session.getTransactionManager().begin();
try { try {
@ -316,15 +315,14 @@ public class KeycloakApplication extends Application {
RealmModel realm = manager.importRealm(rep); RealmModel realm = manager.importRealm(rep);
ServicesLogger.LOGGER.importedRealm(realm.getName(), from); ServicesLogger.LOGGER.importedRealm(realm.getName(), from);
} }
session.getTransactionManager().commit();
} catch (Throwable t) { } catch (Throwable t) {
session.getTransactionManager().rollback(); session.getTransactionManager().setRollbackOnly();
if (!exists) { throw t;
ServicesLogger.LOGGER.unableToImportRealm(t, rep.getRealm(), from); }
} } catch (Throwable t) {
if (!exists) {
ServicesLogger.LOGGER.unableToImportRealm(t, rep.getRealm(), from);
} }
} finally {
session.close();
} }
} }
@ -346,37 +344,30 @@ public class KeycloakApplication extends Application {
for (RealmRepresentation realmRep : realms) { for (RealmRepresentation realmRep : realms) {
for (UserRepresentation userRep : realmRep.getUsers()) { for (UserRepresentation userRep : realmRep.getUsers()) {
KeycloakSession session = sessionFactory.create();
try { try {
session.getTransactionManager().begin(); KeycloakModelUtils.runJobInTransaction(sessionFactory, session -> {
RealmModel realm = session.realms().getRealmByName(realmRep.getRealm()); RealmModel realm = session.realms().getRealmByName(realmRep.getRealm());
if (realm == null) { if (realm == null) {
ServicesLogger.LOGGER.addUserFailedRealmNotFound(userRep.getUsername(), realmRep.getRealm()); ServicesLogger.LOGGER.addUserFailedRealmNotFound(userRep.getUsername(), realmRep.getRealm());
} }
UserProvider users = session.users(); UserProvider users = session.users();
if (users.getUserByUsername(realm, userRep.getUsername()) != null) { if (users.getUserByUsername(realm, userRep.getUsername()) != null) {
ServicesLogger.LOGGER.notCreatingExistingUser(userRep.getUsername()); ServicesLogger.LOGGER.notCreatingExistingUser(userRep.getUsername());
} else { } else {
UserModel user = users.addUser(realm, userRep.getUsername()); UserModel user = users.addUser(realm, userRep.getUsername());
user.setEnabled(userRep.isEnabled()); user.setEnabled(userRep.isEnabled());
RepresentationToModel.createCredentials(userRep, session, realm, user, false); RepresentationToModel.createCredentials(userRep, session, realm, user, false);
RepresentationToModel.createRoleMappings(userRep, user, realm); RepresentationToModel.createRoleMappings(userRep, user, realm);
ServicesLogger.LOGGER.addUserSuccess(userRep.getUsername(), realmRep.getRealm()); ServicesLogger.LOGGER.addUserSuccess(userRep.getUsername(), realmRep.getRealm());
} }
});
session.getTransactionManager().commit();
} catch (ModelDuplicateException e) { } catch (ModelDuplicateException e) {
session.getTransactionManager().rollback();
ServicesLogger.LOGGER.addUserFailedUserExists(userRep.getUsername(), realmRep.getRealm()); ServicesLogger.LOGGER.addUserFailedUserExists(userRep.getUsername(), realmRep.getRealm());
} catch (Throwable t) { } catch (Throwable t) {
session.getTransactionManager().rollback();
ServicesLogger.LOGGER.addUserFailed(t, userRep.getUsername(), realmRep.getRealm()); ServicesLogger.LOGGER.addUserFailed(t, userRep.getUsername(), realmRep.getRealm());
} finally {
session.close();
} }
} }
} }

View file

@ -232,15 +232,11 @@ public class KeycloakOnUndertow implements DeployableContainer<KeycloakOnUnderto
} }
protected void setupDevConfig() { protected void setupDevConfig() {
KeycloakSession session = sessionFactory.create(); try (KeycloakSession session = sessionFactory.create()) {
try {
session.getTransactionManager().begin(); session.getTransactionManager().begin();
if (new ApplianceBootstrap(session).isNoMasterUser()) { if (new ApplianceBootstrap(session).isNoMasterUser()) {
new ApplianceBootstrap(session).createMasterRealmUser("admin", "admin"); new ApplianceBootstrap(session).createMasterRealmUser("admin", "admin");
} }
session.getTransactionManager().commit();
} finally {
session.close();
} }
} }

View file

@ -258,6 +258,9 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
} }
addStorageOptions(storeProvider, commands); addStorageOptions(storeProvider, commands);
if (System.getProperty("auth.server.quarkus.log-level") != null) {
commands.add("--log-level=" + System.getProperty("auth.server.quarkus.log-level"));
}
commands.addAll(getAdditionalBuildArgs()); commands.addAll(getAdditionalBuildArgs());

View file

@ -92,23 +92,17 @@ public class ImportTest extends AbstractTestRealmKeycloakTest {
// Need a new thread to not get context from thread processing request to run-on-server endpoint // Need a new thread to not get context from thread processing request to run-on-server endpoint
Thread t = new Thread(() -> { Thread t = new Thread(() -> {
try { RealmModel realmModel;
KeycloakSession ses = session.getKeycloakSessionFactory().create(); try (KeycloakSession ses = session.getKeycloakSessionFactory().create()) {
ses.getContext().setRealm(session.getContext().getRealm()); ses.getContext().setRealm(session.getContext().getRealm());
ses.getTransactionManager().begin(); ses.getTransactionManager().begin();
RealmModel realmModel = new RealmManager(ses).importRealm(testRealm); realmModel = new RealmManager(ses).importRealm(testRealm);
}
ses.getTransactionManager().commit();
ses.close();
ses = session.getKeycloakSessionFactory().create();
try (KeycloakSession ses = session.getKeycloakSessionFactory().create()) {
ses.getTransactionManager().begin(); ses.getTransactionManager().begin();
session.realms().removeRealm(realmModel.getId()); session.realms().removeRealm(realmModel.getId());
ses.getTransactionManager().commit();
ses.close();
} catch (Throwable th) { } catch (Throwable th) {
err.set(th); err.set(th);
} }

View file

@ -529,12 +529,13 @@ public abstract class KeycloakModelTest {
} }
protected <T> void inRolledBackTransaction(T parameter, BiConsumer<KeycloakSession, T> what) { protected <T> void inRolledBackTransaction(T parameter, BiConsumer<KeycloakSession, T> what) {
KeycloakSession session = getFactory().create(); try (KeycloakSession session = getFactory().create()) {
session.getTransactionManager().begin(); session.getTransactionManager().begin();
what.accept(session, parameter); what.accept(session, parameter);
session.getTransactionManager().rollback(); session.getTransactionManager().rollback();
}
} }
protected <T, R> R inComittedTransaction(T parameter, BiFunction<KeycloakSession, T, R> what) { protected <T, R> R inComittedTransaction(T parameter, BiFunction<KeycloakSession, T, R> what) {

View file

@ -354,10 +354,9 @@ public class KeycloakServer {
} }
public void importRealm(RealmRepresentation rep) { public void importRealm(RealmRepresentation rep) {
KeycloakSession session = sessionFactory.create();;
session.getTransactionManager().begin();
try { try (KeycloakSession session = sessionFactory.create()) {
session.getTransactionManager().begin();
RealmManager manager = new RealmManager(session); RealmManager manager = new RealmManager(session);
if (rep.getId() != null && manager.getRealm(rep.getId()) != null) { if (rep.getId() != null && manager.getRealm(rep.getId()) != null) {
@ -372,25 +371,17 @@ public class KeycloakServer {
RealmModel realm = manager.importRealm(rep); RealmModel realm = manager.importRealm(rep);
info("Imported realm " + realm.getName()); info("Imported realm " + realm.getName());
session.getTransactionManager().commit();
} finally {
session.close();
} }
} }
protected void setupDevConfig() { protected void setupDevConfig() {
if (System.getProperty("keycloak.createAdminUser", "true").equals("true")) { if (System.getProperty("keycloak.createAdminUser", "true").equals("true")) {
KeycloakSession session = sessionFactory.create(); try (KeycloakSession session = sessionFactory.create()) {
try {
session.getTransactionManager().begin(); session.getTransactionManager().begin();
if (new ApplianceBootstrap(session).isNoMasterUser()) { if (new ApplianceBootstrap(session).isNoMasterUser()) {
new ApplianceBootstrap(session).createMasterRealmUser("admin", "admin"); new ApplianceBootstrap(session).createMasterRealmUser("admin", "admin");
log.info("Created master user with credentials admin:admin"); log.info("Created master user with credentials admin:admin");
} }
session.getTransactionManager().commit();
} finally {
session.close();
} }
} }
} }