Skip to content

Commit

Permalink
[ESWE-1181] Add DB (PostgreSQL)
Browse files Browse the repository at this point in the history
- Added local DB (PostgreSQL)
- Added Flyway
- Enabled JPA
  • Loading branch information
rickchoijd committed Jan 28, 2025
1 parent 1ab1fee commit 89b8088
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 4 deletions.
8 changes: 6 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM --platform=$BUILDPLATFORM eclipse-temurin:21-jdk-jammy AS builder

ARG BUILD_NUMBER
ENV BUILD_NUMBER ${BUILD_NUMBER:-1_0_0}
ENV BUILD_NUMBER=${BUILD_NUMBER:-1_0_0}

WORKDIR /app
ADD . .
Expand All @@ -11,7 +11,7 @@ FROM eclipse-temurin:21-jre-jammy
LABEL maintainer="HMPPS Digital Studio <[email protected]>"

ARG BUILD_NUMBER
ENV BUILD_NUMBER ${BUILD_NUMBER:-1_0_0}
ENV BUILD_NUMBER=${BUILD_NUMBER:-1_0_0}

RUN apt-get update && \
apt-get -y upgrade && \
Expand All @@ -23,6 +23,10 @@ RUN ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime && echo "$TZ" > /etc/timezo
RUN addgroup --gid 2000 --system appgroup && \
adduser --uid 2000 --system appuser --gid 2000

# Install AWS RDS Root cert into Java truststore
RUN mkdir /home/appuser/.postgresql
ADD --chown=appuser:appgroup https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem /home/appuser/.postgresql/root.crt

WORKDIR /app
COPY --from=builder --chown=appuser:appgroup /app/build/libs/hmpps-jobs-board-integration-api*.jar /app/app.jar
COPY --from=builder --chown=appuser:appgroup /app/build/libs/applicationinsights-agent*.jar /app/agent.jar
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ The integration service has a `/health` endpoint which indicates the service is
docker compose pull && docker compose up -d
```

will build the application and run it and HMPPS Auth within a local docker instance.
will build the application and run it and HMPPS Auth, with a `PostgreSQL` database and `localstack` within local docker.

### Running the application in Intellij

```bash
docker compose pull && docker compose up --scale hmpps-jobs-board-integration-api=0 -d
```

will just start a docker instance of HMPPS Auth and `localstack`. The application should then be started with a `dev` or `local` active profile
will just start a docker instance of HMPPS Auth, `PostgreSQL` database, and `localstack`. The application should then be started with a `dev` or `local` active profile
in Intellij.
* supply required env var, e.g.
* `spring.profiles.active`=`dev`
Expand Down
5 changes: 5 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ ext["logback.version"] = "1.5.15"
dependencies {
implementation("uk.gov.justice.service.hmpps:hmpps-kotlin-spring-boot-starter:1.1.1")
implementation("uk.gov.justice.service.hmpps:hmpps-sqs-spring-boot-starter:5.2.2")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0")

runtimeOnly("org.flywaydb:flyway-database-postgresql")
runtimeOnly("org.postgresql:postgresql")

testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
}

Expand Down Expand Up @@ -45,6 +49,7 @@ testing {
implementation("org.apache.commons:commons-compress:1.27.1")
}
implementation("org.testcontainers:localstack")
implementation("org.testcontainers:postgresql")
implementation("org.jetbrains.kotlin:kotlin-test-junit5")
}

Expand Down
12 changes: 12 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ services:
- SPRING_PROFILES_ACTIVE=dev
- APPLICATION_AUTHENTICATION_UI_ALLOWLIST=0.0.0.0/0

job-board-intg-db:
image: postgres:16.3
container_name: integration-db
networks:
- hmpps
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=job-board-intg
- POSTGRES_USER=job-board-intg
- POSTGRES_DB=job-board-intg

localstack:
image: localstack/localstack:4
container_name: integration-localstack
Expand Down
5 changes: 5 additions & 0 deletions helm_deploy/hmpps-jobs-board-integration-api/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ generic-service:
MN_JOBBOARD_API_TOKEN: "MN_JOBBOARD_API_TOKEN"
application-insights:
APPLICATIONINSIGHTS_CONNECTION_STRING: "APPLICATIONINSIGHTS_CONNECTION_STRING"
rds-postgresql-instance-output:
DATABASE_USERNAME: "database_username"
DATABASE_PASSWORD: "database_password"
DATABASE_NAME: "database_name"
DATABASE_ENDPOINT: "rds_instance_endpoint"

allowlist:
groups:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import org.springframework.test.context.bean.override.mockito.MockitoSpyBean
import org.springframework.test.web.reactive.server.WebTestClient
import uk.gov.justice.digital.hmpps.jobsboardintegrationapi.integration.testcontainers.LocalStackContainer
import uk.gov.justice.digital.hmpps.jobsboardintegrationapi.integration.testcontainers.LocalStackContainer.setLocalStackProperties
import uk.gov.justice.digital.hmpps.jobsboardintegrationapi.integration.testcontainers.PostgresContainer
import uk.gov.justice.digital.hmpps.jobsboardintegrationapi.integration.wiremock.ExampleApiExtension
import uk.gov.justice.digital.hmpps.jobsboardintegrationapi.integration.wiremock.ExampleApiExtension.Companion.exampleApi
import uk.gov.justice.digital.hmpps.jobsboardintegrationapi.integration.wiremock.HmppsAuthApiExtension
Expand Down Expand Up @@ -54,10 +55,20 @@ abstract class IntegrationTestBase {

companion object {
private val localStackContainer by lazy { LocalStackContainer.instance }
private val postgresContainer = PostgresContainer.flywayContainer

@JvmStatic
@DynamicPropertySource
fun configureTestContainers(registry: DynamicPropertyRegistry) {
postgresContainer?.run {
registry.add("spring.datasource.url", postgresContainer::getJdbcUrl)
registry.add("spring.datasource.username", postgresContainer::getUsername)
registry.add("spring.datasource.password", postgresContainer::getPassword)
registry.add("spring.flyway.url", postgresContainer::getJdbcUrl)
registry.add("spring.flyway.user", postgresContainer::getUsername)
registry.add("spring.flyway.password", postgresContainer::getPassword)
}

localStackContainer?.also { setLocalStackProperties(it, registry) }
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package uk.gov.justice.digital.hmpps.jobsboardintegrationapi.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 flywayContainer: PostgreSQLContainer<Nothing>? by lazy { startPostgresqlContainer() }
val repositoryContainer: PostgreSQLContainer<Nothing>? by lazy { startPostgresqlContainer() }

private fun startPostgresqlContainer(): PostgreSQLContainer<Nothing>? {
if (isPostgresRunning()) {
log.warn("Using existing PostgreSQL database")
return null
}

log.info("Creating a TestContainers PostgreSQL database")

return PostgreSQLContainer<Nothing>("postgres:16.3").apply {
withEnv("HOSTNAME_EXTERNAL", "localhost")
withDatabaseName("job-board-intg")
withUsername("job-board-intg")
withPassword("job-board-intg")
setWaitStrategy(Wait.forListeningPort())
withReuse(true)
start()
}
}

private fun isPostgresRunning(): Boolean =
try {
val serverSocket = ServerSocket(5432)
serverSocket.localPort == 0
} catch (error: IOException) {
log.warn("A PostgreSQL database is running")
true
}

private val log = LoggerFactory.getLogger(this::class.java)
}
9 changes: 9 additions & 0 deletions src/integrationTest/resources/application-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ management.endpoint:
health.cache.time-to-live: 0
info.cache.time-to-live: 0

spring:
jpa:
show-sql: true
datasource:
url: 'jdbc:postgresql://${DATABASE_ENDPOINT}/${DATABASE_NAME}?sslmode=disable&autosave=conservative'
flyway:
baseline-on-migrate: true
clean-disabled: false

hmpps-auth:
url: "http://localhost:8090/auth"

Expand Down
9 changes: 9 additions & 0 deletions src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,12 @@ api:

integration:
enabled: false

spring:
datasource:
url: 'jdbc:postgresql://localhost:5432/job-board-intg'
username: 'job-board-intg'
password: 'job-board-intg'
flyway:
user: 'job-board-intg'
password: 'job-board-intg'
24 changes: 24 additions & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,30 @@ spring:
local:
- "dev"
- "localstack"

jpa:
open-in-view: false
show-sql: false
generate-ddl: false
hibernate:
ddl-auto: none

datasource:
url: 'jdbc:postgresql://${DATABASE_ENDPOINT}/${DATABASE_NAME}?sslmode=verify-full'
username: ${DATABASE_USERNAME}
password: ${DATABASE_PASSWORD}
hikari:
pool-name: Hmpps-job-board-integration
connectionTimeout: 1000
validationTimeout: 500

flyway:
baselineOnMigrate: true
validateMigrationNaming: true
url: ${spring.datasource.url}
user: ${DATABASE_USERNAME}
password: ${DATABASE_PASSWORD}

server:
port: 8080
servlet:
Expand Down

0 comments on commit 89b8088

Please sign in to comment.