Skip to content

Commit

Permalink
CDPS-1086: Setting up JPA
Browse files Browse the repository at this point in the history
  • Loading branch information
brightonsbox committed Jan 13, 2025
1 parent 4b5550a commit b86d0ca
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 28 deletions.
43 changes: 23 additions & 20 deletions .github/workflows/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ jobs:
additional_docker_tag: ${{ inputs.additional_docker_tag }}
push: ${{ inputs.push || true }}
docker_multiplatform: true

deploy_dev:
name: Deploy to the development environment
needs:
Expand All @@ -63,23 +64,25 @@ jobs:
with:
environment: 'development'
app_version: '${{ needs.build.outputs.app_version }}'
# deploy_preprod:
# name: Deploy to pre-production environment
# needs:
# - build
# - deploy_dev
# uses: ministryofjustice/hmpps-github-actions/.github/workflows/deploy_env.yml@v2 # WORKFLOW_VERSION
# secrets: inherit
# with:
# environment: 'preprod'
# app_version: '${{ needs.build.outputs.app_version }}'
# deploy_prod:
# name: Deploy to production environment
# needs:
# - build
# - deploy_preprod
# uses: ministryofjustice/hmpps-github-actions/.github/workflows/deploy_env.yml@v2 # WORKFLOW_VERSION
# secrets: inherit
# with:
# environment: 'production'
# app_version: '${{ needs.build.outputs.app_version }}'

deploy_preprod:
name: Deploy to pre-production environment
needs:
- build
- deploy_dev
uses: ministryofjustice/hmpps-github-actions/.github/workflows/deploy_env.yml@v2 # WORKFLOW_VERSION
secrets: inherit
with:
environment: 'preprod'
app_version: '${{ needs.build.outputs.app_version }}'

deploy_prod:
name: Deploy to production environment
needs:
- build
- deploy_preprod
uses: ministryofjustice/hmpps-github-actions/.github/workflows/deploy_env.yml@v2 # WORKFLOW_VERSION
secrets: inherit
with:
environment: 'production'
app_version: '${{ needs.build.outputs.app_version }}'
28 changes: 28 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
plugins {
id("uk.gov.justice.hmpps.gradle-spring-boot") version "6.1.0"
kotlin("plugin.spring") version "2.0.21"
kotlin("plugin.jpa") version "2.0.21"
jacoco
idea
}

configurations {
testImplementation { exclude(group = "org.junit.vintage") }
}

dependencies {

// Spring Boot
implementation("uk.gov.justice.service.hmpps:hmpps-kotlin-spring-boot-starter:1.1.0")
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.7.0")

// Database
runtimeOnly("com.zaxxer:HikariCP")
runtimeOnly("org.flywaydb:flyway-database-postgresql")
runtimeOnly("org.postgresql:postgresql")

// Test
testImplementation("uk.gov.justice.service.hmpps:hmpps-kotlin-spring-boot-starter-test:1.1.0")
testImplementation("org.testcontainers:junit-jupiter:1.20.3")
testImplementation("org.testcontainers:postgresql:1.20.3")
testImplementation("org.wiremock:wiremock-standalone:3.9.2")
testImplementation("io.swagger.parser.v3:swagger-parser:2.1.24") {
exclude(group = "io.swagger.core.v3")
Expand All @@ -28,3 +44,15 @@ tasks {
compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21
}
}

// Jacoco code coverage
tasks.named("test") {
finalizedBy("jacocoTestReport")
}

tasks.named<JacocoReport>("jacocoTestReport") {
reports {
html.required.set(true)
xml.required.set(true)
}
}
15 changes: 13 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ services:
environment:
- SERVER_PORT=8080
- HMPPS_AUTH_URL=http://hmpps-auth:8080/auth
# TODO: Remove this URL and replace with outgoing service URLs
- EXAMPLE_URL=http://hmpps-health-and-medication-api:8080
- SPRING_PROFILES_ACTIVE=dev

hmpps-auth:
Expand All @@ -31,5 +29,18 @@ services:
- SPRING_PROFILES_ACTIVE=dev
- APPLICATION_AUTHENTICATION_UI_ALLOWLIST=0.0.0.0/0

health-and-medication-data-db:
image: postgres
networks:
- hmpps
container_name: health-and-medication-data-db
restart: unless-stopped
ports:
- "9432:5432"
environment:
- POSTGRES_PASSWORD=health-and-medication-data
- POSTGRES_USER=health-and-medication-data
- POSTGRES_DB=health-and-medication-data
- TZ="Europe/London"
networks:
hmpps:
13 changes: 10 additions & 3 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,17 @@ spring:
hibernate:
ddl-auto: none

flyway:
enabled: true
url: ${spring.datasource.url}
user: ${database.username}
password: ${database.password}
locations: classpath:/db/migration/common

datasource:
url: 'jdbc:postgresql://${DATABASE_ENDPOINT}/${DATABASE_NAME}?sslmode=verify-full'
username: ${DATABASE_USERNAME}
password: ${DATABASE_PASSWORD}
url: 'jdbc:postgresql://${database.endpoint}/${database.name}?sslmode=verify-full'
username: ${database.username}
password: ${database.password}
hikari:
pool-name: HEALTH-AND-MEDICATION-DB-CP
maximum-pool-size: 10
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package uk.gov.justice.digital.hmpps.healthandmedicationapi.config

import java.time.Clock
import java.time.Instant
import java.time.ZoneId
import java.time.temporal.TemporalAmount

class FixedClock(var instant: Instant, private var zone: ZoneId) : Clock() {

fun elapse(amountToAdd: TemporalAmount) {
instant += amountToAdd
}

override fun instant(): Instant = this.instant
override fun withZone(zone: ZoneId): Clock = this.apply { this.zone = zone }
override fun getZone(): ZoneId = this.zone
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@ import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT
import org.springframework.http.HttpHeaders
import org.springframework.test.context.ActiveProfiles
import org.springframework.test.web.reactive.server.WebTestClient
import uk.gov.justice.digital.hmpps.healthandmedicationapi.integration.wiremock.HmppsAuthApiExtension
import uk.gov.justice.digital.hmpps.healthandmedicationapi.integration.wiremock.HmppsAuthApiExtension.Companion.hmppsAuth
import uk.gov.justice.hmpps.test.kotlin.auth.JwtAuthorisationHelper

@ExtendWith(HmppsAuthApiExtension::class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@ActiveProfiles("test")
abstract class IntegrationTestBase {
abstract class IntegrationTestBase : TestBase() {

@Autowired
protected lateinit var webTestClient: WebTestClient
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package uk.gov.justice.digital.hmpps.healthandmedicationapi.integration

import org.springframework.test.context.ActiveProfiles
import org.springframework.test.context.DynamicPropertyRegistry
import org.springframework.test.context.DynamicPropertySource
import uk.gov.justice.digital.hmpps.healthandmedicationapi.config.FixedClock
import uk.gov.justice.digital.hmpps.healthandmedicationapi.integration.testcontainers.PostgresContainer
import java.time.Instant
import java.time.ZoneId

@ActiveProfiles("test")
abstract class TestBase {

companion object {
val clock: FixedClock = FixedClock(
Instant.parse("2024-06-14T09:10:11.123+01:00"),
ZoneId.of("Europe/London"),
)

private val pgContainer = PostgresContainer.instance

@JvmStatic
@DynamicPropertySource
fun properties(registry: DynamicPropertyRegistry) {
pgContainer?.run {
registry.add("spring.datasource.url", pgContainer::getJdbcUrl)
registry.add("spring.flyway.url", pgContainer::getJdbcUrl)
registry.add("spring.flyway.user", pgContainer::getUsername)
registry.add("spring.flyway.password", pgContainer::getPassword)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package uk.gov.justice.digital.hmpps.healthandmedicationapi.integration.testcontainers

import org.slf4j.LoggerFactory
import org.testcontainers.containers.PostgreSQLContainer
import org.testcontainers.containers.wait.strategy.Wait
import java.io.IOException
import java.net.ServerSocket

object PostgresContainer {
val instance: PostgreSQLContainer<Nothing>? by lazy { startPostgresqlContainer() }

private fun startPostgresqlContainer(): PostgreSQLContainer<Nothing>? {
if (isPostgresRunning()) {
log.warn("Using existing Postgres database")
return null
}
log.info("Creating a Postgres database")
return PostgreSQLContainer<Nothing>("postgres").apply {
withEnv("HOSTNAME_EXTERNAL", "localhost")
withEnv("PORT_EXTERNAL", "5432")
withDatabaseName("health-and-medication-data")
withUsername("health-and-medication-data")
withPassword("health-and-medication-data")
setWaitStrategy(Wait.forListeningPort())
withReuse(true)

start()
}
}

private fun isPostgresRunning(): Boolean =
try {
val serverSocket = ServerSocket(5432)
serverSocket.localPort == 0
} catch (e: IOException) {
true
}

private val log = LoggerFactory.getLogger(this::class.java)
}

0 comments on commit b86d0ca

Please sign in to comment.