Skip to content

Commit

Permalink
Merge branch 'main' into PI-2887-new-api-to-get-delius-roles
Browse files Browse the repository at this point in the history
  • Loading branch information
achimber-moj authored Mar 3, 2025
2 parents 063f5c5 + 6729f22 commit a312b16
Show file tree
Hide file tree
Showing 14 changed files with 236 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ jobs:

- name: Push images
if: env.push == 'true'
uses: nick-fields/retry@c97818ca39074beaea45180dba704f92496a0082 # v3.0.1
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
max_attempts: 3 # Pushing lots of new image versions at once can result in GitHub rate-limiting so we retry this step
timeout_minutes: 15
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
java-version: '21'
distribution: 'temurin'

- uses: gradle-update/update-gradle-wrapper-action@9cca748ef7cfd967bc3a5c39e15a7aa229ad1b3d # v2.0.1
- uses: gradle-update/update-gradle-wrapper-action@512b1875f3b6270828abfe77b247d5895a2da1e5 # v2.1.0
with:
labels: dependencies
repo-token: ${{ steps.app-token.outputs.token }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/readonly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ jobs:
run: kubectl scale deploy '${{ matrix.project }}' --replicas "${{ inputs.action == 'enable' && '0' || '2' }}"

- name: ${{ inputs.action == 'enable' && 'Block' || 'Unblock' }} ingresses
uses: nick-fields/retry@c97818ca39074beaea45180dba704f92496a0082 # v3.0.1
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
max_attempts: 3 # Patching ingresses intermittently fails on MOJ Cloud Platform, so we retry this step
timeout_minutes: 15
Expand Down Expand Up @@ -152,7 +152,7 @@ jobs:

- name: Block updates
if: inputs.action == 'enable' && matrix.project != 'hmpps-auth-and-delius' && matrix.project != 'probation-search-and-delius' && matrix.project != 'feature-flags' # Note: hmpps-auth is excluded here to continue allowing 'POST /authenticate' requests, which are read-only
uses: nick-fields/retry@c97818ca39074beaea45180dba704f92496a0082 # v3.0.1
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
max_attempts: 3 # Patching ingresses intermittently fails on MOJ Cloud Platform, so we retry this step
timeout_minutes: 15
Expand All @@ -174,7 +174,7 @@ jobs:
- name: Unblock updates
if: inputs.action == 'disable' && matrix.project != 'hmpps-auth-and-delius' && matrix.project != 'probation-search-and-delius' && matrix.project != 'feature-flags'
uses: nick-fields/retry@c97818ca39074beaea45180dba704f92496a0082 # v3.0.1
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
with:
max_attempts: 3 # Patching ingresses intermittently fails on MOJ Cloud Platform, so we retry this step
timeout_minutes: 15
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ plugins {
val agentDeps: Configuration by configurations.creating

dependencies {
agentDeps("com.microsoft.azure:applicationinsights-agent:3.7.0")
agentDeps("com.microsoft.azure:applicationinsights-agent:3.7.1")
}

val copyAgentTask = project.tasks.register<Copy>("copyAgent") {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"source": "OASys",
"inputs": {
"crnSource": "pris",
"crn": "P467262",
"additionalParameter": "Y",
"laoPrivilege": "ALLOW"
},
"probNumber": "P467262",
"prisNumber": "A8747PN",
"limitedAccessOffender": false,
"pniCalc": null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"source": "OASys",
"inputs": {
"crnSource": "pris",
"crn": "P467261",
"additionalParameter": "N",
"laoPrivilege": "ALLOW"
},
"probNumber": "P467261",
"prisNumber": "A8746PN",
"limitedAccessOffender": false,
"pniCalc": [
{
"offenderPk": 869584726,
"riskLevel": "L",
"missingFields": null,
"sexDomainLevel": "L",
"sexDomainScore": 0,
"thinkingDomainLevel": "M",
"thinkingDomainScore": 1,
"relationshipDomainLevel": "M",
"relationshipDomainScore": 1,
"selfManagementDomainLevel": "H",
"selfManagementDomainScore": 2,
"totalDomainScore": 4,
"overallNeedLevel": "M",
"pniCalculation": "A",
"saraRiskLevelToPartner": 1,
"saraRiskLevelToOther": 2
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,56 @@
"Content-Type": "application/json"
}
}
},
{
"request": {
"method": "GET",
"url": "/eor/oasys/ass/pnildc/pris/A8746PN:N/ALLOW",
"headers": {
"Authorization": {
"matches": "^Bearer oasys.token$"
}
}
},
"response": {
"status": 200,
"bodyFileName": "pni-calculation-success.json",
"headers": {
"Content-Type": "application/json"
}
}
},
{
"request": {
"method": "GET",
"url": "/eor/oasys/ass/pnildc/pris/A8747PN:Y/ALLOW",
"headers": {
"Authorization": {
"matches": "^Bearer oasys.token$"
}
}
},
"response": {
"status": 200,
"bodyFileName": "pni-calculation-no-calculation.json",
"headers": {
"Content-Type": "application/json"
}
}
},
{
"request": {
"method": "GET",
"url": "/eor/oasys/ass/pnildc/pris/A1741PN:N/ALLOW",
"headers": {
"Authorization": {
"matches": "^Bearer oasys.token$"
}
}
},
"response": {
"status": 404
}
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
import uk.gov.justice.digital.hmpps.controller.*
import uk.gov.justice.digital.hmpps.integrations.oasys.Level
import uk.gov.justice.digital.hmpps.telemetry.TelemetryService
import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.contentAsJson
import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken
import java.math.BigDecimal
import java.time.LocalDateTime
import uk.gov.justice.digital.hmpps.integrations.oasys.PniCalculation.Type as PniType

@AutoConfigureMockMvc
@SpringBootTest(webEnvironment = RANDOM_PORT)
Expand Down Expand Up @@ -109,4 +111,44 @@ internal class IntegrationTest {
)
)
}

@Test
fun `get pni success`() {
val res = mockMvc
.perform(get("/assessments/pni/A8746PN?community=false").withToken())
.andExpect(status().isOk)
.andReturn().response.contentAsJson<PniCalculation>()

assertThat(
res,
equalTo(
PniCalculation(
LevelScore(Level.L, 0),
LevelScore(Level.M, 1),
LevelScore(Level.M, 1),
LevelScore(Level.H, 2),
Level.L,
Level.M,
4,
PniType.A,
SaraRiskLevel(1, 2),
listOf(),
)
)
)
}

@Test
fun `get pni no calculation`() {
mockMvc
.perform(get("/assessments/pni/A8747PN?community=true").withToken())
.andExpect(status().isNoContent)
}

@Test
fun `get pni returns 404 if oasys returns 404`() {
mockMvc
.perform(get("/assessments/pni/A1741PN?community=false").withToken())
.andExpect(status().isNotFound)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.*
import org.springframework.web.client.HttpClientErrorException
import uk.gov.justice.digital.hmpps.advice.ErrorResponse
import uk.gov.justice.digital.hmpps.integrations.oasys.OrdsClient
import uk.gov.justice.digital.hmpps.integrations.oasys.asIntegrationModel
import uk.gov.justice.digital.hmpps.integrations.oasys.getRiskPredictors

@RestController
Expand All @@ -26,6 +27,16 @@ class AssessmentController(private val ordsClient: OrdsClient) {
@GetMapping("/{id}/risk-predictors")
fun getRiskPredictors(@PathVariable id: Long): RiskPrediction = ordsClient.getRiskPredictors(id)

@PreAuthorize("hasRole('PROBATION_API__ACCREDITED_PROGRAMMES__ASSESSMENT')")
@GetMapping("/pni/{nomsId}")
fun getPniCalculation(
@PathVariable nomsId: String,
@RequestParam community: Boolean
): ResponseEntity<PniCalculation> =
ordsClient.getPni(nomsId, if (community) "Y" else "N").asIntegrationModel()?.let {
ResponseEntity.ok(it)
} ?: ResponseEntity.noContent().build()

@ExceptionHandler
fun handleNotFound(e: HttpClientErrorException) = ResponseEntity
.status(e.statusCode)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package uk.gov.justice.digital.hmpps.controller

import uk.gov.justice.digital.hmpps.integrations.oasys.Level
import uk.gov.justice.digital.hmpps.integrations.oasys.PniCalculation.Type

data class PniCalculation(
val sexDomain: LevelScore,
val thinkingDomain: LevelScore,
val relationshipDomain: LevelScore,
val selfManagementDomain: LevelScore,
val riskLevel: Level,
val needLevel: Level,
val totalDomainScore: Int,
val pni: Type,
val saraRiskLevel: SaraRiskLevel,
val missingFields: List<String> = listOf(),
)

data class LevelScore(val level: Level, val score: Int)
data class SaraRiskLevel(val toPartner: Int, val toOther: Int)
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ interface OrdsClient {

@GetExchange("/ass/riskscrass/ALLOW/{id}")
fun getAssessmentPredictors(@PathVariable id: Long): OasysRiskPredictors

@GetExchange("/ass/pnildc/pris/{nomsId}:{communityFlag}/ALLOW")
fun getPni(
@PathVariable nomsId: String,
@PathVariable communityFlag: String
): PniResult
}

fun OrdsClient.getRiskPredictors(assessmentId: Long): RiskPrediction =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package uk.gov.justice.digital.hmpps.integrations.oasys

import uk.gov.justice.digital.hmpps.controller.LevelScore
import uk.gov.justice.digital.hmpps.controller.SaraRiskLevel
import uk.gov.justice.digital.hmpps.controller.PniCalculation as IntegrationModel

data class PniResult(val pniCalc: List<PniCalculation>?)
data class PniCalculation(
val missingFields: List<String>?,
val riskLevel: Level,
val sexDomainLevel: Level,
val sexDomainScore: Int,
val thinkingDomainLevel: Level,
val thinkingDomainScore: Int,
val relationshipDomainLevel: Level,
val relationshipDomainScore: Int,
val selfManagementDomainLevel: Level,
val selfManagementDomainScore: Int,
val overallNeedLevel: Level,
val totalDomainScore: Int,
val pniCalculation: Type,
val saraRiskLevelToPartner: Int,
val saraRiskLevelToOther: Int,
) {
enum class Type {
H, M, A, O
}
}

enum class Level {
H, M, L
}

fun PniResult.asIntegrationModel(): IntegrationModel? = with(pniCalc?.firstOrNull()) {
if (this == null) null
else IntegrationModel(
sexDomain = LevelScore(sexDomainLevel, sexDomainScore),
thinkingDomain = LevelScore(thinkingDomainLevel, thinkingDomainScore),
relationshipDomain = LevelScore(relationshipDomainLevel, relationshipDomainScore),
selfManagementDomain = LevelScore(selfManagementDomainLevel, selfManagementDomainScore),
riskLevel = riskLevel,
needLevel = overallNeedLevel,
totalDomainScore = totalDomainScore,
pni = pniCalculation,
saraRiskLevel = SaraRiskLevel(saraRiskLevelToPartner, saraRiskLevelToOther),
missingFields = missingFields ?: listOf(),
)
}
2 changes: 1 addition & 1 deletion projects/redrive-dead-letter-queues/container/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM public.ecr.aws/aws-cli/aws-cli:2.24.10
FROM public.ecr.aws/aws-cli/aws-cli:2.24.15

USER root
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
Expand Down
14 changes: 7 additions & 7 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -74,26 +74,26 @@ dependencyResolutionManagement {
create("libs") {
library("asyncapi", "org.openfolder:kotlin-asyncapi-spring-web:3.0.4")
library("aws-autoconfigure", "io.awspring.cloud:spring-cloud-aws-autoconfigure:3.3.0")
library("aws-query-protocol", "software.amazon.awssdk:aws-query-protocol:2.30.26")
library("aws-query-protocol", "software.amazon.awssdk:aws-query-protocol:2.30.31")
library("aws-sns", "io.awspring.cloud:spring-cloud-aws-starter-sns:3.3.0")
library("aws-sqs", "io.awspring.cloud:spring-cloud-aws-starter-sqs:3.3.0")
library("aws-starter", "io.awspring.cloud:spring-cloud-aws-starter:3.3.0")
library("aws-sts", "software.amazon.awssdk:sts:2.30.26")
library("azure-app-insights", "com.microsoft.azure:applicationinsights-web:3.7.0")
library("aws-sts", "software.amazon.awssdk:sts:2.30.31")
library("azure-app-insights", "com.microsoft.azure:applicationinsights-web:3.7.1")
library("azure-identity", "com.azure:azure-identity:1.15.3")
library("flipt", "io.flipt:flipt-java:1.1.2")
library("html2md", "com.vladsch.flexmark:flexmark-html2md-converter:0.64.8")
library("microsoft-graph", "com.microsoft.graph:microsoft-graph:6.29.0")
library("microsoft-graph", "com.microsoft.graph:microsoft-graph:6.30.1")
library("mockito-inline", "org.mockito:mockito-inline:5.2.0")
library("mockito-kotlin", "org.mockito.kotlin:mockito-kotlin:5.4.0")
library("notify", "uk.gov.service.notify:notifications-java-client:5.2.1-RELEASE")
library(
"opentelemetry-annotations",
"io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations:2.13.1"
"io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations:2.13.3"
)
library("sentry", "io.sentry:sentry-spring-boot-starter-jakarta:8.2.0")
library("sentry", "io.sentry:sentry-spring-boot-starter-jakarta:8.3.0")
library("springdoc", "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.5")
library("wiremock", "org.wiremock:wiremock-standalone:3.12.0")
library("wiremock", "org.wiremock:wiremock-standalone:3.12.1")

bundle(
"aws-messaging",
Expand Down

0 comments on commit a312b16

Please sign in to comment.