I am trying to do a sync process via the keycloak ImportSynchronization interface. (wildlfy 18.0.1.Final) it provides the following method to override:
@Override
public SynchronizationResult sync(
final KeycloakSessionFactory sessionFactory,
final String realmId,
final UserStorageProviderModel model) {
...}
This sync process takes much more time than our default transaction timeout (300 sec = 5 min).
I am aware of this possible opportunity:
<core-environment node-identifier="${jboss.tx.node.id:1}">
<process-id>
<uuid/>
</process-id>
</core-environment>
<recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
<coordinator-environment statistics-enabled="${wildfly.transactions.statistics-enabled:${wildfly.statistics-enabled:false}}"
default-timeout="${env.TRANSACTION_TIMEOUT_SEC:300}"/>
<object-store path="tx-object-store" relative-to="jboss.server.data.dir"/>
</subsystem>
BUT this is not what I want, unfortunately.
I don't want to increase the timeout for all of our processes, just for this one. Meaning I am searching for a custom transaction timeout solution. (something like @TransactionTimeout...)
I've tried the following
@Override
public SynchronizationResult doCleanup(final KeycloakSessionFactory keycloakSessionFactory, final String realmId) {
final SynchronizationResult synchronizationResult = new SynchronizationResult();
try {
final RealmModel realmModel = this.getRealmModelInTx(realmId, keycloakSessionFactory);
Thread.sleep(<more than tx timeout>);
final int userEntityCountBeforeCleanup = this.getUserCountInTx(realmModel, keycloakSessionFactory);
...}
and in both methods, I created a new keycloakSession and a new transactionManager and closed them like here:
private CleanupTransactionHandler createSession(final KeycloakSessionFactory keycloakSessionFactory) {
KeycloakTransactionManager transactionManager = null;
final KeycloakSession keycloakSession = keycloakSessionFactory.create();
log.tracef("KeycloakSession has been created [%s].", keycloakSession.hashCode());
transactionManager = keycloakSession.getTransactionManager();
transactionManager.begin();
log.tracef("KeycloakTransactionManager's transaction has been begun [%s].", transactionManager.hashCode());
return new CleanupTransactionHandler(keycloakSession,transactionManager);
}
private void closeSession(final KeycloakSession keycloakSession) {
keycloakSession.close();
log.tracef("KeycloakSession has been closed [%s].", keycloakSession.hashCode());
}
private void rollback(final KeycloakTransactionManager keycloakTransactionManager) {
keycloakTransactionManager.rollback();
log.tracef("KeycloakTransactionManager's transaction has been rolled back [%s].", keycloakTransactionManager.hashCode());
}
If someone wonders how this might be fixed in Keycloak 21.1.1++, here is what I did:
KC_QUARKUS_PROPERTIES_ENABLED=true
as env variable or kc.quarkus-properties-enabled
flagquarkus.properties
file, and add hte following:quarkus.transaction-manager.default-transaction-timeout=PT6H
The quarkus.properties
file must be copied to the conf
folder in the Keycloak distribution.
Sources: tons of debugging :)
https://www.keycloak.org/migration/migrating-to-quarkus
https://quarkus.io/guides/transaction#configuring-the-transaction-timeout
Regarding the duration format:
https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-