diff --git a/libs/audit/src/main/kotlin/uk/gov/justice/digital/hmpps/audit/service/OptimisationTables.kt b/libs/audit/src/main/kotlin/uk/gov/justice/digital/hmpps/audit/service/OptimisationTables.kt new file mode 100644 index 0000000000..ce11456b87 --- /dev/null +++ b/libs/audit/src/main/kotlin/uk/gov/justice/digital/hmpps/audit/service/OptimisationTables.kt @@ -0,0 +1,27 @@ +package uk.gov.justice.digital.hmpps.audit.service + +import org.springframework.context.annotation.Conditional +import org.springframework.jdbc.core.JdbcTemplate +import org.springframework.stereotype.Service +import org.springframework.transaction.support.TransactionSynchronization +import org.springframework.transaction.support.TransactionSynchronizationManager +import uk.gov.justice.digital.hmpps.audit.config.OracleCondition + +@Service +class OptimisationTables(private val optimisationTablesRebuild: OptimisationTablesRebuild?) { + fun rebuild(personId: Long) { + optimisationTablesRebuild?.rebuild(personId) + } +} + +@Service +@Conditional(OracleCondition::class) +class OptimisationTablesRebuild(private val jdbcTemplate: JdbcTemplate) { + fun rebuild(personId: Long) { + TransactionSynchronizationManager.registerSynchronization(object : TransactionSynchronization { + override fun afterCommit() { + jdbcTemplate.execute("call PKG_TRIGGERSUPPORT.PROCREBUILDOPTTABLES($personId)") + } + }) + } +} diff --git a/libs/audit/src/main/kotlin/uk/gov/justice/digital/hmpps/datasource/DeliusConnectionProvider.kt b/libs/audit/src/main/kotlin/uk/gov/justice/digital/hmpps/datasource/DeliusConnectionProvider.kt index d597177417..f6d963ee9f 100644 --- a/libs/audit/src/main/kotlin/uk/gov/justice/digital/hmpps/datasource/DeliusConnectionProvider.kt +++ b/libs/audit/src/main/kotlin/uk/gov/justice/digital/hmpps/datasource/DeliusConnectionProvider.kt @@ -17,16 +17,7 @@ open class DeliusConnectionProvider : DatasourceConnectionProviderImpl() { } override fun closeConnection(connection: Connection) { - if (OptimisationContext.offenderId.get() != null) { - connection.prepareStatement("call PKG_TRIGGERSUPPORT.PROCREBUILDOPTTABLES(${OptimisationContext.offenderId.get()})") - .use { - it.execute() - } - OptimisationContext.offenderId.set(null) - } - connection.prepareStatement("call PKG_VPD_CTX.CLEAR_CLIENT_IDENTIFIER()").use { - it.execute() - } + connection.prepareStatement("call PKG_VPD_CTX.CLEAR_CLIENT_IDENTIFIER()").use { it.execute() } super.closeConnection(connection) } } diff --git a/libs/audit/src/main/kotlin/uk/gov/justice/digital/hmpps/datasource/OptimisationContext.kt b/libs/audit/src/main/kotlin/uk/gov/justice/digital/hmpps/datasource/OptimisationContext.kt deleted file mode 100644 index 99b31ee8d1..0000000000 --- a/libs/audit/src/main/kotlin/uk/gov/justice/digital/hmpps/datasource/OptimisationContext.kt +++ /dev/null @@ -1,5 +0,0 @@ -package uk.gov.justice.digital.hmpps.datasource - -object OptimisationContext { - val offenderId: ThreadLocal = ThreadLocal() -} diff --git a/libs/audit/src/test/kotlin/uk/gov/justice/digital/hmpps/audit/service/OptimisationTablesTest.kt b/libs/audit/src/test/kotlin/uk/gov/justice/digital/hmpps/audit/service/OptimisationTablesTest.kt new file mode 100644 index 0000000000..704cf4196e --- /dev/null +++ b/libs/audit/src/test/kotlin/uk/gov/justice/digital/hmpps/audit/service/OptimisationTablesTest.kt @@ -0,0 +1,29 @@ +package uk.gov.justice.digital.hmpps.audit.service + +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.hasSize +import org.junit.jupiter.api.Assertions.assertDoesNotThrow +import org.junit.jupiter.api.Test +import org.mockito.Mockito.mock +import org.mockito.Mockito.verify +import org.springframework.jdbc.core.JdbcTemplate +import org.springframework.transaction.support.TransactionSynchronizationManager + +class OptimisationTablesTest { + @Test + fun `handles non-Oracle database`() { + assertDoesNotThrow { OptimisationTables(null).rebuild(123) } + } + + @Test + fun `creates afterCommit hook`() { + val jdbcTemplate = mock(JdbcTemplate::class.java) + TransactionSynchronizationManager.initSynchronization() + + OptimisationTables(OptimisationTablesRebuild(jdbcTemplate)).rebuild(123) + + assertThat(TransactionSynchronizationManager.getSynchronizations(), hasSize(1)) + TransactionSynchronizationManager.getSynchronizations()[0].afterCommit() + verify(jdbcTemplate).execute("call PKG_TRIGGERSUPPORT.PROCREBUILDOPTTABLES(123)") + } +} diff --git a/libs/audit/src/test/kotlin/uk/gov/justice/digital/hmpps/datasource/DeliusConnectionProviderTest.kt b/libs/audit/src/test/kotlin/uk/gov/justice/digital/hmpps/datasource/DeliusConnectionProviderTest.kt index b230b0a2ea..31ba857d8c 100644 --- a/libs/audit/src/test/kotlin/uk/gov/justice/digital/hmpps/datasource/DeliusConnectionProviderTest.kt +++ b/libs/audit/src/test/kotlin/uk/gov/justice/digital/hmpps/datasource/DeliusConnectionProviderTest.kt @@ -70,12 +70,4 @@ class DeliusConnectionProviderTest { verify(preparedStatement).execute() verify(preparedStatement).close() } - - @Test - fun `when offender id in optimisation context sp called`() { - OptimisationContext.offenderId.set(765) - whenever(connection.prepareStatement(anyString())).thenReturn(preparedStatement) - deliusConnectionProvider.closeConnection(connection) - verify(connection, times(2)).prepareStatement(anyString()) - } } diff --git a/projects/tier-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/tier/TierService.kt b/projects/tier-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/tier/TierService.kt index 212420f709..d824bbc303 100644 --- a/projects/tier-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/tier/TierService.kt +++ b/projects/tier-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/tier/TierService.kt @@ -2,7 +2,7 @@ package uk.gov.justice.digital.hmpps.integrations.tier import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional -import uk.gov.justice.digital.hmpps.datasource.OptimisationContext +import uk.gov.justice.digital.hmpps.audit.service.OptimisationTables import uk.gov.justice.digital.hmpps.datetime.DeliusDateTimeFormatter import uk.gov.justice.digital.hmpps.exception.NotFoundException import uk.gov.justice.digital.hmpps.integrations.delius.contact.Contact @@ -35,14 +35,15 @@ class TierService( private val staffRepository: StaffRepository, private val teamRepository: TeamRepository, private val contactTypeRepository: ContactTypeRepository, - private val telemetryService: TelemetryService + private val telemetryService: TelemetryService, + private val optimisationTables: OptimisationTables ) { @Transactional fun updateTier(crn: String, tierCalculation: TierCalculation) { val person = personRepository.findByCrnAndSoftDeletedIsFalse(crn) ?: return let { telemetryService.trackEvent("PersonNotFound", tierCalculation.telemetryProperties(crn)) } - OptimisationContext.offenderId.set(person.id) + optimisationTables.rebuild(person.id) val tier = referenceDataRepository.getByCodeAndSetName("U${tierCalculation.tierScore}", "TIER") val changeReason = referenceDataRepository.getByCodeAndSetName("ATS", "TIER CHANGE REASON") val latestTierChangeDate = managementTierRepository.findFirstByIdPersonIdOrderByIdDateChangedDesc(person.id)?.id?.dateChanged diff --git a/projects/tier-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/integrations/tier/TierServiceTest.kt b/projects/tier-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/integrations/tier/TierServiceTest.kt index e44057a5a9..8b8a897863 100644 --- a/projects/tier-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/integrations/tier/TierServiceTest.kt +++ b/projects/tier-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/integrations/tier/TierServiceTest.kt @@ -15,6 +15,7 @@ import org.mockito.kotlin.any import org.mockito.kotlin.never import org.mockito.kotlin.verify import org.mockito.kotlin.whenever +import uk.gov.justice.digital.hmpps.audit.service.OptimisationTables import uk.gov.justice.digital.hmpps.data.generator.ContactTypeGenerator import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator @@ -57,6 +58,8 @@ internal class TierServiceTest { @Mock lateinit var telemetryService: TelemetryService + @Mock lateinit var optimisationTables: OptimisationTables + @InjectMocks lateinit var tierService: TierService private val tierScore = ReferenceDataGenerator.generate("someTierCode", ReferenceDataSetGenerator.TIER) diff --git a/projects/workforce-allocations-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AllocateEventService.kt b/projects/workforce-allocations-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AllocateEventService.kt index 6fbdc16bac..a3cd768ac3 100644 --- a/projects/workforce-allocations-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AllocateEventService.kt +++ b/projects/workforce-allocations-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AllocateEventService.kt @@ -3,7 +3,7 @@ package uk.gov.justice.digital.hmpps.service import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import uk.gov.justice.digital.hmpps.audit.service.AuditedInteractionService -import uk.gov.justice.digital.hmpps.datasource.OptimisationContext +import uk.gov.justice.digital.hmpps.audit.service.OptimisationTables import uk.gov.justice.digital.hmpps.exception.ConflictException import uk.gov.justice.digital.hmpps.exception.NotActiveException import uk.gov.justice.digital.hmpps.exception.NotFoundException @@ -33,7 +33,8 @@ class AllocateEventService( private val allocationValidator: AllocationValidator, private val contactTypeRepository: ContactTypeRepository, private val contactRepository: ContactRepository, - private val transferReasonRepository: TransferReasonRepository + private val transferReasonRepository: TransferReasonRepository, + private val optimisationTables: OptimisationTables ) : ManagerService(auditedInteractionService, orderManagerRepository) { @Transactional @@ -43,7 +44,7 @@ class AllocateEventService( it["offenderId"] = event.person.id it["eventId"] = event.id - OptimisationContext.offenderId.set(event.person.id) + optimisationTables.rebuild(event.person.id) if (!event.active) throw NotActiveException("Event", "number", allocationDetail.eventNumber) diff --git a/projects/workforce-allocations-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AllocatePersonService.kt b/projects/workforce-allocations-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AllocatePersonService.kt index d30b7978ea..fea82b78a1 100644 --- a/projects/workforce-allocations-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AllocatePersonService.kt +++ b/projects/workforce-allocations-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AllocatePersonService.kt @@ -3,7 +3,7 @@ package uk.gov.justice.digital.hmpps.service import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import uk.gov.justice.digital.hmpps.audit.service.AuditedInteractionService -import uk.gov.justice.digital.hmpps.datasource.OptimisationContext +import uk.gov.justice.digital.hmpps.audit.service.OptimisationTables import uk.gov.justice.digital.hmpps.datetime.DeliusDateTimeFormatter import uk.gov.justice.digital.hmpps.exception.ConflictException import uk.gov.justice.digital.hmpps.exception.NotFoundException @@ -31,7 +31,8 @@ class AllocatePersonService( private val allocationValidator: AllocationValidator, private val contactTypeRepository: ContactTypeRepository, private val contactRepository: ContactRepository, - private val responsibleOfficerRepository: ResponsibleOfficerRepository + private val responsibleOfficerRepository: ResponsibleOfficerRepository, + private val optimisationTables: OptimisationTables ) : ManagerService(auditedInteractionService, personManagerRepository) { @Transactional @@ -41,7 +42,7 @@ class AllocatePersonService( ?: throw NotFoundException("Person", "crn", allocationDetail.crn) it["offenderId"] = personId - OptimisationContext.offenderId.set(personId) + optimisationTables.rebuild(personId) val activeOffenderManager = personManagerRepository.findActiveManager( personId, diff --git a/projects/workforce-allocations-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AllocateRequirementService.kt b/projects/workforce-allocations-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AllocateRequirementService.kt index f7c6db6e12..f5101b44ae 100644 --- a/projects/workforce-allocations-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AllocateRequirementService.kt +++ b/projects/workforce-allocations-to-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/service/AllocateRequirementService.kt @@ -4,7 +4,7 @@ import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import uk.gov.justice.digital.hmpps.audit.service.AuditedInteractionService -import uk.gov.justice.digital.hmpps.datasource.OptimisationContext +import uk.gov.justice.digital.hmpps.audit.service.OptimisationTables import uk.gov.justice.digital.hmpps.exception.ConflictException import uk.gov.justice.digital.hmpps.exception.NotActiveException import uk.gov.justice.digital.hmpps.exception.NotFoundException @@ -32,7 +32,8 @@ class AllocateRequirementService( private val allocationValidator: AllocationValidator, private val contactTypeRepository: ContactTypeRepository, private val contactRepository: ContactRepository, - private val transferReasonRepository: TransferReasonRepository + private val transferReasonRepository: TransferReasonRepository, + private val optimisationTables: OptimisationTables ) : ManagerService(auditedInteractionService, requirementManagerRepository) { @Transactional @@ -44,7 +45,7 @@ class AllocateRequirementService( it["offenderId"] = requirement.person.id it["eventId"] = requirement.disposal.event.id it["requirementId"] = requirement.id - OptimisationContext.offenderId.set(requirement.person.id) + optimisationTables.rebuild(requirement.person.id) if (requirement.person.crn != crn) { throw ConflictException("Requirement ${allocationDetail.requirementId} not for $crn") diff --git a/projects/workforce-allocations-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/AllocateEventServiceTest.kt b/projects/workforce-allocations-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/AllocateEventServiceTest.kt index 2bef24576a..f5d38abf4a 100644 --- a/projects/workforce-allocations-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/AllocateEventServiceTest.kt +++ b/projects/workforce-allocations-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/AllocateEventServiceTest.kt @@ -14,6 +14,7 @@ import org.mockito.kotlin.never import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import uk.gov.justice.digital.hmpps.audit.service.AuditedInteractionService +import uk.gov.justice.digital.hmpps.audit.service.OptimisationTables import uk.gov.justice.digital.hmpps.data.generator.EventGenerator import uk.gov.justice.digital.hmpps.data.generator.OrderManagerGenerator import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator @@ -54,6 +55,9 @@ internal class AllocateEventServiceTest { @Mock private lateinit var transferReasonRepository: TransferReasonRepository + @Mock + private lateinit var optimisationTables: OptimisationTables + @InjectMocks private lateinit var allocateEventService: AllocateEventService diff --git a/projects/workforce-allocations-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/AllocatePersonServiceTest.kt b/projects/workforce-allocations-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/AllocatePersonServiceTest.kt index 0847ac503b..ce08e824dd 100644 --- a/projects/workforce-allocations-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/AllocatePersonServiceTest.kt +++ b/projects/workforce-allocations-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/AllocatePersonServiceTest.kt @@ -16,6 +16,7 @@ import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import uk.gov.justice.digital.hmpps.audit.service.AuditedInteractionService +import uk.gov.justice.digital.hmpps.audit.service.OptimisationTables import uk.gov.justice.digital.hmpps.data.generator.ContactTypeGenerator import uk.gov.justice.digital.hmpps.data.generator.OrderManagerGenerator import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator @@ -65,6 +66,9 @@ internal class AllocatePersonServiceTest { @Mock private lateinit var responsibleOfficerRepository: ResponsibleOfficerRepository + @Mock + private lateinit var optimisationTables: OptimisationTables + @InjectMocks private lateinit var allocatePersonService: AllocatePersonService diff --git a/projects/workforce-allocations-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/AllocateRequirementServiceTest.kt b/projects/workforce-allocations-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/AllocateRequirementServiceTest.kt index dec3593b07..29c0b098fe 100644 --- a/projects/workforce-allocations-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/AllocateRequirementServiceTest.kt +++ b/projects/workforce-allocations-to-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/service/AllocateRequirementServiceTest.kt @@ -17,6 +17,7 @@ import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import uk.gov.justice.digital.hmpps.audit.service.AuditedInteractionService +import uk.gov.justice.digital.hmpps.audit.service.OptimisationTables import uk.gov.justice.digital.hmpps.data.generator.ContactTypeGenerator import uk.gov.justice.digital.hmpps.data.generator.DisposalGenerator import uk.gov.justice.digital.hmpps.data.generator.EventGenerator @@ -69,6 +70,9 @@ internal class AllocateRequirementServiceTest { @Mock private lateinit var transferReasonRepository: TransferReasonRepository + @Mock + private lateinit var optimisationTables: OptimisationTables + @InjectMocks private lateinit var allocateRequirementService: AllocateRequirementService