Skip to content

Commit

Permalink
PI-2575 Initial integration for creating person records (#4319)
Browse files Browse the repository at this point in the history
* PI-2575
- Create common-platform-and-delius service

* Formatting changes

* PI-2575
- Update handler tests

* Formatting changes

* PI-2575
- Test Fixes + changed court code lookup to use nationalCourtCode db column on COURT table

* PI-2575
- Insert address logic implemented

* Formatting changes

* PI-2575
- Added notifier to publish sns messages (probation-case.engagement.created) when insert person is performed

* Formatting changes

* PI-2575
- Entity changes to match delius database
- Removed oracle profile from application.yml

* Formatting changes

* PI-2575
- Added Address sns created notification
- Filter hearing message to cases containing judicial results with label Remanded in custody

* Formatting changes

* PI-2575
- PR Review Feedback

* Formatting changes

* PI-2575
- PR Review Feedback

* PI-2575
- PR Review Feedback

---------

Co-authored-by: probation-integration-bot[bot] <177347787+probation-integration-bot[bot]@users.noreply.github.com>
  • Loading branch information
1 parent 1ed05b6 commit 3bbb30b
Show file tree
Hide file tree
Showing 42 changed files with 1,983 additions and 102 deletions.
11 changes: 10 additions & 1 deletion projects/common-platform-and-delius/deploy/database/access.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,16 @@ database:
username_key: /common-platform-and-delius/db-username
password_key: /common-platform-and-delius/db-password

tables:
- offender
- offender_manager
- equality
- audited_interaction
- address
packages:
- offender_support_api # for generating crn

audit:
username: CommonPlatformAndDelius
forename: Common Platform
surname: Service
surname: Service
2 changes: 0 additions & 2 deletions projects/common-platform-and-delius/deploy/values-dev.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
enabled: false

generic-service:
ingress:
host: common-platform-and-delius-dev.hmpps.service.justice.gov.uk
Expand Down
2 changes: 0 additions & 2 deletions projects/common-platform-and-delius/deploy/values-preprod.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
enabled: false

generic-service:
ingress:
host: common-platform-and-delius-preprod.hmpps.service.justice.gov.uk
Expand Down
2 changes: 2 additions & 0 deletions projects/common-platform-and-delius/deploy/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ generic-service:
SENTRY_DSN: SENTRY_DSN
common-platform-and-delius-queue:
MESSAGING_CONSUMER_QUEUE: QUEUE_NAME
hmpps-domain-events-topic:
MESSAGING_PRODUCER_TOPIC: topic_arn

generic-prometheus-alerts:
targetApplication: common-platform-and-delius
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package uk.gov.justice.digital.hmpps.data

import jakarta.annotation.PostConstruct
import jakarta.persistence.EntityManager
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.context.ApplicationListener
import org.springframework.stereotype.Component
import uk.gov.justice.digital.hmpps.data.generator.UserGenerator
import org.springframework.transaction.annotation.Transactional
import uk.gov.justice.digital.hmpps.data.generator.*
import uk.gov.justice.digital.hmpps.user.AuditUserRepository

@Component
@ConditionalOnProperty("seed.database")
class DataLoader(
private val entityManager: EntityManager,
private val auditUserRepository: AuditUserRepository
) : ApplicationListener<ApplicationReadyEvent> {

Expand All @@ -19,7 +22,26 @@ class DataLoader(
auditUserRepository.save(UserGenerator.AUDIT_USER)
}

@Transactional
override fun onApplicationEvent(are: ApplicationReadyEvent) {
// Perform dev/test database setup here, using JPA repositories and generator classes...
entityManager.run {
persist(BusinessInteractionGenerator.INSERT_PERSON)
persist(BusinessInteractionGenerator.INSERT_ADDRESS)
persist(DatasetGenerator.GENDER)
persist(DatasetGenerator.OM_ALLOCATION_REASON)
persist(DatasetGenerator.ADDRESS_STATUS)
persist(DatasetGenerator.ADDRESS_TYPE)
persist(ReferenceDataGenerator.GENDER_MALE)
persist(ReferenceDataGenerator.GENDER_FEMALE)
persist(ReferenceDataGenerator.INITIAL_ALLOCATION)
persist(ReferenceDataGenerator.MAIN_ADDRESS_STATUS)
persist(ReferenceDataGenerator.AWAITING_ASSESSMENT)
persist(ProviderGenerator.DEFAULT)
persist(TeamGenerator.ALLOCATED)
persist(TeamGenerator.UNALLOCATED)
persist(StaffGenerator.UNALLOCATED)
persist(StaffGenerator.ALLOCATED)
persist(CourtGenerator.UNKNOWN_COURT_N07_PROVIDER)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
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 INSERT_PERSON = BusinessInteraction(
IdGenerator.getAndIncrement(),
BusinessInteractionCode.INSERT_PERSON.code,
ZonedDateTime.now().minusMonths(6)
)
val INSERT_ADDRESS = BusinessInteraction(
IdGenerator.getAndIncrement(),
BusinessInteractionCode.INSERT_ADDRESS.code,
ZonedDateTime.now().minusMonths(6)
)
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
package uk.gov.justice.digital.hmpps.data.generator

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

object MessageGenerator {
val EXAMPLE = ResourceLoader.message<HmppsDomainEvent>("example-message")
val COMMON_PLATFORM_EVENT = ResourceLoader.message<CommonPlatformHearing>("common-platform-hearing")
val COMMON_PLATFORM_EVENT_DOB_ERROR =
ResourceLoader.message<CommonPlatformHearing>("common-platform-hearing-dob-error")
val COMMON_PLATFORM_EVENT_NO_CASES =
ResourceLoader.message<CommonPlatformHearing>("common-platform-hearing-no-cases")
val COMMON_PLATFORM_EVENT_BLANK_ADDRESS =
ResourceLoader.message<CommonPlatformHearing>("common-platform-hearing-blank-address")
val COMMON_PLATFORM_EVENT_NO_REMAND =
ResourceLoader.message<CommonPlatformHearing>("common-platform-hearing-no-remand")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package uk.gov.justice.digital.hmpps.data.generator

import uk.gov.justice.digital.hmpps.integrations.delius.entity.Person
import uk.gov.justice.digital.hmpps.integrations.delius.person.entity.PersonAddress
import java.time.LocalDate

object PersonAddressGenerator {
val MAIN_ADDRESS = generate(person = PersonGenerator.DEFAULT)

fun generate(
id: Long? = IdGenerator.getAndIncrement(),
person: Person,
notes: String? = null,
postcode: String? = null,
) = PersonAddress(
id = id,
start = LocalDate.now(),
status = ReferenceDataGenerator.MAIN_ADDRESS_STATUS,
person = person,
notes = notes,
postcode = postcode,
type = ReferenceDataGenerator.AWAITING_ASSESSMENT
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package uk.gov.justice.digital.hmpps.data.generator

import uk.gov.justice.digital.hmpps.integrations.delius.entity.*
import java.time.LocalDate
import java.time.LocalDateTime
import java.util.*
import kotlin.random.Random

object PersonGenerator {
val DEFAULT = generate(crn = "A000001")

fun generate(
crn: String,
id: Long? = IdGenerator.getAndIncrement()
) = Person(
id = id,
crn = crn,
forename = UUID.randomUUID().toString().substring(0, 15),
surname = UUID.randomUUID().toString().substring(0, 15),
dateOfBirth = LocalDate.now().minusYears(Random.nextInt(16, 76).toLong()),
gender = if (Random.nextBoolean()) ReferenceDataGenerator.GENDER_MALE else ReferenceDataGenerator.GENDER_FEMALE,
surnameSoundex = "surnameSoundex",
firstNameSoundex = "firstNameSoundex",
middleNameSoundex = null
)
}

object PersonManagerGenerator {

val DEFAULT = generate(person = PersonGenerator.DEFAULT)

fun generate(
id: Long = IdGenerator.getAndIncrement(),
person: Person,
provider: Provider = ProviderGenerator.DEFAULT,
team: Team = TeamGenerator.UNALLOCATED,
staff: Staff = StaffGenerator.UNALLOCATED,
allocationDate: LocalDateTime = LocalDateTime.of(1900, 1, 1, 0, 0),
allocationReason: ReferenceData = ReferenceDataGenerator.INITIAL_ALLOCATION
) = PersonManager(
id = id,
person = person,
provider = provider,
staff = staff,
staffEmployeeID = staff.id,
team = team,
trustProviderTeamId = team.id,
allocationDate = allocationDate,
allocationReason = allocationReason
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package uk.gov.justice.digital.hmpps.data.generator

import uk.gov.justice.digital.hmpps.data.generator.DatasetGenerator.ADDRESS_STATUS
import uk.gov.justice.digital.hmpps.data.generator.DatasetGenerator.ADDRESS_TYPE
import uk.gov.justice.digital.hmpps.data.generator.DatasetGenerator.GENDER
import uk.gov.justice.digital.hmpps.data.generator.DatasetGenerator.OM_ALLOCATION_REASON
import uk.gov.justice.digital.hmpps.integrations.delius.entity.*

object ReferenceDataGenerator {

val GENDER_FEMALE = generate(ReferenceData.GenderCode.FEMALE.deliusValue, GENDER.id, "Female")
val GENDER_MALE = generate(ReferenceData.GenderCode.MALE.deliusValue, GENDER.id, "Male")
val INITIAL_ALLOCATION = generate(
ReferenceData.StandardRefDataCode.INITIAL_ALLOCATION.code,
OM_ALLOCATION_REASON.id,
"Initial Allocation"
)
val MAIN_ADDRESS_STATUS =
generate(ReferenceData.StandardRefDataCode.ADDRESS_MAIN_STATUS.code, ADDRESS_STATUS.id, "Main")
val AWAITING_ASSESSMENT =
generate(ReferenceData.StandardRefDataCode.AWAITING_ASSESSMENT.code, ADDRESS_TYPE.id, "Awaiting Assessment")

fun generate(
code: String,
datasetId: Long,
description: String = "Description of $code",
id: Long = IdGenerator.getAndIncrement()
) = ReferenceData(id = id, code = code, datasetId = datasetId, description = description)
}

object DatasetGenerator {
val ALL_DATASETS = DatasetCode.entries.map { Dataset(IdGenerator.getAndIncrement(), it) }.associateBy { it.code }
val GENDER = ALL_DATASETS[DatasetCode.GENDER]!!
val OM_ALLOCATION_REASON = ALL_DATASETS[DatasetCode.OM_ALLOCATION_REASON]!!
val ADDRESS_TYPE = ALL_DATASETS[DatasetCode.ADDRESS_TYPE]!!
val ADDRESS_STATUS = ALL_DATASETS[DatasetCode.ADDRESS_STATUS]!!
}

object CourtGenerator {
val UNKNOWN_COURT_N07_PROVIDER = generate(code = "UNKNCT", ouCode = "A00AA00")

fun generate(
id: Long = IdGenerator.getAndIncrement(),
code: String,
selectable: Boolean = true,
courtName: String = "Court not known",
provider: Provider = ProviderGenerator.DEFAULT,
ouCode: String? = null,
) = Court(
id = id,
code = code,
selectable = selectable,
name = courtName,
provider = provider,
ouCode = ouCode
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package uk.gov.justice.digital.hmpps.data.generator

import uk.gov.justice.digital.hmpps.integrations.delius.entity.Provider
import uk.gov.justice.digital.hmpps.integrations.delius.entity.Staff
import uk.gov.justice.digital.hmpps.integrations.delius.entity.Team
import java.util.concurrent.atomic.AtomicLong

object StaffGenerator {
val UNALLOCATED = generate("N07UATU")
val ALLOCATED = generate("N07T01A")
fun generate(
code: String,
id: Long = IdGenerator.getAndIncrement(),
) =
Staff(code = code, id = id)
}

object ProviderGenerator {
val DEFAULT = generate()
fun generate(id: Long = IdGenerator.getAndIncrement()) = Provider(
id = id,
selectable = true,
code = "N07",
description = "London",
endDate = null,
)
}

object TeamGenerator {
private val teamCodeGenerator = AtomicLong(1)
val ALLOCATED = generate(code = "N07T01")
val UNALLOCATED = generate(code = "N07UAT")

fun generate(
code: String = "N07${teamCodeGenerator.getAndIncrement().toString().padStart(3, '0')}",
description: String = "Description of Team $code",
) = Team(
id = IdGenerator.getAndIncrement(),
code = code,
description = description,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
DROP SCHEMA IF EXISTS offender_support_api CASCADE;

CREATE SCHEMA offender_support_api;

CREATE ALIAS offender_support_api.getNextCRN AS
'String getNextCRN() {
return "A111111";
}';
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CREATE OR REPLACE PACKAGE offender_support_api AS
FUNCTION getNextCRN RETURN VARCHAR2;
END offender_support_api;

GRANT EXECUTE ON offender_support_api TO delius_app_schema;

CREATE OR REPLACE PACKAGE BODY offender_support_api AS
FUNCTION getNextCRN RETURN VARCHAR2 IS
BEGIN
RETURN 'A111111';
END getNextCRN;
END offender_support_api;
/
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"Type": "Notification",
"MessageId": "aa2c2828-167f-529b-8e19-73735a2fb85c",
"TopicArn": "arn:aws:sns:eu-west-2:000000000000:example",
"Message": "{\"hearing\":{\"id\":\"00000000-0000-0000-0000-000000000000\",\"courtCentre\":{\"id\":\"00000000-0000-0000-0000-000000000000\",\"code\":\"A00AA00\",\"roomId\":\"00000000-0000-0000-0000-000000000000\",\"roomName\":\"Courtroom 01\"},\"type\":{\"id\":\"00000000-0000-0000-0000-000000000000\",\"description\":\"First hearing\",\"welshDescription\":null},\"jurisdictionType\":\"MAGISTRATES\",\"hearingDays\":[{\"sittingDay\":\"2024-01-01T12:00:00\",\"listedDurationMinutes\":30,\"listingSequence\":1}],\"prosecutionCases\":[{\"id\":\"00000000-0000-0000-0000-000000000000\",\"initiationCode\":\"A\",\"prosecutionCaseIdentifier\":{\"prosecutionAuthorityCode\":\"AAAAA\",\"prosecutionAuthorityId\":\"00000000-0000-0000-0000-000000000000\",\"caseURN\":\"00AA000000\"},\"defendants\":[{\"id\":\"00000000-0000-0000-0000-000000000000\",\"offences\":[{\"id\":\"00000000-0000-0000-0000-000000000000\",\"offenceDefinitionId\":\"00000000-0000-0000-0000-000000000000\",\"offenceCode\":\"AA00000\",\"offenceTitle\":\"Example Offense Title\",\"wording\":\"Example of the offense committed\",\"offenceLegislation\":\"Example legislation\",\"listingNumber\":1,\"judicialResults\":[{\"isConvictedResult\":true,\"label\":\"Remanded in custody\",\"judicialResultTypeId\":\"00000000-0000-0000-0000-000000000000\",\"resultText\":\"RI - Remanded in custody\"}],\"plea\":null,\"verdict\":null}],\"prosecutionCaseId\":\"00000000-0000-0000-0000-000000000000\",\"personDefendant\":{\"personDetails\":{\"gender\":\"MALE\",\"lastName\":\"Example Last Name\",\"middleName\":null,\"firstName\":\"Example First Name\",\"dateOfBirth\":\"2000-01-01\",\"address\":{\"address1\":null,\"address2\":null,\"address3\":null,\"address4\":null,\"address5\":null,\"postcode\":null},\"contact\":{\"home\":null,\"mobile\":\"07000000000\",\"work\":null},\"ethnicity\":{\"observedEthnicityDescription\":\"White\",\"selfDefinedEthnicityDescription\":\"British\"}}},\"legalEntityDefendant\":null,\"masterDefendantId\":\"00000000-0000-0000-0000-000000000000\",\"pncId\":\"00000000000A\",\"croNumber\":\"000000/00A\"}],\"caseStatus\":\"ACTIVE\",\"caseMarkers\":[]}]}}",
"Timestamp": "2022-07-27T14:22:08.509Z",
"SignatureVersion": "1",
"Signature": "EXAMPLE",
"SigningCertURL": "https://sns.eu-west-2.amazonaws.com/EXAMPLE.pem",
"UnsubscribeURL": "https://sns.eu-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=EXAMPLE",
"MessageAttributes": {
"messageType": {
"Type": "String",
"Value": "COMMON_PLATFORM_HEARING"
},
"hearingEventType": {
"Type": "String",
"Value": "ConfirmedOrUpdated"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"Type": "Notification",
"MessageId": "aa2c2828-167f-529b-8e19-73735a2fb85c",
"TopicArn": "arn:aws:sns:eu-west-2:000000000000:example",
"Message": "{\"hearing\":{\"id\":\"00000000-0000-0000-0000-000000000000\",\"courtCentre\":{\"id\":\"00000000-0000-0000-0000-000000000000\",\"code\":\"A00AA00\",\"roomId\":\"00000000-0000-0000-0000-000000000000\",\"roomName\":\"Courtroom 01\"},\"type\":{\"id\":\"00000000-0000-0000-0000-000000000000\",\"description\":\"First hearing\",\"welshDescription\":null},\"jurisdictionType\":\"MAGISTRATES\",\"hearingDays\":[{\"sittingDay\":\"2024-01-01T12:00:00\",\"listedDurationMinutes\":30,\"listingSequence\":1}],\"prosecutionCases\":[{\"id\":\"00000000-0000-0000-0000-000000000000\",\"initiationCode\":\"A\",\"prosecutionCaseIdentifier\":{\"prosecutionAuthorityCode\":\"AAAAA\",\"prosecutionAuthorityId\":\"00000000-0000-0000-0000-000000000000\",\"caseURN\":\"00AA000000\"},\"defendants\":[{\"id\":\"00000000-0000-0000-0000-000000000000\",\"offences\":[{\"id\":\"00000000-0000-0000-0000-000000000000\",\"offenceDefinitionId\":\"00000000-0000-0000-0000-000000000000\",\"offenceCode\":\"AA00000\",\"offenceTitle\":\"Example Offense Title\",\"wording\":\"Example of the offense committed\",\"offenceLegislation\":\"Example legislation\",\"listingNumber\":1,\"judicialResults\":[{\"isConvictedResult\":true,\"label\":\"Remanded in custody\",\"judicialResultTypeId\":\"00000000-0000-0000-0000-000000000000\",\"resultText\":\"RI - Remanded in custody\"}],\"plea\":null,\"verdict\":null}],\"prosecutionCaseId\":\"00000000-0000-0000-0000-000000000000\",\"personDefendant\":{\"personDetails\":{\"gender\":\"MALE\",\"lastName\":\"Example Last Name\",\"middleName\":null,\"firstName\":\"Example First Name\",\"dateOfBirth\":\"2020-01-01\",\"address\":{\"address1\":\"Example Address Line 1\",\"address2\":\"Example Address Line 2\",\"address3\":\"Example Address Line 3\",\"address4\":null,\"address5\":null,\"postcode\":\"AA1 1AA\"},\"contact\":{\"home\":\"01234567890\",\"mobile\":\"07000000000\",\"work\":null},\"ethnicity\":{\"observedEthnicityDescription\":\"White\",\"selfDefinedEthnicityDescription\":\"British\"}}},\"legalEntityDefendant\":null,\"masterDefendantId\":\"00000000-0000-0000-0000-000000000000\",\"pncId\":\"00000000000A\",\"croNumber\":\"000000/00A\"}],\"caseStatus\":\"ACTIVE\",\"caseMarkers\":[]}]}}",
"Timestamp": "2022-07-27T14:22:08.509Z",
"SignatureVersion": "1",
"Signature": "EXAMPLE",
"SigningCertURL": "https://sns.eu-west-2.amazonaws.com/EXAMPLE.pem",
"UnsubscribeURL": "https://sns.eu-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=EXAMPLE",
"MessageAttributes": {
"messageType": {
"Type": "String",
"Value": "COMMON_PLATFORM_HEARING"
},
"hearingEventType": {
"Type": "String",
"Value": "ConfirmedOrUpdated"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"Type": "Notification",
"MessageId": "aa2c2828-167f-529b-8e19-73735a2fb85c",
"TopicArn": "arn:aws:sns:eu-west-2:000000000000:example",
"Message": "{\"hearing\":{\"id\":\"00000000-0000-0000-0000-000000000000\",\"courtCentre\":{\"id\":\"00000000-0000-0000-0000-000000000000\",\"code\":\"A00AA00\",\"roomId\":\"00000000-0000-0000-0000-000000000000\",\"roomName\":\"Courtroom 01\"},\"type\":{\"id\":\"00000000-0000-0000-0000-000000000000\",\"description\":\"First hearing\",\"welshDescription\":null},\"jurisdictionType\":\"MAGISTRATES\",\"hearingDays\":[{\"sittingDay\":\"2024-01-01T12:00:00\",\"listedDurationMinutes\":30,\"listingSequence\":1}],\"prosecutionCases\":[]}}",
"Timestamp": "2022-07-27T14:22:08.509Z",
"SignatureVersion": "1",
"Signature": "EXAMPLE",
"SigningCertURL": "https://sns.eu-west-2.amazonaws.com/EXAMPLE.pem",
"UnsubscribeURL": "https://sns.eu-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=EXAMPLE",
"MessageAttributes": {
"messageType": {
"Type": "String",
"Value": "COMMON_PLATFORM_HEARING"
},
"hearingEventType": {
"Type": "String",
"Value": "ConfirmedOrUpdated"
}
}
}
Loading

0 comments on commit 3bbb30b

Please sign in to comment.