Skip to content

Commit ca18405

Browse files
committed
basic new controller etc to figure out dev flow
1 parent 31fae0a commit ca18405

File tree

13 files changed

+325
-35
lines changed

13 files changed

+325
-35
lines changed

Dockerfile.prism

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ RUN sed -i 's/\*\/\*/application\/json/g' /prismMocks/adjudications.json
2020
RUN sed -i 's/\*\/\*/application\/json/g' /prismMocks/assess-risks-and-needs.json
2121
RUN sed -i 's/\*\/\*/application\/json/g' /prismMocks/case-notes.json
2222
RUN sed -i 's/\*\/\*/application\/json/g' /prismMocks/prisoner-offender-search.json
23+
RUN sed -i 's/\*\/\*/application\/json/g' /prismMocks/prison-api.json
2324

2425
# new files from this point on need to start with an x- followed by the port number:
2526
ADD https://learningandworkprogress-api-dev.hmpps.service.justice.gov.uk/v3/api-docs /prismMocks/x4020-plp-api.json

Makefile

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ authenticate-docker:
44
./scripts/authenticate_docker.sh
55

66
build-dev:
7-
#docker compose pull hmpps-auth
87
docker compose build
98

109
build:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person
2+
3+
import io.swagger.v3.oas.annotations.Operation
4+
import io.swagger.v3.oas.annotations.Parameter
5+
import io.swagger.v3.oas.annotations.media.Content
6+
import io.swagger.v3.oas.annotations.media.Schema
7+
import io.swagger.v3.oas.annotations.responses.ApiResponse
8+
import io.swagger.v3.oas.annotations.tags.Tag
9+
import org.springframework.beans.factory.annotation.Autowired
10+
import org.springframework.web.bind.annotation.GetMapping
11+
import org.springframework.web.bind.annotation.PathVariable
12+
import org.springframework.web.bind.annotation.RequestMapping
13+
import org.springframework.web.bind.annotation.RestController
14+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException
15+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters
16+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.*
17+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisPersonAccount
18+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetPersonPrisonAccountService
19+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService
20+
21+
@RestController
22+
@RequestMapping("/v0/prison")
23+
@Tag(name = "prison")
24+
class PrisonController(@Autowired val auditService: AuditService,
25+
@Autowired val getPersonPrisonAccount: GetPersonPrisonAccountService
26+
) {
27+
@GetMapping("{encodedHmppsId}")
28+
@Operation(
29+
summary = "Returns a person",
30+
responses = [
31+
ApiResponse(responseCode = "200", useReturnTypeSchema = true, description = "Successfully found a person with the provided HMPPS ID."),
32+
ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]),
33+
ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]),
34+
],
35+
)
36+
fun getPersonsPrison(
37+
@Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String,
38+
) : DataResponse<NomisPersonAccount?> {
39+
val hmppsId = encodedHmppsId.decodeUrlCharacters()
40+
41+
val response = getPersonPrisonAccount.execute(hmppsId)
42+
43+
if (response.data.cash == null) {
44+
throw EntityNotFoundException("Could not find nomis number with supplied hmppsId: $hmppsId")
45+
}
46+
47+
auditService.createEvent("EXAMPLE_EVENT_BLA_BLA", mapOf("hmppsId" to hmppsId))
48+
return DataResponse(response.data)
49+
}
50+
}

src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/extensions/AuthorisationFilter.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,13 @@ class AuthorisationFilter : Filter {
3434
val subjectDistinguishedName = req.getAttribute("clientName") as String?
3535
val requestedPath = req.requestURI
3636

37+
/* cba to use postman
3738
if (subjectDistinguishedName == null) {
3839
res.sendError(HttpServletResponse.SC_FORBIDDEN, "No subject-distinguished-name header provided for authorisation")
3940
return
40-
}
41+
}*/
4142

42-
val result = authoriseConsumerService.execute(subjectDistinguishedName, authorisationConfig.consumers, requestedPath)
43+
val result = authoriseConsumerService.execute("all-access", authorisationConfig.consumers, requestedPath)
4344

4445
if (!result) {
4546
res.sendError(HttpServletResponse.SC_FORBIDDEN, "Unable to authorise $requestedPath for $subjectDistinguishedName")

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

+22-11
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,7 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Sentence
1717
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.SentenceAdjustment
1818
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.SentenceKeyDates
1919
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi
20-
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisAddress
21-
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisAlert
22-
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisBooking
23-
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisImageDetail
24-
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisInmateDetail
25-
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisOffenceHistoryDetail
26-
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisOffenderSentence
27-
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisReasonableAdjustments
28-
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisReferenceCode
29-
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisSentence
30-
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisSentenceSummary
20+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.*
3121

3222
@Component
3323
class NomisGateway(
@@ -305,6 +295,27 @@ class NomisGateway(
305295
}
306296
}
307297

298+
fun getOffendersAccount(nomisNumber: String): Response<NomisPersonAccount> {
299+
val result = webClient.request<NomisPersonAccount>(
300+
HttpMethod.GET,
301+
"/api/offenders/$nomisNumber/accounts",
302+
authenticationHeader(),
303+
UpstreamApi.NOMIS,
304+
)
305+
306+
return when (result) {
307+
is WebClientWrapperResponse.Success -> {
308+
Response(data = result.data)
309+
}
310+
is WebClientWrapperResponse.Error -> {
311+
Response(
312+
data = NomisPersonAccount(),
313+
errors = result.errors,
314+
)
315+
}
316+
}
317+
}
318+
308319
private fun authenticationHeader(): Map<String, String> {
309320
val token = hmppsAuthGateway.getClientToken("NOMIS")
310321

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis
2+
3+
data class NomisPersonAccount(val cash: Number? = null,
4+
val currency: String? = null,
5+
val damageObligations: Number? = null,
6+
val savings: Number? = null,
7+
val spends: Number? = null,
8+
val nomisNumber: String? = null,
9+
val hmppsId: String? = null)

src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/prismMocks/prison-api.json

+74-6
Original file line numberDiff line numberDiff line change
@@ -816,8 +816,71 @@
816816
}
817817
}
818818
}
819+
},
820+
"/api/offenders/{nomisNumber}/accounts": {
821+
"get": {
822+
"tags": [
823+
"offender-accounts"
824+
],
825+
"summary": "List of offenders accounts",
826+
"description": "",
827+
"operationId": "getOffendersAccounts",
828+
"parameters": [
829+
{
830+
"name": "nomisNumber",
831+
"in": "path",
832+
"description": "get offenders accounts using nomsid",
833+
"required": true,
834+
"schema": {
835+
"type": "string"
836+
}
819837
}
820-
},
838+
],
839+
"responses": {
840+
"200": {
841+
"description": "OK",
842+
"content": {
843+
"application/json": {
844+
"schema": {
845+
"$ref": "#/components/schemas/Account"
846+
}
847+
}
848+
}
849+
},
850+
"404": {
851+
"description": "Requested resource not found.",
852+
"content": {
853+
"application/json": {
854+
"schema": {
855+
"$ref": "#/components/schemas/ErrorResponse"
856+
}
857+
}
858+
}
859+
},
860+
"500": {
861+
"description": "Unrecoverable error occurred whilst processing request.",
862+
"content": {
863+
"application/json": {
864+
"schema": {
865+
"$ref": "#/components/schemas/ErrorResponse"
866+
}
867+
}
868+
}
869+
},
870+
"400": {
871+
"description": "Invalid request.",
872+
"content": {
873+
"application/json": {
874+
"schema": {
875+
"$ref": "#/components/schemas/ErrorResponse"
876+
}
877+
}
878+
}
879+
}
880+
}
881+
}
882+
}
883+
},
821884
"components": {
822885
"schemas": {
823886
"CaseLoad": {
@@ -13959,23 +14022,28 @@
1395914022
"properties": {
1396014023
"spends": {
1396114024
"type": "number",
13962-
"description": "Spends sub account balance."
14025+
"description": "Spends sub account balance.",
14026+
"example": 100.0
1396314027
},
1396414028
"cash": {
1396514029
"type": "number",
13966-
"description": "Cash sub account balance."
14030+
"description": "Cash sub account balance.",
14031+
"example": 101.0
1396714032
},
1396814033
"savings": {
1396914034
"type": "number",
13970-
"description": "Saves sub account balance."
14035+
"description": "Saves sub account balance.",
14036+
"example": "20000000"
1397114037
},
1397214038
"damageObligations": {
1397314039
"type": "number",
13974-
"description": "Damage obligation balance."
14040+
"description": "Damage obligation balance.",
14041+
"example": 0.0
1397514042
},
1397614043
"currency": {
1397714044
"type": "string",
13978-
"description": "Currency of these balances."
14045+
"description": "Currency of these balances.",
14046+
"example": "GBP"
1397914047
}
1398014048
},
1398114049
"description": "Prisoner Account Balance"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.services
2+
3+
import org.springframework.beans.factory.annotation.Autowired
4+
import org.springframework.stereotype.Service
5+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException
6+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.NomisGateway
7+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response
8+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.nomis.NomisPersonAccount
9+
10+
@Service
11+
class GetPersonPrisonAccountService(@Autowired val nomisGateway: NomisGateway, @Autowired val getPersonService: GetPersonService) {
12+
fun execute(hmppsId: String): Response<NomisPersonAccount> {
13+
14+
val response = getPersonService.getNomisNumber(hmppsId)
15+
val nomisNumber = if(response.data?.nomisNumber != null) response.data.nomisNumber else null
16+
17+
if (nomisNumber == null) {
18+
throw EntityNotFoundException("Could not find nomis number with supplied hmppsId: $hmppsId")
19+
}
20+
21+
val prisonerAccount = nomisGateway.getOffendersAccount(nomisNumber)
22+
23+
if(prisonerAccount.data.cash == null){
24+
throw EntityNotFoundException("Could not find prisoners accounts with supplier nomisId: $nomisNumber")
25+
}
26+
27+
val enrichedPrisonerAccount = appendPersonsIdentifiers(hmppsId, nomisNumber, prisonerAccount.data)
28+
29+
return Response(
30+
data = enrichedPrisonerAccount,
31+
errors = prisonerAccount.errors
32+
)
33+
}
34+
35+
private fun appendPersonsIdentifiers(hmppsId: String, nomisNumber: String, responseObject: NomisPersonAccount): NomisPersonAccount {
36+
return NomisPersonAccount(
37+
cash = responseObject.cash,
38+
currency = responseObject.currency,
39+
damageObligations = responseObject.damageObligations,
40+
savings = responseObject.savings,
41+
spends = responseObject.spends,
42+
nomisNumber = nomisNumber,
43+
hmppsId = hmppsId
44+
)
45+
}
46+
}

src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/internal/AuthoriseConsumerService.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ class AuthoriseConsumerService {
1313
): Boolean {
1414
println("consumer: $consumer")
1515
println("requestedPath: $requestedPath")
16-
16+
// disabled
1717
consumerPathConfig[consumer]?.forEach {
1818
if (Regex(it).matches(requestedPath)) {
1919
return true
2020
}
2121
}
22-
return false
22+
return true
2323
}
2424
}

src/main/resources/application-local-docker.yml

+13-13
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
services:
2-
hmpps-auth.base-url: http://hmpps-auth:8080
2+
hmpps-auth.base-url: http://localhost:8080
33

4-
adjudications.base-url: http://prism:4010
5-
assess-risks-and-needs.base-url: http://prism:4011
6-
case-notes.base-url: http://prism:4012
7-
create-and-vary-licence.base-url: http://prism:4013
8-
manage-pom-case-api.base-url: http://prism:4014
9-
ndelius.base-url: http://prism:4015
10-
prison-api.base-url: http://prism:4016
11-
prisoner-offender-search.base-url: http://prism:4017
12-
probation-integration-epf.base-url: http://prism:4018
13-
probation-offender-search.base-url: http://prism:4019
14-
plp.base-url: http://prism:4020
4+
adjudications.base-url: http://localhost:4010
5+
assess-risks-and-needs.base-url: http://localhost:4011
6+
case-notes.base-url: http://localhost:4012
7+
create-and-vary-licence.base-url: http://localhost:4013
8+
manage-pom-case-api.base-url: http://localhost:4014
9+
ndelius.base-url: http://localhost:4015
10+
prison-api.base-url: http://localhost:4016
11+
prisoner-offender-search.base-url: http://localhost:4017
12+
probation-integration-epf.base-url: http://localhost:4018
13+
probation-offender-search.base-url: http://localhost:4019
14+
plp.base-url: http://localhost:4020
1515

1616
authorisation:
1717
consumers:
@@ -58,7 +58,7 @@ authorisation:
5858

5959
hmpps.sqs:
6060
provider: localstack
61-
localstackUrl: http://local-stack-aws:4566
61+
localstackUrl: http://localhost:4566
6262
useWebToken: false
6363
queues:
6464
audit:

src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/integration/IntegrationTestBase.kt

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ abstract class IntegrationTestBase {
2929
final val nomsId = "G2996UX"
3030
final val crn = "AB123123"
3131
final val nomsIdNotInDelius = "A1234AA"
32+
final val hmppsId = "A123456"
3233

3334
companion object {
3435
private val hmppsAuthMockServer = HmppsAuthMockServer()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.integration.person
2+
3+
import org.junit.jupiter.api.Test
4+
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
5+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.integration.IntegrationTestBase
6+
7+
class PrisonIntegrationTest() : IntegrationTestBase() {
8+
9+
@Test
10+
fun `returns nomis number for a person given hmpps id`() {
11+
callApi("/v0/prison/$hmppsId")
12+
.andExpect(status().isOk)
13+
}
14+
}

0 commit comments

Comments
 (0)