Skip to content

Commit

Permalink
Add ability to customize name of dataSource bean and databaseUrl (#523)
Browse files Browse the repository at this point in the history
* Add ability to customize name of dataSource bean and databaseUrl

* Fix tests

* Add new demo app
  • Loading branch information
mfvanek authored Dec 5, 2024
1 parent 395626b commit ca3c9ea
Show file tree
Hide file tree
Showing 23 changed files with 499 additions and 66 deletions.
4 changes: 4 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ dependencies {
implementation("info.solidsoft.gradle.pitest:gradle-pitest-plugin:1.15.0")
implementation("org.gradle:test-retry-gradle-plugin:1.6.0")
implementation(libs.forbiddenapis)
implementation(libs.detekt)
val kotlinVersion = "1.9.23"
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
implementation("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import io.gitlab.arturbosch.detekt.Detekt
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
id("org.jetbrains.kotlin.jvm")
id("org.jetbrains.kotlin.plugin.spring")
id("pg-index-health.java-compilation")
id("io.gitlab.arturbosch.detekt")
id("pg-index-health.forbidden-apis")
}

private val versionCatalog = extensions.getByType<VersionCatalogsExtension>().named("libs")

dependencies {
implementation("org.jetbrains.kotlin:kotlin-reflect")

versionCatalog.findLibrary("detekt-formatting").ifPresent {
detektPlugins(it)
}
versionCatalog.findLibrary("detekt-libraries").ifPresent {
detektPlugins(it)
}
}

tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs += "-Xjsr305=strict"
jvmTarget = "11"
}
}

detekt {
toolVersion = versionCatalog.findVersion("detekt").get().requiredVersion
config.setFrom(file("${rootDir}/config/detekt/detekt.yml"))
buildUponDefaultConfig = true
}

