Skip to content

Commit

Permalink
PI-1443 added message handler for court case notes (#2405)
Browse files Browse the repository at this point in the history
  • Loading branch information
stevomcallister authored Oct 18, 2023
1 parent b250b0a commit 5eb2bbc
Show file tree
Hide file tree
Showing 31 changed files with 650 additions and 0 deletions.
3 changes: 3 additions & 0 deletions projects/court-case-and-delius/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ apply(plugin = "com.google.cloud.tools.jib")
dependencies {
implementation(project(":libs:audit"))
implementation(project(":libs:commons"))
implementation(project(":libs:messaging"))
implementation(project(":libs:oauth-client"))
implementation(project(":libs:oauth-server"))

implementation("org.springframework.boot:spring-boot-starter-actuator")
Expand All @@ -16,6 +18,7 @@ dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation(libs.springdoc)
implementation(libs.openfeign)

dev(project(":libs:dev-tools"))
dev("com.h2database:h2")
Expand Down
3 changes: 3 additions & 0 deletions projects/court-case-and-delius/deploy/database/access.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ database:
access:
username_key: /court-case-and-delius/db-username
password_key: /court-case-and-delius/db-password
tables:
- audited_interaction
- contact

audit:
username: CourtCaseAndDelius
Expand Down
1 change: 1 addition & 0 deletions projects/court-case-and-delius/deploy/values-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ generic-service:
SENTRY_ENVIRONMENT: dev
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: https://sign-in-dev.hmpps.service.justice.gov.uk/auth/.well-known/jwks.json
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: https://sign-in-dev.hmpps.service.justice.gov.uk/auth/issuer
SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_HMPPS-AUTH_TOKEN-URI: https://sign-in-dev.hmpps.service.justice.gov.uk/auth/oauth/token

LOGGING_LEVEL_UK_GOV_DIGITAL_JUSTICE_HMPPS: DEBUG

Expand Down
1 change: 1 addition & 0 deletions projects/court-case-and-delius/deploy/values-preprod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ generic-service:
SENTRY_ENVIRONMENT: preprod
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: https://sign-in-preprod.hmpps.service.justice.gov.uk/auth/.well-known/jwks.json
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: https://sign-in-preprod.hmpps.service.justice.gov.uk/auth/issuer
SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_HMPPS-AUTH_TOKEN-URI: https://sign-in-preprod.hmpps.service.justice.gov.uk/auth/oauth/token

generic-prometheus-alerts:
businessHoursOnly: true
1 change: 1 addition & 0 deletions projects/court-case-and-delius/deploy/values-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ generic-service:
SENTRY_ENVIRONMENT: prod
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: https://sign-in.hmpps.service.justice.gov.uk/auth/.well-known/jwks.json
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: https://sign-in.hmpps.service.justice.gov.uk/auth/issuer
SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_HMPPS-AUTH_TOKEN-URI: https://sign-in.hmpps.service.justice.gov.uk/auth/oauth/token
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.context.ApplicationListener
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional
import uk.gov.justice.digital.hmpps.data.generator.BusinessInteractionGenerator
import uk.gov.justice.digital.hmpps.data.generator.ContactTypeGenerator
import uk.gov.justice.digital.hmpps.data.generator.CourtCaseNoteGenerator
import uk.gov.justice.digital.hmpps.data.generator.IdGenerator
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator
import uk.gov.justice.digital.hmpps.data.generator.SentenceGenerator
Expand All @@ -31,6 +34,8 @@ class DataLoader(
@Transactional
override fun onApplicationEvent(are: ApplicationReadyEvent) {
em.saveAll(
BusinessInteractionGenerator.UPDATE_CONTACT,
ContactTypeGenerator.CONTACT_TYPE,
PersonGenerator.NEW_TO_PROBATION,
PersonGenerator.CURRENTLY_MANAGED,
PersonGenerator.PREVIOUSLY_MANAGED,
Expand All @@ -39,6 +44,11 @@ class DataLoader(

em.saveAll(StaffGenerator.ALLOCATED, StaffGenerator.UNALLOCATED)

em.saveAll(
PersonGenerator.generatePersonManager(PersonGenerator.NEW_TO_PROBATION),
PersonGenerator.generatePersonManager(PersonGenerator.CURRENTLY_MANAGED)
)

val noSentenceEvent = SentenceGenerator.generateEvent(PersonGenerator.NO_SENTENCE)
val noSentenceManager = SentenceGenerator.generateOrderManager(noSentenceEvent, StaffGenerator.UNALLOCATED)
val outcome = Outcome(Outcome.Code.AWAITING_PSR.value, IdGenerator.getAndIncrement())
Expand All @@ -59,6 +69,8 @@ class DataLoader(
val preSentence = SentenceGenerator.generateSentence(preEvent, ZonedDateTime.now().minusDays(7), active = false)
val preManager = SentenceGenerator.generateOrderManager(preEvent, StaffGenerator.ALLOCATED)
em.saveAll(preEvent, preSentence, preManager)

em.merge(CourtCaseNoteGenerator.CASE_NOTE)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package uk.gov.justice.digital.hmpps.data.generator

import uk.gov.justice.digital.hmpps.audit.BusinessInteraction
import uk.gov.justice.digital.hmpps.integrations.delius.audit.BusinessInteractionCode
import java.time.ZonedDateTime

object BusinessInteractionGenerator {
val UPDATE_CONTACT = BusinessInteraction(
IdGenerator.getAndIncrement(),
BusinessInteractionCode.UPDATE_CONTACT.code,
ZonedDateTime.now().minusMonths(6)
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package uk.gov.justice.digital.hmpps.data.generator

import uk.gov.justice.digital.hmpps.integrations.delius.contact.entity.CaseNoteType

object ContactTypeGenerator {
val CONTACT_TYPE = CaseNoteType(
IdGenerator.getAndIncrement(),
"C294",
false
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package uk.gov.justice.digital.hmpps.data.generator

import uk.gov.justice.digital.hmpps.integrations.delius.contact.entity.CaseNote
import java.time.ZonedDateTime

object CourtCaseNoteGenerator {
val CASE_NOTE = CaseNote(
IdGenerator.getAndIncrement(),
"2222",
PersonGenerator.CURRENTLY_MANAGED.id,
ContactTypeGenerator.CONTACT_TYPE,
"Existing notes",
ZonedDateTime.now(),
ZonedDateTime.now(),
StaffGenerator.ALLOCATED.id,
StaffGenerator.ALLOCATED.id,
1,
1
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package uk.gov.justice.digital.hmpps.data.generator

import uk.gov.justice.digital.hmpps.message.HmppsDomainEvent
import uk.gov.justice.digital.hmpps.resourceloader.ResourceLoader

object CourtCaseNoteMessageGenerator {
val EXISTS: HmppsDomainEvent = ResourceLoader.message("existing-court-case-note")
val NEW: HmppsDomainEvent = ResourceLoader.message("new-court-case-note")
val NOT_FOUND: HmppsDomainEvent = ResourceLoader.message("court-case-note-not-found")
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package uk.gov.justice.digital.hmpps.data.generator

import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.Person
import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.PersonManager

object PersonGenerator {
val NEW_TO_PROBATION = generate("N123456")
Expand All @@ -10,4 +11,7 @@ object PersonGenerator {

fun generate(crn: String, softDeleted: Boolean = false, id: Long = IdGenerator.getAndIncrement()) =
Person(crn, softDeleted, id)

fun generatePersonManager(person: Person) =
PersonManager(IdGenerator.getAndIncrement(), person.id, 1, StaffGenerator.ALLOCATED.id, StaffGenerator.ALLOCATED.id, 1)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"MessageId": "ae06c49e-1f41-4b9f-b2f2-dcca610d02cd",
"Type": "Notification",
"Timestamp": "2019-10-21T14:01:18.500Z",
"Message": "{\"eventType\":\"court-case-note.published\",\"version\":1,\"description\":\"A court case note has been created or amended\",\"occurredAt\":\"2022-10-18T08:19:19.451579+01:00\",\"detailUrl\":\"http://localhost:{wiremock.port}/court-case-notes/3333\",\"personReference\":{\"identifiers\":[{\"type\":\"CRN\",\"value\":\"AA123456\"}]}}",
"MessageAttributes": {
"eventType": {
"Type": "String",
"Value": "court-case-note.published"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"MessageId": "ae06c49e-1f41-4b9f-b2f2-dcca610d02cd",
"Type": "Notification",
"Timestamp": "2019-10-21T14:01:18.500Z",
"Message": "{\"eventType\":\"court-case-note.published\",\"version\":1,\"description\":\"A court case note has been created or amended\",\"occurredAt\":\"2023-10-18T08:19:19.451579+01:00\",\"detailUrl\":\"http://localhost:{wiremock.port}/court-case-notes/2222\",\"personReference\":{\"identifiers\":[{\"type\":\"CRN\",\"value\":\"C123456\"}]}}",
"MessageAttributes": {
"eventType": {
"Type": "String",
"Value": "court-case-note.published"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"MessageId": "ae06c49e-1f41-4b9f-b2f2-dcca610d02cd",
"Type": "Notification",
"Timestamp": "2019-10-21T14:01:18.500Z",
"Message": "{\"eventType\":\"court-case-note.published\",\"version\":1,\"description\":\"A court case note has been created or amended\",\"occurredAt\":\"2022-10-18T08:19:19.451579+01:00\",\"detailUrl\":\"http://localhost:{wiremock.port}/court-case-notes/1111\",\"personReference\":{\"identifiers\":[{\"type\":\"CRN\",\"value\":\"N123456\"}]}}",
"MessageAttributes": {
"eventType": {
"Type": "String",
"Value": "court-case-note.published"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"reference": "2222",
"notes": "Overwritten the existing notes about the court case."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"reference": "1111",
"notes": "Some new notes about the court case."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"mappings": [
{
"request": {
"method": "GET",
"url": "/court-case-notes/1111"
},
"response": {
"headers": {
"Content-Type": "application/json"
},
"status": 200,
"bodyFileName": "get-new-court-case-note.json"
}
},
{
"request": {
"method": "GET",
"url": "/court-case-notes/2222"
},
"response": {
"headers": {
"Accept": "application/json",
"Content-Type": "application/json"
},
"status": 200,
"bodyFileName": "get-existing-court-case-note.json"
}
},
{
"request": {
"method": "GET",
"url": "/court-case-notes/3333"
},
"response": {
"status": 404,
"headers": {
"Content-Type": "application/json"
},
"jsonBody": {
"status": 404,
"userMessage": "Resource with id [3333] not found.",
"developerMessage": "Resource with id [3333] not found."
}
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package uk.gov.justice.digital.hmpps

import com.github.tomakehurst.wiremock.WireMockServer
import org.hamcrest.MatcherAssert
import org.hamcrest.Matchers
import org.junit.jupiter.api.Test
import org.mockito.ArgumentMatchers.anyMap
import org.mockito.kotlin.eq
import org.mockito.kotlin.never
import org.mockito.kotlin.verify
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.boot.test.mock.mockito.SpyBean
import uk.gov.justice.digital.hmpps.audit.repository.AuditedInteractionRepository
import uk.gov.justice.digital.hmpps.data.generator.CourtCaseNoteMessageGenerator
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator
import uk.gov.justice.digital.hmpps.integrations.delius.repository.CaseNoteRepository
import uk.gov.justice.digital.hmpps.messaging.HmppsChannelManager
import uk.gov.justice.digital.hmpps.telemetry.TelemetryService
import java.time.ZonedDateTime

const val COURT_CASE_NOTE_MERGED = "CourtCaseNoteMerged"

@SpringBootTest
class CaseNotesIntegrationTest {

@Value("\${messaging.consumer.queue}")
private lateinit var queueName: String

@Autowired
private lateinit var channelManager: HmppsChannelManager

@Autowired
private lateinit var caseNoteRepository: CaseNoteRepository

@MockBean
private lateinit var telemetryService: TelemetryService

@Autowired
lateinit var wireMockserver: WireMockServer

@SpyBean
lateinit var air: AuditedInteractionRepository

@Test
fun `create a new court case note succesfully`() {
channelManager.getChannel(queueName).publishAndWait(
prepMessage(CourtCaseNoteMessageGenerator.NEW, wireMockserver.port())
)

val caseNote = caseNoteRepository.findByExternalReferenceAndOffenderIdAndSoftDeletedIsFalse("1111", PersonGenerator.NEW_TO_PROBATION.id)
MatcherAssert.assertThat(caseNote!!.notes, Matchers.equalTo("Some new notes about the court case."))

verify(telemetryService).trackEvent(eq(COURT_CASE_NOTE_MERGED), anyMap(), anyMap())
}

@Test
fun `replace a court case note succesfully`() {
val message = CourtCaseNoteMessageGenerator.EXISTS.copy(occurredAt = ZonedDateTime.now())

channelManager.getChannel(queueName).publishAndWait(
prepMessage(message, wireMockserver.port())
)

val caseNote = caseNoteRepository.findByExternalReferenceAndOffenderIdAndSoftDeletedIsFalse("2222", PersonGenerator.CURRENTLY_MANAGED.id)
MatcherAssert.assertThat(caseNote!!.notes, Matchers.equalTo("Overwritten the existing notes about the court case."))

verify(telemetryService).trackEvent(eq(COURT_CASE_NOTE_MERGED), anyMap(), anyMap())
}

@Test
fun `court case note not found - noop`() {
channelManager.getChannel(queueName).publishAndWait(
prepMessage(CourtCaseNoteMessageGenerator.NOT_FOUND, wireMockserver.port())
)

verify(telemetryService, never()).trackEvent(eq(COURT_CASE_NOTE_MERGED), anyMap(), anyMap())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package uk.gov.justice.digital.hmpps.api.config

import org.springframework.cloud.openfeign.EnableFeignClients
import org.springframework.context.annotation.Configuration
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager
import uk.gov.justice.digital.hmpps.config.feign.FeignConfig
import uk.gov.justice.digital.hmpps.integrations.courtcase.CourtCaseClient

@Configuration
@EnableFeignClients(clients = [CourtCaseClient::class])
class CourtCaseFeignConfig(
authorizedClientManager: OAuth2AuthorizedClientManager
) : FeignConfig(authorizedClientManager) {
override fun registrationId() = "court-case-and-delius"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package uk.gov.justice.digital.hmpps.integrations.courtcase

import org.springframework.cloud.openfeign.FeignClient
import org.springframework.web.bind.annotation.GetMapping
import java.net.URI

@FeignClient(name = "court-case", url = "https://dummy-url/to/be/overridden")
interface CourtCaseClient {
@GetMapping
fun getCourtCaseNote(baseUrl: URI): CourtCaseNote?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package uk.gov.justice.digital.hmpps.integrations.courtcase

data class CourtCaseNote(
val reference: String,
val notes: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package uk.gov.justice.digital.hmpps.integrations.delius.audit

import uk.gov.justice.digital.hmpps.audit.InteractionCode

enum class BusinessInteractionCode(override val code: String) : InteractionCode {
UPDATE_CONTACT("CLBI007")
}
Loading

0 comments on commit 5eb2bbc

Please sign in to comment.