Skip to content

Commit

Permalink
PI-1585 Added update message processing (#2452)
Browse files Browse the repository at this point in the history
  • Loading branch information
stevomcallister authored Oct 26, 2023
1 parent 856d0d0 commit ceb6d26
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"eventType": "accommodation.cas3.person.departed",
"version": 1,
"description": "A cas3 person departed",
"detailUrl": "http://localhost:{wiremock.port}/cas3-api/events/person-departed/12345",
"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,17 @@
{
"id": "364145f9-0af8-488e-9901-b4c46cd9ba37",
"timestamp": "2022-12-30T14:53:44",
"eventType": "accommodation.cas3.person-departed ",
"eventDetails": {
"applicationId": "68df9f6c-3fcb-4ec6-8fcf-96551cd9b080",
"applicationUrl": "https://approved-premises-dev.hmpps.service.justice.gov.uk/booking/68df9f6c-3fcb-4ec6-8fcf-96551cd9b080",
"personReference": {
"crn": "A000001",
"noms": "A0001AA"
},
"bookingId": "14c80733-4b6d-4f35-b724-66955aac320e",
"bookingUrl": "https://approved-premises-dev.hmpps.service.justice.gov.uk/someURLtoTheBooking",
"departedAt": "2022-11-30T12:00:00",
"notes": "Person departed."
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,19 @@
"status": 200,
"bodyFileName": "cas3-person-departed.json"
}
},
{
"request": {
"method": "GET",
"urlPath": "/cas3-api/events/person-departed/12345"
},
"response": {
"headers": {
"Content-Type": "application/json"
},
"status": 200,
"bodyFileName": "cas3-person-departed-update.json"
}
}
]
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package uk.gov.justice.digital.hmpps

import com.fasterxml.jackson.databind.ObjectMapper
import com.github.tomakehurst.wiremock.WireMockServer
import org.hamcrest.MatcherAssert
import org.hamcrest.Matchers
Expand All @@ -13,8 +14,17 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock
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 org.springframework.test.web.servlet.MockMvc
import uk.gov.justice.digital.hmpps.integrations.approvedpremesis.ApplicationSubmitted
import uk.gov.justice.digital.hmpps.integrations.approvedpremesis.BookingCancelled
import uk.gov.justice.digital.hmpps.integrations.approvedpremesis.BookingConfirmed
import uk.gov.justice.digital.hmpps.integrations.approvedpremesis.BookingProvisional
import uk.gov.justice.digital.hmpps.integrations.approvedpremesis.EventDetails
import uk.gov.justice.digital.hmpps.integrations.approvedpremesis.PersonArrived
import uk.gov.justice.digital.hmpps.integrations.approvedpremesis.PersonDeparted
import uk.gov.justice.digital.hmpps.integrations.delius.entity.ContactRepository
import uk.gov.justice.digital.hmpps.messaging.HmppsChannelManager
import uk.gov.justice.digital.hmpps.resourceloader.ResourceLoader
import uk.gov.justice.digital.hmpps.telemetry.TelemetryService
import uk.gov.justice.digital.hmpps.telemetry.notificationReceived

