You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
No exception should be thrown when using the KeycloakUserManagementService.findByUserIdentifier from a non request scope like @Async or @Scheduled annotated methods.
Current behavior
When you annotate a method with @Async or @Scheduled and it then make use of the KeycloakUserManagementService.findByUserIdentifier to lookup a user via its user identifier the exception below is thrown:
org.springframework.beans.factory.support.ScopeNotActiveException: Error creating bean with name 'scopedTarget.requestScopeUserCache': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton
Example of a piece of code which fails a.t.m. due to this exception which is triggered when a task is activated which has an assignee or when a task is assigned:
import mu.KotlinLogging
import com.ritense.valtimo.contract.authentication.UserManagementService
import org.camunda.bpm.spring.boot.starter.event.TaskEvent
import org.springframework.scheduling.annotation.Async
import org.springframework.transaction.event.TransactionPhase
import org.springframework.transaction.event.TransactionalEventListener
import java.util.UUID
open class CamundaTaskAssignedEventListener(
private val userManagementService: UserManagementService
) {
@Async
@TransactionalEventListener(
condition = "#taskEvent.eventName == 'assignment' && #taskEvent.assignee != null",
phase = TransactionPhase.AFTER_COMMIT
)
open fun onTaskEvent(taskEvent: TaskEvent) {
logger.debug {
"Triggered by assignment of CamundaTask(id=${taskEvent.id}, name=${taskEvent.name}) to ${taskEvent.assignee})"
}
logger.info {"""
TaskAssignedEvent(
taskId = taskEvent.taskDefinitionKey,
taskName = taskEvent.name,
assignee = findByUsername(taskEvent.assignee),
processInstanceId = UUID.fromString(taskEvent.processInstanceId),
taskInstanceId = UUID.fromString(taskEvent.id)
) triggered by assignment of CamundaTask(id=${taskEvent.id}, name=${taskEvent.name}) to ${taskEvent.assignee})""".trimIndent()
}
}
fun findByUsername(username: String): String {
logger.debug { "Trying to find e-mail for user '$username'" }
return userManagementService.findByUserIdentifier(username)?.email
?: throw UserNotFoundException.forUsername(username)
}
companion object {
private val logger = KotlinLogging.logger {}
}
}
The text was updated successfully, but these errors were encountered:
Expected behavior
No exception should be thrown when using the
KeycloakUserManagementService.findByUserIdentifier
from a non request scope like@Async
or@Scheduled
annotated methods.Current behavior
When you annotate a method with
@Async
or@Scheduled
and it then make use of theKeycloakUserManagementService.findByUserIdentifier
to lookup a user via its user identifier the exception below is thrown:Possible solution (optional)
Switch to a cache mechanism which is not scope restricted. I came across the Caffeine Cache (https://github.com/ben-manes/caffeine | https://www.baeldung.com/spring-boot-caffeine-cache) which is a high-performance cache library for Java and also has support for TTL of items so maybe that is an interesting cache to switch over to.
Steps to reproduce
Example of a piece of code which fails a.t.m. due to this exception which is triggered when a task is activated which has an assignee or when a task is assigned:
The text was updated successfully, but these errors were encountered: