Skip to content

Commit f3e3c30

Browse files
authored
PI-2584 Create contacts from emails (#4385)
* PI-2584 Create contacts from emails * Enable AsyncApi * Fix integration test errors for approved-premises-and-delius * Added tests for duplicate emails
1 parent 4b369fc commit f3e3c30

File tree

40 files changed

+776
-86
lines changed

40 files changed

+776
-86
lines changed

build.gradle.kts

+8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ plugins {
1717
id("com.google.cloud.tools.jib") apply false
1818
id("base")
1919
id("org.sonarqube")
20+
id("idea")
21+
}
22+
23+
idea {
24+
module {
25+
isDownloadJavadoc = true
26+
isDownloadSources = true
27+
}
2028
}
2129

2230
val agentDeps: Configuration by configurations.creating

libs/dev-tools/src/main/kotlin/uk/gov/justice/digital/hmpps/resourceloader/ResourceLoader.kt

+6-10
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,15 @@ object ResourceLoader {
2121
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
2222
.registerModule(SimpleModule().addDeserializer(ZonedDateTime::class.java, ZonedDateTimeDeserializer()))
2323

24-
fun event(filename: String): HmppsDomainEvent =
25-
MAPPER.readValue(ResourceUtils.getFile("classpath:messages/$filename.json"))
24+
fun event(filename: String): HmppsDomainEvent = get(filename)
2625

27-
inline fun <reified T> message(filename: String): T =
28-
MAPPER.readValue(
29-
MAPPER.readValue<Notification<String>>(
30-
ResourceUtils.getFile("classpath:messages/$filename.json")
31-
).message
32-
)
26+
inline fun <reified T> get(filename: String): T =
27+
MAPPER.readValue<T>(ResourceUtils.getFile("classpath:messages/$filename.json"))
28+
29+
inline fun <reified T> message(filename: String): T = MAPPER.readValue(get<Notification<String>>(filename).message)
3330

3431
inline fun <reified T> notification(filename: String): Notification<T> {
35-
val file = ResourceUtils.getFile("classpath:messages/$filename.json")
36-
val stringMessage = MAPPER.readValue<Notification<String>>(file)
32+
val stringMessage = get<Notification<String>>(filename)
3733
return Notification(
3834
message = MAPPER.readValue(stringMessage.message, T::class.java),
3935
attributes = stringMessage.attributes

projects/approved-premises-and-delius/src/main/resources/application.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ spring.datasource.url: jdbc:h2:mem:./test;MODE=Oracle;DEFAULT_NULL_ORDERING=HIGH
8585

8686
---
8787
spring.config.activate.on-profile: oracle
88-
spring.datasource.url: 'jdbc:tc:oracle:slim-faststart:///XEPDB1'
88+
spring:
89+
datasource.url: 'jdbc:tc:oracle:slim-faststart:///XEPDB1'
90+
jpa.hibernate.ddl-auto: create
8991

9092
---
9193
spring.config.activate.on-profile: delius-db

projects/justice-email-and-delius/build.gradle.kts

+5-2
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,22 @@ apply(plugin = "com.google.cloud.tools.jib")
55
dependencies {
66
implementation(project(":libs:audit"))
77
implementation(project(":libs:commons"))
8-
implementation(project(":libs:oauth-server"))
8+
implementation(project(":libs:messaging"))
99

1010
implementation("org.springframework.boot:spring-boot-starter-actuator")
1111
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
12+
implementation("org.springframework.boot:spring-boot-starter-data-ldap")
1213
implementation("org.springframework.boot:spring-boot-starter-security")
1314
implementation("org.springframework.boot:spring-boot-starter-validation")
1415
implementation("org.springframework.boot:spring-boot-starter-web")
1516
implementation("org.jetbrains.kotlin:kotlin-reflect")
1617
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
1718
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
18-
implementation(libs.springdoc)
19+
implementation(libs.azure.identity)
20+
implementation(libs.microsoft.graph)
1921

2022
dev(project(":libs:dev-tools"))
23+
dev("com.unboundid:unboundid-ldapsdk")
2124
dev("com.h2database:h2")
2225
dev("org.testcontainers:oracle-xe")
2326

projects/justice-email-and-delius/deploy/database/access.yml

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ database:
22
access:
33
username_key: /justice-email-and-delius/db-username
44
password_key: /justice-email-and-delius/db-password
5+
tables:
6+
- audited_interaction
7+
- contact
58

69
audit:
710
username: JusticeEmailAndDelius
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
enabled: false # TODO set this to true when you're ready to deploy your service
2-
31
generic-service:
42
ingress:
53
host: justice-email-and-delius-dev.hmpps.service.justice.gov.uk
@@ -10,8 +8,6 @@ generic-service:
108
env:
119
SENTRY_ENVIRONMENT: dev
1210
LOGGING_LEVEL_UK_GOV_DIGITAL_JUSTICE_HMPPS: DEBUG
13-
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: https://sign-in-dev.hmpps.service.justice.gov.uk/auth/.well-known/jwks.json
14-
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: https://sign-in-dev.hmpps.service.justice.gov.uk/auth/issuer
1511

1612
generic-prometheus-alerts:
1713
businessHoursOnly: true

projects/justice-email-and-delius/deploy/values-preprod.yml

-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ generic-service:
99

1010
env:
1111
SENTRY_ENVIRONMENT: preprod
12-
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: https://sign-in-preprod.hmpps.service.justice.gov.uk/auth/.well-known/jwks.json
13-
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: https://sign-in-preprod.hmpps.service.justice.gov.uk/auth/issuer
1412

1513
generic-prometheus-alerts:
1614
businessHoursOnly: true

projects/justice-email-and-delius/deploy/values-prod.yml

-2
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,3 @@ generic-service:
66

77
env:
88
SENTRY_ENVIRONMENT: prod
9-
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI: https://sign-in.hmpps.service.justice.gov.uk/auth/.well-known/jwks.json
10-
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: https://sign-in.hmpps.service.justice.gov.uk/auth/issuer

projects/justice-email-and-delius/deploy/values.yaml

+11
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
generic-service:
33
productId: HMPPS518
44
nameOverride: justice-email-and-delius
5+
serviceAccountName: justice-email-and-delius
56

67
image:
78
repository: ghcr.io/ministryofjustice/hmpps-probation-integration-services/justice-email-and-delius
@@ -12,11 +13,21 @@ generic-service:
1213
namespace_secrets:
1314
common:
1415
SPRING_DATASOURCE_URL: DB_URL
16+
SPRING_LDAP_URLS: LDAP_URL
17+
SPRING_LDAP_PASSWORD: LDAP_PASSWORD
1518
justice-email-and-delius-database:
1619
SPRING_DATASOURCE_USERNAME: DB_USERNAME
1720
SPRING_DATASOURCE_PASSWORD: DB_PASSWORD
1821
justice-email-and-delius-sentry:
1922
SENTRY_DSN: SENTRY_DSN
23+
justice-email-and-delius-queue:
24+
MESSAGING_PRODUCER_QUEUE: QUEUE_NAME
25+
MESSAGING_CONSUMER_QUEUE: QUEUE_NAME
26+
justice-email-and-delius-microsoft-graph:
27+
MICROSOFT-GRAPH_TENANT-ID: TENANT_ID
28+
MICROSOFT-GRAPH_CLIENT-ID: CLIENT_ID
29+
MICROSOFT-GRAPH_CLIENT-SECRET: CLIENT_SECRET
30+
MICROSOFT-GRAPH_EMAIL-ADDRESS: EMAIL_ADDRESS
2031

2132
generic-prometheus-alerts:
2233
targetApplication: justice-email-and-delius
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,50 @@
11
package uk.gov.justice.digital.hmpps.data
22

33
import jakarta.annotation.PostConstruct
4+
import jakarta.persistence.EntityManager
5+
import jakarta.transaction.Transactional
46
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
57
import org.springframework.boot.context.event.ApplicationReadyEvent
68
import org.springframework.context.ApplicationListener
79
import org.springframework.stereotype.Component
10+
import uk.gov.justice.digital.hmpps.data.generator.Data.BUSINESS_INTERACTIONS
11+
import uk.gov.justice.digital.hmpps.data.generator.Data.CONTACT_TYPES
12+
import uk.gov.justice.digital.hmpps.data.generator.Data.DUPLICATE_STAFF_1
13+
import uk.gov.justice.digital.hmpps.data.generator.Data.DUPLICATE_STAFF_2
14+
import uk.gov.justice.digital.hmpps.data.generator.Data.MANAGER
15+
import uk.gov.justice.digital.hmpps.data.generator.Data.MANAGER_STAFF
16+
import uk.gov.justice.digital.hmpps.data.generator.Data.PERSON
17+
import uk.gov.justice.digital.hmpps.data.generator.Data.STAFF
818
import uk.gov.justice.digital.hmpps.data.generator.UserGenerator
919
import uk.gov.justice.digital.hmpps.user.AuditUserRepository
1020

1121
@Component
1222
@ConditionalOnProperty("seed.database")
1323
class DataLoader(
14-
private val auditUserRepository: AuditUserRepository
24+
private val auditUserRepository: AuditUserRepository,
25+
private val entityManager: EntityManager,
1526
) : ApplicationListener<ApplicationReadyEvent> {
16-
1727
@PostConstruct
1828
fun saveAuditUser() {
1929
auditUserRepository.save(UserGenerator.AUDIT_USER)
2030
}
2131

32+
@Transactional
2233
override fun onApplicationEvent(are: ApplicationReadyEvent) {
23-
// Perform dev/test database setup here, using JPA repositories and generator classes...
34+
listOf(
35+
PERSON,
36+
STAFF,
37+
STAFF.user,
38+
DUPLICATE_STAFF_1,
39+
DUPLICATE_STAFF_1.user,
40+
DUPLICATE_STAFF_2,
41+
DUPLICATE_STAFF_2.user,
42+
MANAGER_STAFF,
43+
MANAGER,
44+
*CONTACT_TYPES,
45+
*BUSINESS_INTERACTIONS,
46+
).forEach {
47+
entityManager.persist(it)
48+
}
2449
}
2550
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package uk.gov.justice.digital.hmpps.data.generator
2+
3+
import uk.gov.justice.digital.hmpps.audit.BusinessInteraction
4+
import uk.gov.justice.digital.hmpps.audit.BusinessInteractionCode
5+
import uk.gov.justice.digital.hmpps.entity.*
6+
import uk.gov.justice.digital.hmpps.set
7+
import java.time.ZonedDateTime
8+
9+
object Data {
10+
val PERSON = Person(id(), crn = "A000001")
11+
val STAFF = staffWithUser(StaffUser(id(), username = "test-user"))
12+
val DUPLICATE_STAFF_1 = staffWithUser(StaffUser(id(), username = "duplicate1"))
13+
val DUPLICATE_STAFF_2 = staffWithUser(StaffUser(id(), username = "duplicate2"))
14+
val MANAGER_STAFF = Staff(id())
15+
val MANAGER = PersonManager(id(), PERSON, MANAGER_STAFF.id, 102, 103)
16+
val CONTACT_TYPES = ContactType.Code.entries.map { ContactType(id(), it.code) }.toTypedArray()
17+
val BUSINESS_INTERACTIONS = BusinessInteractionCode.entries
18+
.map { BusinessInteraction(id(), it.code, ZonedDateTime.now()) }.toTypedArray()
19+
20+
private fun id() = IdGenerator.getAndIncrement()
21+
22+
private fun staffWithUser(user: StaffUser) = Staff(id(), user = user).also { user.set("staff", it) }
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"id": "00000000-0000-0000-0000-000000000000",
3+
"subject": "RE: A000001 and B000002",
4+
"bodyContent": "Example message",
5+
"fromEmailAddress": "[email protected]",
6+
"receivedDateTime": "2020-01-01T12:34:56Z[Europe/London]"
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"id": "00000000-0000-0000-0000-000000000000",
3+
"subject": "RE: A000001",
4+
"bodyContent": "Example message",
5+
"fromEmailAddress": "[email protected]",
6+
"receivedDateTime": "2020-01-01T12:34:56Z[Europe/London]"
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"id": "00000000-0000-0000-0000-000000000000",
3+
"subject": "No CRN here!",
4+
"bodyContent": "Example message",
5+
"fromEmailAddress": "[email protected]",
6+
"receivedDateTime": "2020-01-01T12:34:56Z[Europe/London]"
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"id": "00000000-0000-0000-0000-000000000000",
3+
"subject": "RE: A000001",
4+
"bodyContent": "Example message",
5+
"fromEmailAddress": "[email protected]",
6+
"receivedDateTime": "2020-01-01T12:34:56Z[Europe/London]"
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"id": "00000000-0000-0000-0000-000000000000",
3+
"subject": "RE: A000001",
4+
"bodyContent": "Example message",
5+
"fromEmailAddress": "[email protected]",
6+
"receivedDateTime": "2020-01-01T12:34:56Z[Europe/London]"
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"id": "00000000-0000-0000-0000-000000000000",
3+
"subject": "RE: A000001",
4+
"bodyContent": "Example message",
5+
"fromEmailAddress": "[email protected]",
6+
"receivedDateTime": "2020-01-01T12:34:56Z[Europe/London]"
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
dn: ou=Users,dc=moj,dc=com
2+
objectclass: top
3+
objectclass: organizationalUnit
4+
ou: Users
5+
6+
dn: cn=test-user,ou=Users,dc=moj,dc=com
7+
objectclass: top
8+
objectclass: inetOrgPerson
9+
cn: test-user
10+
sn: test-user
11+
12+
13+
dn: cn=duplicate1,ou=Users,dc=moj,dc=com
14+
objectclass: top
15+
objectclass: inetOrgPerson
16+
cn: duplicate1
17+
sn: duplicate1
18+
19+
20+
dn: cn=duplicate2,ou=Users,dc=moj,dc=com
21+
objectclass: top
22+
objectclass: inetOrgPerson
23+
cn: duplicate2
24+
sn: duplicate2
25+
26+

0 commit comments

Comments
 (0)