Skip to content

Commit

Permalink
PI-1579 added test
Browse files Browse the repository at this point in the history
  • Loading branch information
stevomcallister committed Oct 23, 2023
1 parent 603aa74 commit a6e696c
Show file tree
Hide file tree
Showing 14 changed files with 189 additions and 54 deletions.
3 changes: 3 additions & 0 deletions projects/cas3-and-delius/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ dependencies {
implementation(project(":libs:audit"))
implementation(project(":libs:commons"))
implementation(project(":libs:messaging"))
implementation(project(":libs:oauth-client"))

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

dev(project(":libs:dev-tools"))
dev("com.h2database:h2")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCc2Dlk/NOvXrjSs83W+Nj4bMfz
6svg2ulfcqTcEoA/Vy6FWK3pOX50VZph3V0Sbh8OTRyHgTw3BRQKrxE/TdsUWw8A
QxgbjBWypmm6I/gUGeiSgYwATZpdVbqmuNI0BRg5l/vgJki6K5cg+4fRazZXaHvN
ldzA6bUDdyt73u7qSwIDAQAB
-----END PUBLIC KEY-----
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
{
"MessageId": "ae06c49e-1f41-4b9f-b2f2-dcca610d02cd",
"Type": "Notification",
"Timestamp": "2019-10-21T14:01:18.500Z",
"Message": "{\n \"eventType\": \"accommodation.cas3.referral.submitted\",\n \"version\": 1,\n \"description\": \"CAS3 Referral has been submitted\",\n \"detailUrl\": \"\",\n \"occurredAt\": \"2022-12-04T10:42:43+00:00\",\n \"additionalInformation\": {\n \"applicationId\": \"68df9f6c-3fcb-4ec6-8fcf-96551cd9b080\"\n },\n \"personReference\": {\n \"identifiers\": [\n {\n \"type\": \"CRN\",\n \"value\": \"A000001\"\n }\n ]\n }\n}",
"MessageAttributes": {
"eventType": {
"Type": "String",
"Value": "accommodation.cas3.referral.submitted"
}
"eventType": "accommodation.cas3.referral.submitted",
"version": 1,
"description": "A cas3 referral has been submitted",
"detailUrl": "http://localhost:{wiremock.port}/cas3-api/events/referral-submitted/1234",
"occurredAt": "2022-12-04T10:42:43+00:00",
"additionalInformation": {
"applicationId": "68df9f6c-3fcb-4ec6-8fcf-96551cd9b080"
},
"personReference": {
"identifiers": [
{
"type": "CRN",
"value": "A000001"
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"id": "364145f9-0af8-488e-9901-b4c46cd9ba37",
"timestamp": "2022-11-30T14:53:44",
"eventType": "accommodation.cas3.referral.submitted",
"eventDetails": {
"applicationId": "68df9f6c-3fcb-4ec6-8fcf-96551cd9b080",
"applicationUrl": "https://approved-premises-dev.hmpps.service.justice.gov.uk/application/68df9f6c-3fcb-4ec6-8fcf-96551cd9b080",
"personReference": {
"crn": "A000001",
"noms": "A0001AA"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJwcm9iYXRpb24taW50ZWdyYXRpb24tZGV2IiwiZ3JhbnRfdHlwZSI6ImNsaWVudF9jcmVkZW50aWFscyIsInVzZXJfbmFtZSI6InByb2JhdGlvbi1pbnRlZ3JhdGlvbi1kZXYiLCJzY29wZSI6WyJyZWFkIiwid3JpdGUiXSwiYXV0aF9zb3VyY2UiOiJub25lIiwiaXNzIjoiaHR0cHM6Ly9zaWduLWluLWRldi5obXBwcy5zZXJ2aWNlLmp1c3RpY2UuZ292LnVrL2F1dGgvaXNzdWVyIiwiZXhwIjo5OTk5OTk5OTk5LCJhdXRob3JpdGllcyI6WyJST0xFX0FQUFJPVkVEX1BSRU1JU0VTX1NUQUZGIl0sImp0aSI6IjI1RHVSbjEtaHlIWmV3TGNkSkp4d1ZMMDNLVSIsImNsaWVudF9pZCI6InByb2JhdGlvbi1pbnRlZ3JhdGlvbi1kZXYiLCJpYXQiOjE2NjM3NTczMTF9.HmAw0LBKPSHHyDh1egCb1i2ubjzDQ9x43XKDt-Qg09GsS7RuroBUm2BmRoCXPIapSve-BaUBWGa_pPopsaX6VBlzHBOWZPu68HaCkzBa82fwvyVPI3s88eJBUemEOZWQ0RmCx8KiPjK53-rZEhx_aEMJSQoHJIrFK86TjLwphk4",
"token_type": "bearer",
"expires_in": 9999999999,
"scope": "read write",
"sub": "probation-integration-dev",
"auth_source": "none",
"jti": "fN29JHJy1N7gcYvqe-8B_k5T0mA",
"iss": "https://sign-in-dev.hmpps.service.justice.gov.uk/auth/issuer"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"mappings": [
{
"request": {
"method": "GET",
"urlPath": "/cas3-api/events/referral-submitted/1234"
},
"response": {
"headers": {
"Content-Type": "application/json"
},
"status": 200,
"bodyFileName": "cas3-referral-submitted.json"
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"request": {
"method": "POST",
"urlPath": "/auth/oauth/token"
},
"response": {
"headers": {
"Content-Type": "application/json"
},
"status": 200,
"bodyFileName": "hmpps-auth-token-body.json"
}
}
Original file line number Diff line number Diff line change
@@ -1,52 +1,55 @@
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.MethodOrderer
import org.junit.jupiter.api.Test
import org.mockito.Mockito.atLeastOnce
import org.mockito.kotlin.verify
import org.junit.jupiter.api.TestMethodOrder
import org.mockito.Mockito
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT
import org.springframework.boot.test.mock.mockito.MockBean
import uk.gov.justice.digital.hmpps.data.generator.MessageGenerator
import uk.gov.justice.digital.hmpps.integrations.delius.entity.ContactRepository
import uk.gov.justice.digital.hmpps.message.Notification
import uk.gov.justice.digital.hmpps.messaging.HmppsChannelManager
import uk.gov.justice.digital.hmpps.telemetry.TelemetryService
import uk.gov.justice.digital.hmpps.telemetry.notificationReceived
import java.util.concurrent.TimeoutException

@SpringBootTest
@AutoConfigureMockMvc
@SpringBootTest(webEnvironment = RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation::class)
internal class CASIntegrationTest {
@Value("\${messaging.consumer.queue}")
lateinit var queueName: String

@Autowired lateinit var channelManager: HmppsChannelManager
@Autowired
lateinit var channelManager: HmppsChannelManager

@MockBean lateinit var telemetryService: TelemetryService
@Autowired
lateinit var wireMockServer: WireMockServer

@Autowired lateinit var contactRepository: ContactRepository
@Autowired
lateinit var contactRepository: ContactRepository

@MockBean
lateinit var telemetryService: TelemetryService

@Test
fun `message is processed correctly`() {
// Given a message
val message = prepMessage(MessageGenerator.REFERRAL_SUBMITTED).message
val notification = Notification(message = message)
// Given an application-submitted event
val event = prepEvent("referral-submitted", wireMockServer.port())

// When it is received
try {
channelManager.getChannel(queueName).publishAndWait(notification)
} catch (_: TimeoutException) {
// Note: Remove this try/catch when the MessageListener logic has been implemented
}
channelManager.getChannel(queueName).publishAndWait(event)

// Then it is logged to telemetry
verify(telemetryService, atLeastOnce()).notificationReceived(notification)

// verify that the contact has been created:
Mockito.verify(telemetryService).notificationReceived(event)

val contact = contactRepository.getByExternalReference(message.additionalInformation["applicationId"] as String)
val contact =
contactRepository.getByExternalReference(event.message.additionalInformation["applicationId"] as String)

MatcherAssert.assertThat(contact!!.type.code, Matchers.equalTo("EARS"))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package uk.gov.justice.digital.hmpps.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.approvedpremesis.ApprovedPremisesApiClient

@Configuration
@EnableFeignClients(clients = [ApprovedPremisesApiClient::class])
class FeignOAuth2Config(
authorizedClientManager: OAuth2AuthorizedClientManager
) : FeignConfig(authorizedClientManager) {
override fun registrationId() = "cas3-and-delius"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package uk.gov.justice.digital.hmpps.integrations.approvedpremesis

import org.springframework.cloud.openfeign.FeignClient
import org.springframework.web.bind.annotation.GetMapping
import uk.gov.justice.digital.hmpps.config.FeignOAuth2Config
import java.net.URI

@FeignClient(
name = "approved-premises-api",
url = "https://dummy-url/to/be/overridden",
configuration = [FeignOAuth2Config::class]
)
interface ApprovedPremisesApiClient {
@GetMapping fun getApplicationSubmittedDetails(uri: URI): EventDetails<ApplicationSubmitted>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package uk.gov.justice.digital.hmpps.integrations.approvedpremesis

import java.time.ZonedDateTime

data class EventDetails<T>(
val id: String,
val timestamp: ZonedDateTime,
val eventType: String,
val eventDetails: T
)

data class ApplicationSubmitted(
val applicationId: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import org.springframework.stereotype.Service
import uk.gov.justice.digital.hmpps.audit.service.AuditableService
import uk.gov.justice.digital.hmpps.audit.service.AuditedInteractionService
import uk.gov.justice.digital.hmpps.exception.NotFoundException
import uk.gov.justice.digital.hmpps.integrations.approvedpremesis.ApprovedPremisesApiClient
import uk.gov.justice.digital.hmpps.integrations.delius.audit.BusinessInteractionCode
import uk.gov.justice.digital.hmpps.integrations.delius.entity.Contact
import uk.gov.justice.digital.hmpps.integrations.delius.entity.ContactRepository
Expand All @@ -12,8 +13,8 @@ import uk.gov.justice.digital.hmpps.integrations.delius.entity.ContactTypeReposi
import uk.gov.justice.digital.hmpps.integrations.delius.entity.PersonManagerRepository
import uk.gov.justice.digital.hmpps.integrations.delius.entity.PersonRepository
import uk.gov.justice.digital.hmpps.integrations.delius.entity.getByCrn
import uk.gov.justice.digital.hmpps.integrations.delius.entity.getByNoms
import uk.gov.justice.digital.hmpps.message.HmppsDomainEvent
import uk.gov.justice.digital.hmpps.messaging.url
import uk.gov.justice.digital.hmpps.telemetry.TelemetryService
import java.time.ZonedDateTime

Expand All @@ -24,29 +25,18 @@ class ContactService(
private val personManagerRepository: PersonManagerRepository,
private val contactRepository: ContactRepository,
private val contactTypeRepository: ContactTypeRepository,
private val telemetryService: TelemetryService
private val telemetryService: TelemetryService,
private val approvedPremisesApiClient: ApprovedPremisesApiClient
) : AuditableService(auditedInteractionService) {

fun createReferralSubmitted(event: HmppsDomainEvent) = audit(BusinessInteractionCode.UPDATE_CONTACT) {
val details = approvedPremisesApiClient.getApplicationSubmittedDetails(event.url()).eventDetails
val crn = event.personReference.findCrn()
val noms = event.personReference.findNomsNumber()
val externalReference = event.additionalInformation["applicationId"] as String
val externalReference = details.applicationId
val person = personRepository.getByCrn(crn!!)

val person = when {
crn != null -> {
personRepository.getByCrn(crn)
}

noms != null -> {
personRepository.getByNoms(noms)
}

else -> {
throw IllegalArgumentException("crn or noms number should be supplied in the message")
}
}
if (contactRepository.getByExternalReference(externalReference) != null) {
telemetryService.trackEvent("Duplicate ApplicationSubmitted event received for crn/noms $crn/$noms")
telemetryService.trackEvent("Duplicate ApplicationSubmitted event received for crn $crn")
} else {
contactRepository.save(newContact(event.occurredAt, person.id, REFERRAL_SUBMITTED, externalReference))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import uk.gov.justice.digital.hmpps.message.HmppsDomainEvent
import uk.gov.justice.digital.hmpps.message.Notification
import uk.gov.justice.digital.hmpps.telemetry.TelemetryService
import uk.gov.justice.digital.hmpps.telemetry.notificationReceived
import java.net.URI

@Component
class Handler(
Expand All @@ -22,17 +23,16 @@ class Handler(
contactService.createReferralSubmitted(event)
telemetryService.trackEvent("ApplicationSubmitted", event.telemetryProperties())
}

else -> throw IllegalArgumentException("Unexpected event type ${event.eventType}")
}
}

fun HmppsDomainEvent.telemetryProperties() = mapOf(
"occurredAt" to occurredAt.toString(),
"crn" to crn(),
"noms" to noms()

"crn" to crn()
)

fun HmppsDomainEvent.crn(): String = personReference.findCrn() ?: "N/A"
fun HmppsDomainEvent.noms(): String = personReference.findNomsNumber() ?: "N/A"
}
fun HmppsDomainEvent.crn(): String = personReference.findCrn() ?: throw IllegalArgumentException("Missing CRN")

fun HmppsDomainEvent.url(): URI = URI.create(detailUrl ?: throw IllegalArgumentException("Missing detail url"))
30 changes: 30 additions & 0 deletions projects/cas3-and-delius/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,25 @@ spring:
global_temporary:
create_tables: false
drop_tables: false
security.oauth2.client:
registration:
cas3-and-delius:
provider: hmpps-auth
authorization-grant-type: client_credentials
client-id: ${oauth2.client-id}
client-secret: ${oauth2.client-secret}
provider:
hmpps-auth:
token-uri: http://localhost:${wiremock.port}/auth/oauth/token
cloud.openfeign.client.config:
default:
logger-level: full
connect-timeout: 5000
read-timeout: 5000
default-request-headers:
Accept: application/json
Content-Type: application/json
springdoc.default-produces-media-type: application/json

delius.db.username: Cas3AndDelius # Should match value in [deploy/database/access.yml].

Expand All @@ -31,11 +50,22 @@ spring.config.activate.on-profile: [ "dev", "integration-test" ]
spring:
datasource.url: jdbc:h2:file:./dev;MODE=Oracle;DEFAULT_NULL_ORDERING=HIGH;AUTO_SERVER=true;AUTO_SERVER_PORT=9092
jpa.hibernate.ddl-auto: create-drop
security.oauth2.resourceserver.jwt.public-key-location: classpath:local-public-key.pub

seed.database: true
wiremock.enabled: true
context.initializer.classes: uk.gov.justice.digital.hmpps.wiremock.WireMockInitialiser

messaging.consumer.queue: message-queue

integrations:
cas3-api:
url: http://localhost:${wiremock.port}/cas3

oauth2:
client-id: $SERVICE_NAME
client-secret: $SERVICE_NAME

logging.level:
uk.gov.justice.digital.hmpps: DEBUG
org.hibernate.tool.schema: ERROR
Expand Down

0 comments on commit a6e696c

Please sign in to comment.