Skip to content

Commit 886bb80

Browse files
chiaramapellimtBingjie Liu
and
Bingjie Liu
authored
HIA-697 - Thin Slice for Prison Office Manager (#400)
* HIA-697 - Gateway created + new upstream API * HIA-697 Added Service for Prison Officer Manager API * HIA-697 - Added additional models required * Renamed according to acronym * Committed wrong file, controller-side of things not ready yet * HIA-697 - NDelius retrieve community-manager related data * HIA-697: Adding the service related to community manager * HIA-697 - Adding controller and initial test * Missed one import * HIA-697 - Added unit test for controller. * HIA-697 - WIP Smoke test * WIO - Adding actual data in smoke * Smoke test ok * Delete localstack/cache directory * update openapi.yml * update CaseSentence as per update stream open api * Undo changes * update open api parameter name * Temporary fix for epf smoke test --------- Co-authored-by: Bingjie Liu <bingjie.liu@digital.justice.gov.uk>
1 parent c3ba30e commit 886bb80

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1020
-2
lines changed

Dockerfile.setup-manage-pom-case-api

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM node:current-alpine3.17
2+
3+
RUN apk update && apk add bash curl
4+
5+
RUN curl https://allocation-manager-staging.apps.live.cloud-platform.service.justice.gov.uk/v3/api-docs.json > manage-pom-case-api.json && \
6+
npm install -g @stoplight/prism-cli
7+
8+
CMD prism mock -p 4010 -h 0.0.0.0 /manage-pom-case-api.json

docker-compose.yml

+12
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ services:
1717
condition: service_healthy
1818
probation-integration-epf-api:
1919
condition: service_healthy
20+
manage-pom-case-api:
21+
condition: service_healthy
2022
environment:
2123
- SERVER_PORT=8080
2224
- SPRING_PROFILES_ACTIVE=local-docker
@@ -124,6 +126,16 @@ services:
124126
ports:
125127
- '4080:4010'
126128

129+
manage-pom-case-api:
130+
build:
131+
context: .
132+
dockerfile: Dockerfile.setup-manage-pom-case-api
133+
container_name: manage-pom-case-api
134+
healthcheck:
135+
test: 'wget --header="Authorization: Bearer abc" http://127.0.0.1:4010/api/allocation/X1234YZ/primary_pom -O /dev/null'
136+
ports:
137+
- '4090:4010'
138+
127139
local-stack-aws:
128140
image: localstack/localstack:3.0
129141
container_name: local-stack-aws

openapi.yml

+95-1
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,40 @@ paths:
722722
NoQueryParametersBadRequestError:
723723
$ref: "#/components/examples/InternalServerError"
724724

725+
/v1/persons/{HmppsId}/person-responsible-officer:
726+
get:
727+
summary: Returns the person responsible officer associated with a person.
728+
parameters:
729+
- $ref: "#/components/parameters/HmppsId"
730+
responses:
731+
"200":
732+
description: Successfully found the person responsible officer for a person with the provided HMPPS ID.
733+
content:
734+
application/json:
735+
schema:
736+
type: object
737+
properties:
738+
data:
739+
$ref: "#/components/schemas/PersonResponsibleOfficer"
740+
"404":
741+
description: Failed to find licenses for a person with the provided HMPPS ID.
742+
content:
743+
application/json:
744+
schema:
745+
$ref: "#/components/schemas/Error"
746+
examples:
747+
PersonNotFoundError:
748+
$ref: "#/components/examples/PersonNotFoundError"
749+
"500":
750+
description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get.
751+
content:
752+
application/json:
753+
schema:
754+
$ref: "#/components/schemas/Error"
755+
examples:
756+
NoQueryParametersBadRequestError:
757+
$ref: "#/components/examples/InternalServerError"
758+
725759
/v1/persons/{HmppsId}/licences/conditions:
726760
get:
727761
summary: Returns license conditions associated with a person.
@@ -1269,6 +1303,19 @@ components:
12691303
releaseDate:
12701304
type: string
12711305
format: date
1306+
CommunityOffenderManager:
1307+
type: object
1308+
properties:
1309+
name:
1310+
$ref: "#/components/schemas/PersonResponsibleOfficerName"
1311+
email:
1312+
type: string
1313+
nullable: true
1314+
telephoneNumber:
1315+
type: string
1316+
nullable: true
1317+
team:
1318+
$ref: "#/components/schemas/PersonResponsibleOfficerTeam"
12721319
ContactDetails:
12731320
properties:
12741321
phoneNumbers:
@@ -1755,6 +1802,30 @@ components:
17551802
description: Currently a hmppsId is a CRN identifier however this will change in the future to be a new unique Hmpps identifier
17561803
contactDetails:
17571804
$ref: "#/components/schemas/ContactDetails"
1805+
PersonResponsibleOfficerName:
1806+
type: object
1807+
properties:
1808+
forename:
1809+
type: string
1810+
nullable: true
1811+
surname:
1812+
type: string
1813+
nullable: true
1814+
PersonResponsibleOfficerTeam:
1815+
type: object
1816+
properties:
1817+
code:
1818+
type: string
1819+
nullable: true
1820+
description:
1821+
type: string
1822+
nullable: true
1823+
email:
1824+
type: string
1825+
nullable: true
1826+
telephoneNumber:
1827+
type: string
1828+
nullable: true
17581829
PhoneNumbers:
17591830
type: array
17601831
items:
@@ -1768,6 +1839,13 @@ components:
17681839
type: string
17691840
example: "TELEPHONE"
17701841
description: "The type of number"
1842+
PersonResponsibleOfficer:
1843+
type: object
1844+
properties:
1845+
prisonOffenderOfficer:
1846+
$ref: "#/components/schemas/PrisonOffenderOfficer"
1847+
communityOffenderManager:
1848+
$ref: "#/components/schemas/CommunityOffenderManager"
17711849
PersonLicencesData:
17721850
type: object
17731851
properties:
@@ -1839,7 +1917,23 @@ components:
18391917
minItems: 0
18401918
items:
18411919
$ref: "#/components/schemas/ReasonableAdjustment"
1842-
1920+
Prison:
1921+
type: object
1922+
properties:
1923+
code:
1924+
type: string
1925+
nullable: true
1926+
PrisonOffenderOfficer:
1927+
type: object
1928+
properties:
1929+
forename:
1930+
type: string
1931+
nullable: true
1932+
surname:
1933+
type: string
1934+
nullable: true
1935+
prison:
1936+
$ref: "#/components/schemas/Prison"
18431937

18441938
Punishment:
18451939
type: object
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person
2+
3+
import org.springframework.beans.factory.annotation.Autowired
4+
import org.springframework.web.bind.annotation.GetMapping
5+
import org.springframework.web.bind.annotation.PathVariable
6+
import org.springframework.web.bind.annotation.RequestMapping
7+
import org.springframework.web.bind.annotation.RestController
8+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException
9+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters
10+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PersonResponsibleOfficer
11+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError
12+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCommunityOffenderManagerForPersonService
13+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetPrisonOffenderManagerForPersonService
14+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService
15+
16+
@RestController
17+
@RequestMapping("/v1/persons")
18+
class PersonResponsibleOfficerController(
19+
@Autowired val auditService: AuditService,
20+
@Autowired val getPrisonOffenderManagerForPersonService: GetPrisonOffenderManagerForPersonService,
21+
@Autowired val getCommunityOffenderManagerForPersonService: GetCommunityOffenderManagerForPersonService,
22+
) {
23+
@GetMapping("{encodedHmppsId}/person-responsible-officer")
24+
fun getPersonResponsibleOfficer(
25+
@PathVariable encodedHmppsId: String,
26+
): Map<String, PersonResponsibleOfficer> {
27+
val hmppsId = encodedHmppsId.decodeUrlCharacters()
28+
val prisonOffenderManager = getPrisonOffenderManagerForPersonService.execute(hmppsId)
29+
val communityOffenderManager = getCommunityOffenderManagerForPersonService.execute(hmppsId)
30+
31+
if (prisonOffenderManager.hasError(UpstreamApiError.Type.ENTITY_NOT_FOUND)) {
32+
throw EntityNotFoundException("Could not find prison offender manager related to id: $hmppsId")
33+
}
34+
35+
if (communityOffenderManager.hasError(UpstreamApiError.Type.ENTITY_NOT_FOUND)) {
36+
throw EntityNotFoundException("Could not find community offender manager related to id: $hmppsId")
37+
}
38+
39+
val mergedData =
40+
PersonResponsibleOfficer(
41+
prisonOffenderManager = prisonOffenderManager.data,
42+
communityOffenderManager = communityOffenderManager.data,
43+
)
44+
45+
auditService.createEvent("GET_PERSON_RESPONSIBLE_OFFICER", mapOf("hmppsId" to hmppsId))
46+
return mapOf("data" to mergedData)
47+
}
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways
2+
3+
import org.springframework.beans.factory.annotation.Autowired
4+
import org.springframework.beans.factory.annotation.Value
5+
import org.springframework.http.HttpMethod
6+
import org.springframework.stereotype.Component
7+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.WebClientWrapper
8+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PrisonOffenderManager
9+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response
10+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi
11+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.managePOMCase.AllocationPrimaryPOM
12+
13+
@Component
14+
class ManagePOMCaseGateway(
15+
@Value("\${services.manage-pom-case-api.base-url}") baseUrl: String,
16+
) {
17+
private val webClient = WebClientWrapper(baseUrl)
18+
19+
@Autowired
20+
lateinit var hmppsAuthGateway: HmppsAuthGateway
21+
22+
fun getPrimaryPOMForNomisNumber(id: String): Response<PrisonOffenderManager> {
23+
val result =
24+
webClient.request<AllocationPrimaryPOM>(
25+
HttpMethod.GET,
26+
"/api/allocation/$id/primary_pom",
27+
authenticationHeader(),
28+
UpstreamApi.MANAGE_POM_CASE,
29+
)
30+
31+
return when (result) {
32+
is WebClientWrapper.WebClientWrapperResponse.Success -> {
33+
Response(data = result.data.toPrisonOffenderManager())
34+
}
35+
36+
is WebClientWrapper.WebClientWrapperResponse.Error -> {
37+
Response(
38+
data = PrisonOffenderManager(),
39+
errors = result.errors,
40+
)
41+
}
42+
}
43+
}
44+
45+
private fun authenticationHeader(): Map<String, String> {
46+
val token = hmppsAuthGateway.getClientToken("ManagePOMCase")
47+
48+
return mapOf(
49+
"Authorization" to "Bearer $token",
50+
)
51+
}
52+
}

src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/gateways/NDeliusGateway.kt

+23
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import org.springframework.http.HttpMethod
66
import org.springframework.stereotype.Component
77
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.WebClientWrapper
88
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.WebClientWrapper.WebClientWrapperResponse
9+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CommunityOffenderManager
910
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.MappaDetail
1011
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Offence
1112
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response
@@ -91,6 +92,28 @@ class NDeliusGateway(
9192
}
9293
}
9394

95+
fun getCommunityOffenderManagerForPerson(id: String): Response<CommunityOffenderManager> {
96+
val result =
97+
webClient.request<NDeliusSupervisions>(
98+
HttpMethod.GET,
99+
"/case/$id/supervisions",
100+
authenticationHeader(),
101+
UpstreamApi.NDELIUS,
102+
)
103+
return when (result) {
104+
is WebClientWrapperResponse.Success -> {
105+
Response(data = result.data.communityManager.toCommunityOffenderManager())
106+
}
107+
108+
is WebClientWrapperResponse.Error -> {
109+
Response(
110+
data = CommunityOffenderManager(),
111+
errors = result.errors,
112+
)
113+
}
114+
}
115+
}
116+
94117
private fun authenticationHeader(): Map<String, String> {
95118
val token = hmppsAuthGateway.getClientToken("nDelius")
96119

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps
2+
3+
data class CommunityOffenderManager(
4+
val name: PersonResponsibleOfficerName = PersonResponsibleOfficerName(),
5+
val email: String? = null,
6+
val telephoneNumber: String? = null,
7+
val team: PersonResponsibleOfficerTeam = PersonResponsibleOfficerTeam(),
8+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps
2+
3+
data class PersonResponsibleOfficer(
4+
val prisonOffenderManager: PrisonOffenderManager = PrisonOffenderManager(),
5+
val communityOffenderManager: CommunityOffenderManager = CommunityOffenderManager(),
6+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps
2+
3+
data class PersonResponsibleOfficerName(
4+
val forename: String? = null,
5+
val surname: String? = null,
6+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps
2+
3+
data class PersonResponsibleOfficerTeam(
4+
val code: String? = null,
5+
val description: String? = null,
6+
val email: String? = null,
7+
val telephoneNumber: String? = null,
8+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps
2+
3+
data class Prison(
4+
val code: String? = null,
5+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps
2+
3+
data class PrisonOffenderManager(
4+
val forename: String? = null,
5+
val surname: String? = null,
6+
val prison: Prison = Prison(),
7+
)

src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/UpstreamApi.kt

+1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ enum class UpstreamApi {
99
ADJUDICATIONS,
1010
CVL,
1111
CASE_NOTES,
12+
MANAGE_POM_CASE,
1213
TEST,
1314
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.managePOMCase
2+
3+
data class AllocationManager(
4+
val code: Int? = null,
5+
val forename: String? = null,
6+
val surname: String? = null,
7+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.managePOMCase
2+
3+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Prison
4+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PrisonOffenderManager
5+
6+
data class AllocationPrimaryPOM(
7+
val manager: AllocationManager = AllocationManager(),
8+
val prison: AllocationPrison = AllocationPrison(),
9+
) {
10+
fun toPrisonOffenderManager(): PrisonOffenderManager =
11+
PrisonOffenderManager(
12+
forename = this.manager.forename,
13+
surname = this.manager.surname,
14+
prison =
15+
Prison(
16+
code = this.prison.code,
17+
),
18+
)
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.managePOMCase
2+
3+
data class AllocationPrison(
4+
val code: String? = null,
5+
)

0 commit comments

Comments
 (0)