Expand All @@ -37,99 +47,128 @@ internal class CASIntegrationTest {
@MockBean
lateinit var telemetryService: TelemetryService

@Autowired
lateinit var mockMvc: MockMvc

@Autowired
lateinit var objectMapper: ObjectMapper

@Test
fun `referral submitted message is processed correctly`() {
val event = prepEvent("referral-submitted", wireMockServer.port())
val eventName = "referral-submitted"
val event = prepEvent(eventName, wireMockServer.port())

// When it is received
channelManager.getChannel(queueName).publishAndWait(event)

// Then it is logged to telemetry
Mockito.verify(telemetryService).notificationReceived(event)

val contact =
contactRepository.getByExternalReference("urn:hmpps:cas3:application-submitted:${event.message.additionalInformation["applicationId"] as String}")
val eventDetails = ResourceLoader.file<EventDetails<ApplicationSubmitted>>("cas3-$eventName")
val contact = contactRepository.getByExternalReference(eventDetails.eventDetails.urn)

MatcherAssert.assertThat(contact!!.type.code, Matchers.equalTo("EARS"))
}

@Test
fun `booking cancelled message is processed correctly`() {
val event = prepEvent("booking-cancelled", wireMockServer.port())
val eventName = "booking-cancelled"
val event = prepEvent(eventName, wireMockServer.port())

// When it is received
channelManager.getChannel(queueName).publishAndWait(event)

// Then it is logged to telemetry
Mockito.verify(telemetryService).notificationReceived(event)

val contact =
contactRepository.getByExternalReference("urn:hmpps:cas3:booking-cancelled:14c80733-4b6d-4f35-b724-66955aac320c")
val eventDetails = ResourceLoader.file<EventDetails<BookingCancelled>>("cas3-$eventName")
val contact = contactRepository.getByExternalReference(eventDetails.eventDetails.urn)

MatcherAssert.assertThat(contact!!.type.code, Matchers.equalTo("EACA"))
}

@Test
fun `booking confirmed message is processed correctly`() {
val event = prepEvent("booking-confirmed", wireMockServer.port())
val eventName = "booking-confirmed"
val event = prepEvent(eventName, wireMockServer.port())

// When it is received
channelManager.getChannel(queueName).publishAndWait(event)

// Then it is logged to telemetry
Mockito.verify(telemetryService).notificationReceived(event)

val contact =
contactRepository.getByExternalReference("urn:hmpps:cas3:booking-confirmed:14c80733-4b6d-4f35-b724-66955aac320d")
val eventDetails = ResourceLoader.file<EventDetails<BookingConfirmed>>("cas3-$eventName")
val contact = contactRepository.getByExternalReference(eventDetails.eventDetails.urn)

MatcherAssert.assertThat(contact!!.type.code, Matchers.equalTo("EACO"))
}

@Test
fun `booking provisionally made message is processed correctly`() {
val event = prepEvent("booking-provisionally-made", wireMockServer.port())
val eventName = "booking-provisionally-made"
val event = prepEvent(eventName, wireMockServer.port())

// When it is received
channelManager.getChannel(queueName).publishAndWait(event)

// Then it is logged to telemetry
Mockito.verify(telemetryService).notificationReceived(event)

val contact =
contactRepository.getByExternalReference("urn:hmpps:cas3:booking-provisionally-made:14c80733-4b6d-4f35-b724-66955aac320e")
val eventDetails = ResourceLoader.file<EventDetails<BookingProvisional>>("cas3-$eventName")
val contact = contactRepository.getByExternalReference(eventDetails.eventDetails.urn)

MatcherAssert.assertThat(contact!!.type.code, Matchers.equalTo("EABP"))
}

@Test
fun `person arrived message is processed correctly`() {
val event = prepEvent("person-arrived", wireMockServer.port())
val eventName = "person-arrived"
val event = prepEvent(eventName, wireMockServer.port())

// When it is received
channelManager.getChannel(queueName).publishAndWait(event)

// Then it is logged to telemetry
Mockito.verify(telemetryService).notificationReceived(event)

val contact =
contactRepository.getByExternalReference("urn:hmpps:cas3:person-arrived:14c80733-4b6d-4f35-b724-66955aac320e")
val eventDetails = ResourceLoader.file<EventDetails<PersonArrived>>("cas3-$eventName")
val contact = contactRepository.getByExternalReference(eventDetails.eventDetails.urn)

MatcherAssert.assertThat(contact!!.type.code, Matchers.equalTo("EAAR"))
}

@Test
fun `person departed message is processed correctly`() {
val event = prepEvent("person-departed", wireMockServer.port())
val eventName = "person-departed"
val event = prepEvent(eventName, wireMockServer.port())

// When it is received
channelManager.getChannel(queueName).publishAndWait(event)

// Then it is logged to telemetry
Mockito.verify(telemetryService).notificationReceived(event)

val contact =
contactRepository.getByExternalReference("urn:hmpps:cas3:person-departed:14c80733-4b6d-4f35-b724-66955aac320e")
val eventDetails = ResourceLoader.file<EventDetails<PersonDeparted>>("cas3-$eventName")
val contact = contactRepository.getByExternalReference(eventDetails.eventDetails.urn)

MatcherAssert.assertThat(contact!!.type.code, Matchers.equalTo("EADP"))
}

@Test
fun `person departed message update is processed correctly`() {
val eventName = "person-departed-update"
val event = prepEvent(eventName, wireMockServer.port())

// When it is received
channelManager.getChannel(queueName).publishAndWait(event)

// Then it is logged to telemetry
Mockito.verify(telemetryService).notificationReceived(event)
val oldEventDetails = ResourceLoader.file<EventDetails<PersonDeparted>>("cas3-person-departed")
val eventDetails = ResourceLoader.file<EventDetails<PersonDeparted>>("cas3-$eventName")
val contact = contactRepository.getByExternalReference(eventDetails.eventDetails.urn)

MatcherAssert.assertThat(contact!!.type.code, Matchers.equalTo("EADP"))
MatcherAssert.assertThat(contact.notes, Matchers.equalTo(eventDetails.eventDetails.noteText))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ 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.telemetry.TelemetryService
import java.time.ZonedDateTime

@Service
Expand All @@ -21,7 +22,8 @@ class ContactService(
private val personRepository: PersonRepository,
private val personManagerRepository: PersonManagerRepository,
private val contactRepository: ContactRepository,
private val contactTypeRepository: ContactTypeRepository
private val contactTypeRepository: ContactTypeRepository,
private val telemetryService: TelemetryService
) : AuditableService(auditedInteractionService) {

fun <T : Cas3Event> createContact(
Expand All @@ -30,15 +32,30 @@ class ContactService(
) = audit(BusinessInteractionCode.UPDATE_CONTACT) {
val event = getEvent()
val person = personRepository.getByCrn(crn)
contactRepository.save(
newContact(
event.timestamp,
person.id,
event.eventDetails.contactTypeCode,
event.eventDetails.urn,
event.eventDetails.noteText
val existing = contactRepository.getByExternalReference(event.eventDetails.urn)
if (existing != null) {
if (existing.startTime < event.timestamp) {
existing.notes = event.eventDetails.noteText
existing.date = event.timestamp.toLocalDate()
existing.startTime = event.timestamp
contactRepository.save(existing)
} else {
telemetryService.trackEvent(
"Ignoring out of sequence older message.",
mapOf("crn" to crn, "urn" to event.eventDetails.urn)
)
}
} else {
contactRepository.save(
newContact(
event.timestamp,
person.id,
event.eventDetails.contactTypeCode,
event.eventDetails.urn,
event.eventDetails.noteText
)
)
)
}
}

fun newContact(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ class Contact(
val type: ContactType,

@Lob
val notes: String,
var notes: String,

@Column(name = "contact_date")
val date: LocalDate,
var date: LocalDate,

@Column(name = "contact_start_time")
val startTime: ZonedDateTime,
var startTime: ZonedDateTime,

@Column(updatable = false)
val staffId: Long,
Expand Down

0 comments on commit ceb6d26

Please sign in to comment.