This commit is contained in:
2026-04-27 23:30:22 +09:30
parent 9e966f1b1a
commit 648d67cb29
8 changed files with 451 additions and 172 deletions
+66 -54
View File
@@ -1,14 +1,21 @@
import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.jooq.meta.jaxb.Property
import org.gradle.jvm.toolchain.JavaLanguageVersion
import java.sql.DriverManager
plugins {
id("org.springframework.boot") version "3.2.5"
id("io.spring.dependency-management") version "1.1.4"
id("org.openapi.generator") version "7.3.0"
id("org.openapi.generator") version "7.4.0"
id("nu.studer.jooq") version "9.0"
id("application")
id("java")
}
val postgresqlVersion: String by project
val flywayVersion: String by project
val jooqVersion: String by project
val logbackVersion: String by project
group = "net.moustos"
version = "0.1.0"
@@ -17,48 +24,38 @@ repositories {
}
dependencies {
// Spring Boot
implementation("org.springframework.boot:spring-boot-starter-web:3.2.5")
implementation("org.springframework.boot:spring-boot-starter-data-jpa:3.2.5")
implementation("org.springframework.boot:spring-boot-starter-security:3.2.5")
implementation("org.springframework.boot:spring-boot-starter-validation:3.2.5")
developmentOnly("org.springframework.boot:spring-boot-devtools:3.2.5")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-validation")
developmentOnly("org.springframework.boot:spring-boot-devtools")
// Database
implementation("org.postgresql:postgresql:42.7.3")
implementation("org.flywaydb:flyway-core:9.22.3")
implementation("org.flywaydb:flyway-database-postgresql:9.22.3")
implementation("org.postgresql:postgresql:$postgresqlVersion")
implementation("org.flywaydb:flyway-core:$flywayVersion")
// jOOQ
implementation("org.jooq:jooq:3.19.8")
implementation("org.jooq:jooq-meta:3.19.8")
implementation("org.jooq:jooq-codegen:3.19.8")
jooqGenerator("org.postgresql:postgresql:42.7.3")
implementation("org.jooq:jooq:$jooqVersion")
implementation("org.jooq:jooq-meta:$jooqVersion")
implementation("org.jooq:jooq-codegen:$jooqVersion")
jooqGenerator("org.postgresql:postgresql:$postgresqlVersion")
// Security & JWT
implementation("com.auth0:java-jwt:4.4.0")
implementation("at.fageorgetown:jbcrypt:0.9.1")
implementation("org.springframework.security:spring-security-crypto:6.2.3")
// OpenAPI & Swagger
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.4.0")
implementation("jakarta.annotation:jakarta.annotation-api:2.1.1")
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.1")
// Logging
implementation("ch.qos.logback:logback-core:1.5.0")
implementation("ch.qos.logback:logback-classic:1.5.0")
implementation("ch.qos.logback:logback-core:$logbackVersion")
implementation("ch.qos.logback:logback-classic:$logbackVersion")
implementation("net.logstash.logback:logstash-logback-encoder:7.4")
// Utilities
implementation("org.projectlombok:lombok:1.18.30")
compileOnly("org.projectlombok:lombok:1.18.30")
annotationProcessor("org.projectlombok:lombok:1.18.30")
implementation("org.apache.commons:commons-lang3:3.14.0")
implementation("com.google.guava:guava:33.1.0-jre")
// Testing
testImplementation("org.springframework.boot:spring-boot-starter-test:3.2.5")
testImplementation("org.springframework.security:spring-security-test:6.2.3")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.security:spring-security-test")
testImplementation("org.testcontainers:testcontainers:1.19.7")
testImplementation("org.testcontainers:postgresql:1.19.7")
testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
@@ -68,8 +65,9 @@ dependencies {
}
java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
toolchain {
languageVersion.set(JavaLanguageVersion.of(21))
}
}
application {
@@ -80,7 +78,6 @@ springBoot {
buildInfo()
}
// OpenAPI Generator Configuration
openApiGenerate {
generatorName.set("spring")
inputSpec.set("$projectDir/openapi/api.yaml")
@@ -101,16 +98,15 @@ openApiGenerate {
))
}
// jOOQ Configuration
jooq {
configurations {
create("main") {
jooqConfiguration.apply {
jdbc.apply {
driver = "org.postgresql.Driver"
url = "jdbc:postgresql://localhost:5432/mtgsearch"
user = "postgres"
password = "postgres"
url = project.property("db.url") as String
user = project.property("db.user") as String
password = project.property("db.password") as String
}
generator.apply {
name = "org.jooq.codegen.JavaGenerator"
@@ -128,35 +124,51 @@ jooq {
}
}
tasks.register("generateJooqCode") {
dependsOn("jooqCodegen")
}
sourceSets {
main {
java {
srcDirs(
"src/main/java",
"$buildDir/generated/src/main/java",
"$buildDir/generated/jooq"
)
}
fun isPostgresAvailable(): Boolean {
return try {
DriverManager.setLoginTimeout(2)
DriverManager.getConnection(project.property("db.url") as String, project.property("db.user") as String, project.property("db.password") as String).use { true }
} catch (ex: Exception) {
logger.warn("PostgreSQL is unavailable at configured DB; skipping jOOQ code generation.")
false
}
}
tasks.compileJava {
dependsOn("openApiGenerate", "generateJooqCode")
tasks.named("generateJooq") {
onlyIf {
isPostgresAvailable()
}
doFirst {
logger.lifecycle("Starting jOOQ code generation...")
}
doLast {
logger.lifecycle("Finished jOOQ task.")
}
}
tasks.test {
tasks.named("compileJava") {
dependsOn("openApiGenerate")
}
sourceSets["main"].java {
srcDir("$buildDir/generated/src/main/java")
srcDir("$buildDir/generated/jooq")
}
tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
options.compilerArgs.add("-parameters")
}
tasks.withType<Test> {
useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
events(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
showStandardStreams = false
}
}
tasks.named("build") {
dependsOn("openApiGenerate", "generateJooqCode")
dependsOn("openApiGenerate")
}
@@ -27,14 +27,16 @@ public class UserDetailsServiceImpl implements UserDetailsService {
var user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found: " + username));
boolean active = Boolean.TRUE.equals(user.getActive());
return User.builder()
.username(user.getUsername())
.password(user.getPassword())
.authorities(Collections.singleton(new SimpleGrantedAuthority("ROLE_USER")))
.accountNonLocked(user.getActive())
.accountNonExpired(true)
.credentialsNonExpired(true)
.enabled(user.getActive())
.accountLocked(!active)
.accountExpired(false)
.credentialsExpired(false)
.disabled(!active)
.build();
}
}
+19 -8
View File
@@ -1,14 +1,14 @@
spring:
application:
name: mtg-search
version: 0.1.0
name: ${app.name:mtg-search}
version: ${app.version:0.1.0}
datasource:
url: jdbc:postgresql://localhost:5432/mtgsearch
username: postgres
password: postgres
url: ${db.url:jdbc:postgresql://localhost:5432/mtgsearch}
username: ${db.user:postgres}
password: ${db.password:postgres}
hikari:
maximum-pool-size: 10
maximum-pool-size: ${db.maxPoolSize:10}
minimum-idle: 2
idle-timeout: 300000
max-lifetime: 1200000
@@ -37,10 +37,21 @@ spring:
max-file-size: 10MB
max-request-size: 10MB
server:
port: ${server.port:8080}
servlet:
context-path: ${server.servlet.contextPath:/}
app:
jwt:
secret: ${JWT_SECRET:your-secret-key-change-in-production}
expiration: ${JWT_EXPIRATION:86400}
secret: ${jwt.secret:your-secret-key-change-in-production}
expiration: ${jwt.expiration:86400}
logging:
level:
root: ${log.level:INFO}
file:
name: ${log.dir:logs}/app.log
springdoc:
api-docs: