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

[ESWE-1181] Add DB (PostgreSQL) #22

Merged
merged 1 commit into from
Jan 29, 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
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")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

add 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")
Comment on lines +20 to +21
Copy link
Contributor Author

@rickchoijd rickchoijd Jan 28, 2025

Choose a reason for hiding this comment

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

using Flyway with 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")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

running PostgreSQL container for integration tests

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"
Comment on lines +39 to +43
Copy link
Contributor Author

Choose a reason for hiding this comment

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

pull in DB parameters from secrets (prepared before during DB bootstrap with TF)


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
Copy link
Contributor Author

Choose a reason for hiding this comment

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

provide a postgreSQL for integration tests with Flyway enabled
(another will be for JPA repository tests without Flyway)


@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() }
Comment on lines +10 to +11
Copy link
Contributor Author

Choose a reason for hiding this comment

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

using two different postgreSQL containers for different integration tests (with or without Flyway)


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
Copy link
Contributor Author

Choose a reason for hiding this comment

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

for integration tests with Flyway

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
Copy link
Contributor Author

Choose a reason for hiding this comment

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

for local run with DB

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
Copy link
Contributor Author

Choose a reason for hiding this comment

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

enable Flyway by default

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
Loading