Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CDPS-1086: Dependency bumps and fixing subsequent issues #8

Merged
merged 1 commit into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .trivyignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@
# Suppression for h2 2.1.214 password on command line vulnerability
# can be suppressed as we only run h2 locally and not on build environments
CVE-2022-45868
# Suppression for tomcat vulnerability affecting jsp compilation in the default servlet
# can be suppressed as we do not use the default servlet and haven't configured it for write either
CVE-2024-50379
10 changes: 5 additions & 5 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
id("uk.gov.justice.hmpps.gradle-spring-boot") version "6.0.9"
id("uk.gov.justice.hmpps.gradle-spring-boot") version "6.1.2"
kotlin("plugin.spring") version "2.0.21"
kotlin("plugin.jpa") version "2.0.21"
jacoco
Expand All @@ -13,12 +13,12 @@ configurations {
dependencies {

// Spring Boot
implementation("uk.gov.justice.service.hmpps:hmpps-kotlin-spring-boot-starter:1.0.8")
implementation("uk.gov.justice.service.hmpps:hmpps-kotlin-spring-boot-starter:1.1.1")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")

// OpenAPI
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0")
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.3")

// UUIDs
implementation("com.fasterxml.uuid:java-uuid-generator:5.1.0")
Expand All @@ -32,9 +32,9 @@ dependencies {
testImplementation("uk.gov.justice.service.hmpps:hmpps-kotlin-spring-boot-starter-test:1.1.1")
testImplementation("org.testcontainers:junit-jupiter:1.20.4")
testImplementation("org.testcontainers:postgresql:1.20.4")
testImplementation("io.mockk:mockk:1.13.13")
testImplementation("io.mockk:mockk:1.13.16")
testImplementation("org.wiremock:wiremock-standalone:3.10.0")
testImplementation("io.swagger.parser.v3:swagger-parser:2.1.24") {
testImplementation("io.swagger.parser.v3:swagger-parser:2.1.25") {
exclude(group = "io.swagger.core.v3")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import io.swagger.v3.oas.models.Components
import io.swagger.v3.oas.models.OpenAPI
import io.swagger.v3.oas.models.info.Contact
import io.swagger.v3.oas.models.info.Info
import io.swagger.v3.oas.models.media.DateTimeSchema
import io.swagger.v3.oas.models.media.Schema
import io.swagger.v3.oas.models.media.StringSchema
import io.swagger.v3.oas.models.security.OAuthFlow
Expand Down Expand Up @@ -84,7 +83,8 @@ class OpenApiConfiguration(
val properties = schema.properties ?: mutableMapOf()
for (propertyName in properties.keys) {
val propertySchema = properties[propertyName]!!
if (propertySchema is DateTimeSchema) {

if (propertySchema.format == "date-time") {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OpenAPI changes also broke this, now having to check the format instead...

properties.replace(
propertyName,
StringSchema()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ import java.time.ZonedDateTime
@Schema(description = "Reference Data Code")
@JsonInclude(NON_NULL)
data class ReferenceDataCodeDto(
@Schema(description = "Id", example = "FACIAL_HAIR_BEARDED")
@Schema(description = "Id", example = "FOOD_ALLERGY_MILK")
val id: String,

@Schema(description = "Short code for the reference data code", example = "FACIAL_HAIR")
@Schema(description = "Short code for the reference data domain", example = "FOOD_ALLERGY")
val domain: String,

@Schema(description = "Short code for reference data code", example = "BEARDED")
@Schema(description = "Short code for reference data code", example = "MILK")
val code: String,

@Schema(description = "Description of the reference data code", example = "Full Beard")
@Schema(description = "Description of the reference data code", example = "Milk")
val description: String,

@Schema(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import java.time.ZonedDateTime
@Schema(description = "Reference Data Domain")
@JsonInclude(NON_NULL)
data class ReferenceDataDomainDto(
@Schema(description = "Short code for the reference data domain", example = "HAIR")
@Schema(description = "Short code for the reference data domain", example = "FOOD_ALLERGY")
val code: String,

@Schema(description = "Description of the reference data domain", example = "Hair type or colour")
@Schema(description = "Description of the reference data domain", example = "Food allergy")
val description: String,

@Schema(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import io.swagger.v3.oas.annotations.media.Schema
@Schema(description = "Reference Data Simple DTO - for use in dropdowns")
@JsonInclude(NON_NULL)
data class ReferenceDataSimpleDto(
@Schema(description = "Id", example = "FACIAL_HAIR_BEARDED")
@Schema(description = "Id", example = "FOOD_ALLERGY_MILK")
val id: String,

@Schema(description = "Description of the reference data code", example = "Full Beard")
@Schema(description = "Description of the reference data code", example = "Milk")
val description: String,

@Schema(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,43 +1,47 @@
package uk.gov.justice.digital.hmpps.healthandmedication.dto.request

import com.fasterxml.jackson.annotation.JsonAnySetter
import com.fasterxml.jackson.annotation.JsonIgnore
import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL
import io.swagger.v3.oas.annotations.StringToClassMapItem
import io.swagger.v3.oas.annotations.media.Schema
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED
import uk.gov.justice.digital.hmpps.healthandmedication.annotation.NullishReferenceDataCodeList
import uk.gov.justice.digital.hmpps.healthandmedication.utils.Nullish
import uk.gov.justice.digital.hmpps.healthandmedication.utils.getAttributeAsNullish

private abstract class StringList : List<String>

@Schema(
description = "Request object for updating a prisoner's health information. Can include one or multiple fields. " +
"If an attribute is provided and set to 'null' it will be updated equal to 'null'. " +
"If it is not provided it is not updated",
"If an attribute is not provided it is not updated. Valid reference codes for `foodAllergies` can be retrieved by " +
"querying `GET /reference-data/domains/FOOD_ALLERGY` and `GET /reference-data/domains/MEDICAL_DIET` for " +
"`medicalDietaryRequirements`.",
type = "object",
properties = [
StringToClassMapItem(key = "foodAllergies", value = StringList::class),
StringToClassMapItem(key = "medicalDietaryRequirements", value = StringList::class),
],
example = """
{
"foodAllergies": ["FOOD_ALLERGY_EGG", "FOOD_ALLERGY_MILK"],
"medicalDietaryRequirements": ["MEDICAL_DIET_LOW_CHOLESTEROL"]
}
""",
)
@JsonInclude(NON_NULL)
data class PrisonerHealthUpdateRequest(
@Schema(hidden = true)
@JsonAnySetter
private val attributes: MutableMap<String, Any?> = mutableMapOf(),
) {
@Schema(
description = "The food allergies the prisoner has. A list of `ReferenceDataCode`.`id`",
type = "string[]",
example = "[FOOD_ALLERGY_EGG, FOOD_ALLERGY_MILK]",
requiredMode = NOT_REQUIRED,
)
@field:NullishReferenceDataCodeList(
domains = ["FOOD_ALLERGY"],
)
val foodAllergies: Nullish<List<String>> = getAttributeAsNullish<List<String>>(attributes, "foodAllergies")
@field:NullishReferenceDataCodeList(domains = ["FOOD_ALLERGY"])
@JsonIgnore
Copy link
Contributor Author

@brightonsbox brightonsbox Jan 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jackson update changed the way that it was handling Nullish... which meant that I now needed to @JsonIgnore these fields... which then has a knock on impact that the OpenAPI schema is then ignored... (annoyingly for us, there's no way of forcing OpenAPI to ignore an @JsonIgnore https://github.com/springdoc/springdoc-openapi/blob/main/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocAnnotationsUtils.java#L91).

val foodAllergies: Nullish<List<String>> =
getAttributeAsNullish<List<String>>(attributes, "foodAllergies")

@Schema(
description = "The medical dietary requirements the prisoner has. A list of `ReferenceDataCode`.`id`",
type = "string[]",
example = "[MEDICAL_DIET_LOW_FAT, FREE_FROM_EGG]",
requiredMode = NOT_REQUIRED,
)
@field:NullishReferenceDataCodeList(
domains = ["MEDICAL_DIET", "FREE_FROM"],
)
@field:NullishReferenceDataCodeList(domains = ["MEDICAL_DIET"])
@JsonIgnore
val medicalDietaryRequirements: Nullish<List<String>> =
getAttributeAsNullish<List<String>>(attributes, "medicalDietaryRequirements")
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ import uk.gov.justice.digital.hmpps.healthandmedication.dto.ReferenceDataSimpleD

@Schema(description = "Health data")
data class HealthDto(
@Schema(description = "Smoker or vaper")
val smokerOrVaper: ValueWithMetadata<ReferenceDataSimpleDto?>? = null,

@Schema(description = "Food allergies")
val foodAllergies: ValueWithMetadata<List<ReferenceDataSimpleDto>>? = null,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import java.time.ZonedDateTime
class FieldHistory(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val fieldHistoryId: Long = -1,
val fieldHistoryId: Long = 0,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JPA changed how it was handling unpersisted entities... suddenly you're not allowed to have a default value of -1 anymore to identify something not persisted 🤷


// Allow this to mutate in order to handle merges
var prisonerNumber: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class FoodAllergy(
) {
@Id
@GeneratedValue(strategy = IDENTITY)
val id: Long = -1
val id: Long = 0

override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class MedicalDietaryRequirement(
) {
@Id
@GeneratedValue(strategy = IDENTITY)
val id: Long = -1
val id: Long = 0

override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,8 @@ import uk.gov.justice.digital.hmpps.healthandmedication.mapper.toDto
class ReferenceDataCodeService(
private val referenceDataCodeRepository: ReferenceDataCodeRepository,
) {

/*
* Exclude certain reference data codes
*/
private val excludedCodes = setOf(
Pair("FACIAL_HAIR", "NA"),
Pair("EYE", "MISSING"),
)

fun getReferenceDataCodes(domain: String, includeInactive: Boolean): Collection<ReferenceDataCodeDto> =
referenceDataCodeRepository.findAllByDomainAndIncludeInactive(domain, includeInactive)
.filterNot { excludedCodes.contains(Pair(it.domain.code, it.code)) }
.map { it.toDto() }

fun getReferenceDataCode(code: String, domain: String): ReferenceDataCodeDto =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ class PrisonerPrisonerHealthControllerIntTest : IntegrationTestBase() {
).expectBody().json(
// language=json
"""
{ "smokerOrVaper": null,
{
"foodAllergies": {
"value": [],
"lastModifiedAt":"2024-06-14T09:10:11+0100",
Expand Down Expand Up @@ -263,7 +263,6 @@ class PrisonerPrisonerHealthControllerIntTest : IntegrationTestBase() {
// language=json
"""
{
"smokerOrVaper": null,
"foodAllergies": {
"value": [
{
Expand All @@ -288,7 +287,6 @@ class PrisonerPrisonerHealthControllerIntTest : IntegrationTestBase() {
// language=json
"""
{
"smokerOrVaper": null,
"foodAllergies": {
"value": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test
import org.springframework.dao.DataIntegrityViolationException
import org.springframework.orm.jpa.JpaObjectRetrievalFailureException
import org.springframework.dao.InvalidDataAccessApiUsageException
import org.springframework.test.context.transaction.TestTransaction
import uk.gov.justice.digital.hmpps.healthandmedication.enums.HealthAndMedicationField.FOOD_ALLERGY
import uk.gov.justice.digital.hmpps.healthandmedication.jpa.FieldHistory
Expand Down Expand Up @@ -71,7 +71,7 @@ class FieldHistoryRepositoryTest : RepositoryTest() {
createdBy = USER1,
)

assertThrows(JpaObjectRetrievalFailureException::class.java) {
assertThrows(InvalidDataAccessApiUsageException::class.java) {
fieldHistoryRepository.save(fieldHistory).fieldHistoryId

TestTransaction.flagForCommit()
Expand Down
Loading