tasks.withType<Detekt>().configureEach {
reports {
xml.required.set(true)
html.required.set(true)
}
}
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ detekt-formatting = { group = "io.gitlab.arturbosch.detekt", name = "detekt-form
detekt-libraries = { group = "io.gitlab.arturbosch.detekt", name = "detekt-rules-libraries", version.ref = "detekt" }
testcontainers-bom = { group = "org.testcontainers", name = "testcontainers-bom", version.ref = "testcontainers" }
forbiddenapis = { group = "de.thetaphi", name = "forbiddenapis", version.ref = "forbiddenapis" }
detekt = { group = "io.gitlab.arturbosch.detekt", name = "detekt-gradle-plugin", version.ref = "detekt" }

[plugins]
spring-boot-gradlePlugin = { id = "org.springframework.boot", version.ref = "spring-boot" }
spring-dependency-management = { id = "io.spring.dependency-management", version = "1.1.6" }
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
2 changes: 2 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ include("pg-index-health-logger")
include("pg-index-health-core")
include("spring-boot-integration:postgres-tc-url-demo-app")
findProject(":spring-boot-integration:postgres-tc-url-demo-app")?.name = "postgres-tc-url-demo-app"
include("spring-boot-integration:kotlin-custom-ds-demo-app")
findProject(":spring-boot-integration:kotlin-custom-ds-demo-app")?.name = "kotlin-custom-ds-demo-app"
23 changes: 23 additions & 0 deletions spring-boot-integration/kotlin-custom-ds-demo-app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
plugins {
id("pg-index-health.kotlin-application")
alias(libs.plugins.spring.boot.gradlePlugin)
alias(libs.plugins.spring.dependency.management)
}

ext["commons-lang3.version"] = libs.versions.commons.lang3.get()
ext["assertj.version"] = libs.versions.assertj.get()
// ext["mockito.version"] = libs.versions.mockito.get()
ext["junit-jupiter.version"] = libs.versions.junit.get()

dependencies {
implementation(platform(libs.testcontainers.bom))
implementation("org.testcontainers:postgresql")
implementation(libs.spring.boot.starter.data.jdbc)
implementation("org.liquibase:liquibase-core:4.30.0")
implementation("com.github.blagerweij:liquibase-sessionlock:1.6.9")

runtimeOnly(libs.postgresql)

testImplementation(libs.spring.boot.starter.test)
testImplementation(project(":spring-boot-integration:pg-index-health-test-starter"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2019-2024. Ivan Vakhrushev and others.
* https://github.com/mfvanek/pg-index-health
*
* This file is a part of "pg-index-health" - a Java library for
* analyzing and maintaining indexes health in PostgreSQL databases.
*
* Licensed under the Apache License 2.0
*/

package io.github.mfvanek.pg.spring.postgres.kt.custom.ds

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class PostgresCustomDataSourceDemoApplication

fun main(args: Array<String>) {
runApplication<PostgresCustomDataSourceDemoApplication>(*args)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2019-2024. Ivan Vakhrushev and others.
* https://github.com/mfvanek/pg-index-health
*
* This file is a part of "pg-index-health" - a Java library for
* analyzing and maintaining indexes health in PostgreSQL databases.
*
* Licensed under the Apache License 2.0
*/

package io.github.mfvanek.pg.spring.postgres.kt.custom.ds.config

import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import org.springframework.boot.autoconfigure.liquibase.LiquibaseDataSource
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Primary

@Configuration
class DataSourceConfiguration {

@Configuration
@ConfigurationProperties("pgih.custom.datasource")
class CustomDataSourceProperties : HikariConfig()

@Bean
@Primary
@LiquibaseDataSource
fun pgihCustomDataSource(properties: CustomDataSourceProperties): HikariDataSource {
return HikariDataSource(properties)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
debug: false

spring:
main:
banner-mode: off
liquibase:
change-log: classpath:/changelog/changelog.yaml
default-schema: custom_ds_schema

pgih:
custom:
datasource:
jdbc-url: jdbc:tc:postgresql:17.2:///demo_for_pg_index_health_starter?TC_INITSCRIPT=init.sql
driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver
maximum-pool-size: 5
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
databaseChangeLog:
- include:
file: changelog/sql/warehouse.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--liquibase formatted sql

--changeset ivan.vakhrushev:2024.12.04:warehouse.table
create table if not exists warehouse
(
id bigint primary key generated always as identity,
name varchar(255) not null
);

comment on table warehouse is 'Information about the warehouses';
comment on column warehouse.id is 'Unique identifier of the warehouse';
comment on column warehouse.name is 'Human readable name of the warehouse';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
create schema if not exists custom_ds_schema;
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.github.mfvanek.pg.spring.postgres.kt.custom.ds

import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatCode
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.boot.test.system.CapturedOutput
import org.springframework.boot.test.system.OutputCaptureExtension

@ExtendWith(OutputCaptureExtension::class)
internal class PostgresCustomDataSourceDemoApplicationKtRunTest {

@Test
fun applicationShouldRun(output: CapturedOutput) {
assertThatCode { main(arrayOf("--spring.profiles.active=test")) }
.doesNotThrowAnyException()
assertThat(output.all)
.contains("Starting PostgresCustomDataSourceDemoApplicationKt using Java")
.contains("Container is started (JDBC URL: jdbc:postgresql://localhost:")
.contains("Started PostgresCustomDataSourceDemoApplicationKt in")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package io.github.mfvanek.pg.spring.postgres.kt.custom.ds

import com.zaxxer.hikari.HikariDataSource
import io.github.mfvanek.pg.connection.PgConnection
import io.github.mfvanek.pg.core.checks.common.DatabaseCheckOnHost
import io.github.mfvanek.pg.core.checks.common.Diagnostic
import io.github.mfvanek.pg.model.context.PgContext
import io.github.mfvanek.pg.model.dbobject.DbObject
import io.github.mfvanek.pg.model.predicates.SkipLiquibaseTablesPredicate
import io.github.mfvanek.pg.model.table.Table
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.context.ApplicationContext
import org.springframework.test.context.ActiveProfiles

@ActiveProfiles("test")
@SpringBootTest
internal class PostgresCustomDataSourceDemoApplicationKtTest {

@Autowired
private lateinit var applicationContext: ApplicationContext

@Autowired
private lateinit var checks: List<DatabaseCheckOnHost<out DbObject?>>

@Test
fun contextLoadsAndContainsPgIndexHealthBeans() {
assertThat(applicationContext.getBean("pgihCustomDataSource"))
.isInstanceOf(HikariDataSource::class.java)

assertThat(applicationContext.getBean("pgConnection"))
.isInstanceOf(PgConnection::class.java)
}

@Test
fun checksShouldWork() {
assertThat(checks)
.hasSameSizeAs(Diagnostic.entries.toTypedArray())

checks
.filter { it.isStatic }
.forEach { check ->
val ctx = PgContext.of("custom_ds_schema")
// Due to the use of spring.liquibase.default-schema, all names are resolved without a schema
val listAssert = assertThat(check.check(ctx, SkipLiquibaseTablesPredicate.ofPublic()))
.`as`(check.diagnostic.name)

when (check.diagnostic) {
Diagnostic.TABLES_NOT_LINKED_TO_OTHERS ->
listAssert
.hasSize(1)
.containsExactly(Table.of("warehouse", 0L))

else -> listAssert.isEmpty()
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pg.index.health.test:
datasource-bean-name: pgihCustomDataSource
datasource-url-property-name: pgih.custom.datasource.jdbc-url
34 changes: 1 addition & 33 deletions spring-boot-integration/kotlin-demo-app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
import io.gitlab.arturbosch.detekt.Detekt
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
val kotlinVersion = "1.9.23"
kotlin("jvm") version kotlinVersion
kotlin("plugin.spring") version kotlinVersion
id("pg-index-health.java-compilation")
id("pg-index-health.kotlin-application")
alias(libs.plugins.spring.boot.gradlePlugin)
alias(libs.plugins.spring.dependency.management)
alias(libs.plugins.detekt)
id("pg-index-health.forbidden-apis")
}

ext["commons-lang3.version"] = libs.versions.commons.lang3.get()
Expand All @@ -18,7 +10,6 @@ ext["assertj.version"] = libs.versions.assertj.get()
ext["junit-jupiter.version"] = libs.versions.junit.get()

dependencies {
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation(project(":pg-index-health-testing"))
implementation(libs.spring.boot.starter.data.jdbc)
implementation(platform(libs.testcontainers.bom))
Expand All @@ -28,27 +19,4 @@ dependencies {

testImplementation(libs.spring.boot.starter.test)
testImplementation(project(":spring-boot-integration:pg-index-health-test-starter"))

detektPlugins(libs.detekt.formatting)
detektPlugins(libs.detekt.libraries)
}

tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs += "-Xjsr305=strict"
jvmTarget = "11"
}
}

detekt {
toolVersion = libs.versions.detekt.get()
config.setFrom(file("${rootDir}/config/detekt/detekt.yml"))
buildUponDefaultConfig = true
}

tasks.withType<Detekt>().configureEach {
reports {
xml.required.set(true)
html.required.set(true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import org.springframework.test.context.ActiveProfiles

@ActiveProfiles("test")
@SpringBootTest
class PostgresDemoApplicationKtTest {
internal class PostgresDemoApplicationKtTest {

@Autowired
private lateinit var applicationContext: ApplicationContext
Expand All @@ -37,7 +37,7 @@ class PostgresDemoApplicationKtTest {
private lateinit var checks: List<DatabaseCheckOnHost<out DbObject?>>

@Test
fun contextLoadsAndDoesNotContainPgIndexHealthBeans() {
fun contextLoadsAndContainsPgIndexHealthBeans() {
assertThat(applicationContext.getBean("dataSource"))
.isInstanceOf(HikariDataSource::class.java)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import org.springframework.boot.test.system.CapturedOutput
import org.springframework.boot.test.system.OutputCaptureExtension

@ExtendWith(OutputCaptureExtension::class)
class PostgresDemoApplicationRunKtTest {
internal class PostgresDemoApplicationRunKtTest {

@Test
fun applicationShouldRun(output: CapturedOutput) {
Expand Down
Loading

0 comments on commit ca3c9ea

Please sign in to comment.