Skip to content

Commit

Permalink
PI-1284 Migrate prison-to-probation-update listener to prison-identif…
Browse files Browse the repository at this point in the history
…ier-and-delius (#3478)
  • Loading branch information
marcus-bcl authored Mar 19, 2024
1 parent c85cfc5 commit ebcb1fe
Show file tree
Hide file tree
Showing 61 changed files with 1,729 additions and 580 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import uk.gov.justice.digital.hmpps.publisher.NotificationPublisher
import java.time.Duration
import java.time.LocalDateTime
import java.time.LocalTime
import java.util.LinkedList
import java.util.Queue
import java.util.UUID
import java.util.*
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException
import java.util.concurrent.locks.ReentrantLock
Expand Down Expand Up @@ -139,7 +137,7 @@ class HmppsNotificationListener(

@Component
@ConditionalOnProperty("messaging.producer.topic")
class HmppsNotificationPublisher(
class TopicPublisher(
@Value("\${messaging.producer.topic}") private val topicName: String,
private val channelManager: HmppsChannelManager
) : NotificationPublisher {
Expand All @@ -150,7 +148,7 @@ class HmppsNotificationPublisher(

@Component
@ConditionalOnProperty("messaging.producer.queue")
class HmppsQueuePublisher(
class QueuePublisher(
@Value("\${messaging.producer.queue}") private val queueName: String,
private val channelManager: HmppsChannelManager
) : NotificationPublisher {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import java.util.concurrent.Semaphore
@Component
@Conditional(AwsCondition::class)
@ConditionalOnProperty("messaging.producer.queue")
class AwsQueuePublisher(
class QueuePublisher(
private val sqsTemplate: SqsTemplate,
private val objectMapper: ObjectMapper,
@Value("\${messaging.producer.queue}") private val queue: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import uk.gov.justice.digital.hmpps.message.Notification
@Component
@Conditional(AwsCondition::class)
@ConditionalOnProperty("messaging.producer.topic")
class AwsNotificationPublisher(
class TopicPublisher(
private val notificationTemplate: SnsTemplate,
@Value("\${messaging.producer.topic}") private val topic: String
) : NotificationPublisher {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import uk.gov.justice.digital.hmpps.message.MessageAttributes
import uk.gov.justice.digital.hmpps.message.Notification

@ExtendWith(MockitoExtension::class)
class AwsNotificationPublisherTest {
class TopicPublisherTest {

@Mock
lateinit var notificationTemplate: SnsTemplate
Expand All @@ -29,7 +29,7 @@ class AwsNotificationPublisherTest {

@BeforeEach
fun setup() {
publisher = AwsNotificationPublisher(notificationTemplate, "my-topic")
publisher = TopicPublisher(notificationTemplate, "my-topic")
}

@Test
Expand Down
25 changes: 14 additions & 11 deletions projects/prison-identifier-and-delius/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,22 @@ HMPPS has a number of systems each holding information about a person's interact

The matching process can be triggered by a request to the integration service API endpoint

| Business Event | API Endpoint |
|-----------------------|------------------------------|
| List of CRNs to Match | /person/populate-noms-number |
| Business Event | API Endpoint |
|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| List of CRNs to Match | [/person/match-by-crn](https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/prison-identifier-and-delius/api-reference.html#person-match-by-crn) |
| List of NOMIS IDs to Match | [/person/match-by-noms](https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/prison-identifier-and-delius/api-reference.html#person-match-by-noms) |

### Domain Event Processing (Not Yet Implemented)
### Domain Event Processing

The matching process will be triggered by domain events raised by Delius, once these events are implemented

| Business Event | Message Event Type / Filter |
|------------------------------------|---------------------------------|
| New Sentence Added to Delius | probation-case.sentence.created |
| Sentence Changed in Delius | probation-case.sentence.amended |
| Sentence Moved to New Delius Event | probation-case.sentence.move |
| Business Event | Message Event Type / Filter | Status |
|------------------------------------|------------------------------------------|---------------------|
| New Sentence Added to Delius | probation-case.sentence.created | Not yet implemented |
| Sentence Changed in Delius | probation-case.sentence.amended | Not yet implemented |
| Sentence Moved to New Delius Event | probation-case.sentence.move | Not yet implemented |
| Prisoner received into NOMIS | prison-offender-events.prisoner.received | Active |
| Prisoner merged in NOMIS | prison-offender-events.prisoner.merged | Active |

## Workflows

Expand All @@ -41,8 +44,8 @@ The matching process will be triggered by domain events raised by Delius, once t
API endpoints are secured by roles supplied by the HMPPS Auth client used in
the requests

| API Endpoint | Required Role |
|--------------|-------------------------------------------------|
| API Endpoint | Required Role |
|--------------|--------------------------------------------------|
| All | ROLE\_PROBATION\_API_\_PRISON_IDENTIFIER__UPDATE |

## Concepts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ database:
username_key: /prison-identifier-and-delius/db-username
password_key: /prison-identifier-and-delius/db-password
tables:
- offender
- additional_identifier
- custody
- offender
- offender_prisoner

audit:
username: PrisonIdentifierAndDelius
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ spec:
args:
- /bin/sh
- -c
- 'curl -fsSL -X POST "https://$BASE_URL/person/populate-noms-number?dryRun=$DRY_RUN" --header "Authorization: Bearer $(curl -fsSL --request POST "$AUTH_URL?grant_type=client_credentials" --user "$CLIENT_ID:$CLIENT_SECRET" | jq -r .access_token)" --header "Content-Type: application/json"'
- 'curl -fsSL -X POST "https://$BASE_URL/person/match-by-crn?dryRun=$DRY_RUN" --header "Authorization: Bearer $(curl -fsSL --request POST "$AUTH_URL?grant_type=client_credentials" --user "$CLIENT_ID:$CLIENT_SECRET" | jq -r .access_token)" --header "Content-Type: application/json"'
env:
- name: AUTH_URL
value: {{ index .Values "generic-service" "env" "SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_HMPPS-AUTH_TOKEN-URI" }}
Expand Down
2 changes: 2 additions & 0 deletions projects/prison-identifier-and-delius/deploy/values-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ generic-service:
SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_HMPPS-AUTH_TOKEN-URI: http://hmpps-auth.hmpps-auth-dev.svc.cluster.local/auth/oauth/token
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: http://hmpps-auth.hmpps-auth-dev.svc.cluster.local/auth/.well-known/jwks.json

INTEGRATIONS_PRISON-API_URL: https://prison-api-dev.prison.service.justice.gov.uk
INTEGRATIONS_PRISONER-SEARCH_URL: https://prisoner-search-dev.prison.service.justice.gov.uk
INTEGRATIONS_PROBATION-SEARCH_URL: https://probation-offender-search-dev.hmpps.service.justice.gov.uk

SPRING_DATASOURCE_HIKARI_MAXIMUMPOOLSIZE: 5
SPRING_DATASOURCE_HIKARI_MINIMUMIDLE: 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ generic-service:
SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_HMPPS-AUTH_TOKEN-URI: http://hmpps-auth.hmpps-auth-preprod.svc.cluster.local/auth/oauth/token
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: http://hmpps-auth.hmpps-auth-preprod.svc.cluster.local/auth/.well-known/jwks.json

INTEGRATIONS_PRISON-API_URL: https://prison-api-preprod.prison.service.justice.gov.uk
INTEGRATIONS_PRISONER-SEARCH_URL: https://prisoner-search-preprod.prison.service.justice.gov.uk
INTEGRATIONS_PROBATION-SEARCH_URL: https://probation-offender-search-preprod.hmpps.service.justice.gov.uk

generic-prometheus-alerts:
businessHoursOnly: true
Expand Down
2 changes: 2 additions & 0 deletions projects/prison-identifier-and-delius/deploy/values-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ generic-service:
SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_HMPPS-AUTH_TOKEN-URI: http://hmpps-auth.hmpps-auth-prod.svc.cluster.local/auth/oauth/token
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: http://hmpps-auth.hmpps-auth-prod.svc.cluster.local/auth/.well-known/jwks.json

INTEGRATIONS_PRISON-API_URL: https://api.prison.service.justice.gov.uk
INTEGRATIONS_PRISONER-SEARCH_URL: https://prisoner-search.prison.service.justice.gov.uk
INTEGRATIONS_PROBATION-SEARCH_URL: https://probation-offender-search.hmpps.service.justice.gov.uk

noms:
update:
Expand Down
2 changes: 2 additions & 0 deletions projects/prison-identifier-and-delius/deploy/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ generic-service:
prison-identifier-and-delius-queue:
MESSAGING_CONSUMER_QUEUE: QUEUE_NAME
MESSAGING_PRODUCER_QUEUE: QUEUE_NAME
hmpps-domain-events-topic:
MESSAGING_PRODUCER_TOPIC: topic_arn

generic-prometheus-alerts:
targetApplication: prison-identifier-and-delius
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.generateCustody
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.generateDisposal
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.generateEvent
import uk.gov.justice.digital.hmpps.data.generator.ReferenceDataGenerator
import uk.gov.justice.digital.hmpps.data.generator.UserGenerator
import uk.gov.justice.digital.hmpps.user.AuditUserRepository
import java.time.LocalDate
import java.time.format.DateTimeFormatter

@Component
@ConditionalOnProperty("seed.database")
Expand All @@ -31,44 +31,40 @@ class DataLoader(
@Transactional
override fun onApplicationEvent(are: ApplicationReadyEvent) {
val personWithNomsEvent = generateEvent(PersonGenerator.PERSON_WITH_NOMS)
val personWithNomsDisposal = generateDisposal(LocalDate.now(), personWithNomsEvent)
val personWithNomsDisposal = generateDisposal(LocalDate.of(2022, 11, 11), personWithNomsEvent)
val personWithNomsCustody = generateCustody(personWithNomsDisposal)

val personWithNoNomsNumberEvent = generateEvent(PersonGenerator.PERSON_WITH_NO_NOMS)
val personWithNoNomsNumberDisposal = generateDisposal(
LocalDate.parse("12/12/2022", DateTimeFormatter.ofPattern("MM/dd/yyyy")),
personWithNoNomsNumberEvent
)
val personWithNoNomsNumberDisposal = generateDisposal(LocalDate.of(2022, 12, 12), personWithNoNomsNumberEvent)
val personWithNoNomsNumberCustody = generateCustody(personWithNoNomsNumberDisposal)

val personWithMultiMatchEvent = generateEvent(PersonGenerator.PERSON_WITH_MULTI_MATCH)
val personWithMultiMatchDisposal = generateDisposal(
LocalDate.parse("12/12/2022", DateTimeFormatter.ofPattern("MM/dd/yyyy")),
personWithMultiMatchEvent
)
val personWithMultiMatchDisposal = generateDisposal(LocalDate.of(2022, 12, 12), personWithMultiMatchEvent)
val personWithMultiMatchCustody = generateCustody(personWithMultiMatchDisposal)

val personWithNoMatchEvent = generateEvent(PersonGenerator.PERSON_WITH_NO_MATCH)
val personWithNoMatchDisposal = generateDisposal(
LocalDate.parse("12/12/2022", DateTimeFormatter.ofPattern("MM/dd/yyyy")),
personWithNoMatchEvent
)
val personWithNoMatchDisposal = generateDisposal(LocalDate.of(2022, 12, 12), personWithNoMatchEvent)
val personWithNoMatchCustody = generateCustody(personWithNoMatchDisposal)

val personWithNomsInDeliusEvent = generateEvent(PersonGenerator.PERSON_WITH_NOMS_IN_DELIUS)
val personWithNomsInDeliusDisposal = generateDisposal(
LocalDate.parse("12/12/2022", DateTimeFormatter.ofPattern("MM/dd/yyyy")),
personWithNomsInDeliusEvent
)
val personWithNomsInDeliusDisposal = generateDisposal(LocalDate.of(2022, 12, 12), personWithNomsInDeliusEvent)
val personWithNomsInDeliusCustody = generateCustody(personWithNomsInDeliusDisposal)

em.saveAll(
PersonGenerator.MALE,
ReferenceDataGenerator.GENDER_SET,
ReferenceDataGenerator.MALE,
ReferenceDataGenerator.CUSTODY_STATUS_SET,
ReferenceDataGenerator.CUSTODY_STATUS,
ReferenceDataGenerator.ADDITIONAL_IDENTIFIER_TYPE_SET,
ReferenceDataGenerator.DUPLICATE_NOMS,
ReferenceDataGenerator.FORMER_NOMS,
PersonGenerator.PERSON_WITH_NOMS,
PersonGenerator.PERSON_WITH_NO_NOMS,
PersonGenerator.PERSON_WITH_MULTI_MATCH,
PersonGenerator.PERSON_WITH_NO_MATCH,
PersonGenerator.PERSON_WITH_NOMS_IN_DELIUS,
PersonGenerator.PERSON_WITH_DUPLICATE_NOMS,
PersonGenerator.PERSON_WITH_EXISTING_NOMS,
personWithNomsEvent,
personWithNomsDisposal,
personWithNomsCustody,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
package uk.gov.justice.digital.hmpps.data.generator

import uk.gov.justice.digital.hmpps.integrations.delius.entity.*
import uk.gov.justice.digital.hmpps.entity.*
import java.time.LocalDate
import java.time.format.DateTimeFormatter

object PersonGenerator {
val MALE = generateGender("M")
val PERSON_WITH_NOMS = generate("A000001", "E1234XS")
val PERSON_WITH_NO_NOMS = generate("A000002", pncNumber = "07/220000004Q")
val PERSON_WITH_NOMS_IN_DELIUS = generate("A000005", pncNumber = "07/220000004Q")
val PERSON_WITH_MULTI_MATCH = generate("A000003", forename = "Jack", surname = "Jones")
val PERSON_WITH_NO_MATCH = generate("A000004", forename = "Fred", surname = "Jones", dobString = "12/12/2001")
val PERSON_WITH_NOMS_IN_DELIUS = generate("A000005", pncNumber = "07/220000004Q")
val PERSON_WITH_DUPLICATE_NOMS = generate("A000006", "G5541UN")
val PERSON_WITH_EXISTING_NOMS = generate("A000007", "A0007AA")

fun generate(
crn: String,
noms: String? = null,
pncNumber: String? = null,
gender: ReferenceData = MALE,
gender: ReferenceData = ReferenceDataGenerator.MALE,
forename: String = "bob",
surname: String = "smith",
softDeleted: Boolean = false,
Expand All @@ -32,6 +33,7 @@ object PersonGenerator {
surname,
noms,
null,
null,
pncNumber,
gender,
listOf(),
Expand All @@ -45,7 +47,6 @@ object PersonGenerator {
Disposal(id, startDate, event, active = true, softDeleted = false)

fun generateCustody(disposal: Disposal, id: Long = IdGenerator.getAndIncrement()) =
Custody(id, null, disposal = disposal)

fun generateGender(code: String, id: Long = IdGenerator.getAndIncrement()) = ReferenceData(id, code)
Custody(id, null, status = ReferenceDataGenerator.CUSTODY_STATUS, disposal = disposal)
}

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

import uk.gov.justice.digital.hmpps.entity.ReferenceData
import uk.gov.justice.digital.hmpps.entity.ReferenceDataSet

object ReferenceDataGenerator {
val GENDER_SET = generateReferenceDataSet("GENDER")
val MALE = generateGender("M")

val CUSTODY_STATUS_SET = generateReferenceDataSet("THROUGHCARE STATUS")
val CUSTODY_STATUS = generateCustodyStatus("A")

val ADDITIONAL_IDENTIFIER_TYPE_SET = generateReferenceDataSet("ADDITIONAL IDENTIFIER TYPE")
val DUPLICATE_NOMS = generateIdentifierType("DNOMS")
val FORMER_NOMS = generateIdentifierType("XNOMS")

fun generateGender(code: String, id: Long = IdGenerator.getAndIncrement()) = ReferenceData(id, code, GENDER_SET)
fun generateCustodyStatus(code: String, id: Long = IdGenerator.getAndIncrement()) =
ReferenceData(id, code, CUSTODY_STATUS_SET)

fun generateIdentifierType(code: String, id: Long = IdGenerator.getAndIncrement()) =
ReferenceData(id, code, ADDITIONAL_IDENTIFIER_TYPE_SET)

fun generateReferenceDataSet(name: String, id: Long = IdGenerator.getAndIncrement()) = ReferenceDataSet(id, name)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"version": 1,
"eventType": "prison-offender-events.prisoner.merged",
"description": "A prisoner has been merged from A0001AA to B0001BB",
"occurredAt": "2024-03-14T16:14:47Z",
"publishedAt": "2024-03-14T16:14:48.060048501Z",
"additionalInformation": {
"nomsNumber": "B0007BB",
"removedNomsNumber": "A0007AA",
"reason": "MERGE"
},
"personReference": {
"identifiers": [
{
"type": "NOMS",
"value": "A0007AA"
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"version": 1,
"eventType": "prison-offender-events.prisoner.received",
"description": "A prisoner has been received into prison",
"occurredAt": "2023-08-04T08:09:36.649098+01:00",
"publishedAt": "2023-08-04T09:06:46.65281576+01:00",
"additionalInformation": {
"nomsNumber": "A0002AA",
"reason": "ADMISSION",
"probableCause": "RECALL",
"source": "PRISON",
"nomisMovementReasonCode": "N",
"details": "ACTIVE IN:ADM-N",
"currentLocation": "IN_PRISON",
"prisonId": "WSI",
"currentPrisonStatus": "UNDER_PRISON_CARE"
},
"personReference": {
"identifiers": [
{
"type": "NOMS",
"value": "A0002AA"
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"version": 1,
"eventType": "prison-offender-events.prisoner.received",
"description": "A prisoner has been received into prison",
"occurredAt": "2023-08-04T08:09:36.649098+01:00",
"publishedAt": "2023-08-04T09:06:46.65281576+01:00",
"additionalInformation": {
"nomsNumber": "A0001AA",
"reason": "ADMISSION",
"probableCause": "RECALL",
"source": "PRISON",
"nomisMovementReasonCode": "N",
"details": "ACTIVE IN:ADM-N",
"currentLocation": "IN_PRISON",
"prisonId": "WSI",
"currentPrisonStatus": "UNDER_PRISON_CARE"
},
"personReference": {
"identifiers": [
{
"type": "NOMS",
"value": "A0001AA"
}
]
}
}
Loading

0 comments on commit ebcb1fe

Please sign in to comment.