diff --git a/.editorconfig b/.editorconfig index 063e4a8..45d4fa6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,3 +1,5 @@ [*.{kt,kts}] ij_kotlin_allow_trailing_comma = false ij_kotlin_allow_trailing_comma_on_call_site = false +ktlint_code_style = intellij_idea +ktlint_standard_no-unused-imports = enabled \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index b90465a..fea8f1b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,17 +1,18 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - id("io.spring.dependency-management") version "1.1.4" - id("org.jmailen.kotlinter") version "4.1.0" + id("io.spring.dependency-management") version "1.1.7" + id("org.jmailen.kotlinter") version "5.5.0" id("maven-publish") id("java-library") - kotlin("jvm") version "1.9.21" - kotlin("plugin.spring") version "1.9.21" + kotlin("jvm") version "2.4.0" + kotlin("plugin.spring") version "2.4.0" id("net.thebugmc.gradle.sonatype-central-portal-publisher") version "1.2.4" } group = "com.valensas" -java.sourceCompatibility = JavaVersion.VERSION_17 +java.sourceCompatibility = JavaVersion.VERSION_21 repositories { mavenCentral() @@ -23,23 +24,26 @@ dependencies { compileOnly("org.springframework.boot:spring-boot-starter-webflux") implementation("org.springframework.data:spring-data-commons") implementation("org.jetbrains.kotlin:kotlin-reflect") - implementation("com.valensas:exception:2.4.2") + implementation("com.valensas:exception:2.5.0") compileOnly("io.micrometer:micrometer-core") - api("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:1.7.3") + api("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:1.11.0") testImplementation("org.springframework.boot:spring-boot-starter-webflux") testImplementation("org.springframework.boot:spring-boot-starter-test") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") } tasks.withType { - kotlinOptions { - freeCompilerArgs = listOf("-Xjsr305=strict") - jvmTarget = "17" + compilerOptions { + freeCompilerArgs.addAll("-Xjsr305=strict") + jvmTarget = JvmTarget.JVM_21 } } +extra["kotlin.version"] = "2.4.0" + dependencyManagement { imports { - mavenBom("org.springframework.boot:spring-boot-dependencies:3.2.0") + mavenBom("org.springframework.boot:spring-boot-dependencies:3.5.15") } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd49..e644113 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1af9e09..5dd3c01 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a4..b740cf1 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. diff --git a/gradlew.bat b/gradlew.bat index 6689b85..7101f8e 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/src/main/kotlin/com/valensas/util/autoconfigure/ClientIpExtractorConfig.kt b/src/main/kotlin/com/valensas/util/autoconfigure/ClientIpExtractorConfig.kt index 18520f1..5cea4b7 100644 --- a/src/main/kotlin/com/valensas/util/autoconfigure/ClientIpExtractorConfig.kt +++ b/src/main/kotlin/com/valensas/util/autoconfigure/ClientIpExtractorConfig.kt @@ -22,11 +22,17 @@ class ClientIpExtractorConfig( serverWebExchange: ServerWebExchange, webFilterChain: WebFilterChain ): Mono { - if (serverWebExchange.request.path.toString().startsWith(managementBasePath)) return webFilterChain.filter(serverWebExchange) + if (serverWebExchange.request.path + .toString() + .startsWith(managementBasePath) + ) { + return webFilterChain.filter(serverWebExchange) + } val clientIp = serverWebExchange.request.headers.getFirst("x-client-ip") if (clientIp == null) logger.trace("Failed to fetch client ip from header x-client-ip") - return webFilterChain.filter(serverWebExchange) + return webFilterChain + .filter(serverWebExchange) .contextWrite { context: Context -> clientIp?.let { context.put("ClientIp", clientIp) } ?: context } diff --git a/src/main/kotlin/com/valensas/util/autoconfigure/JacksonConfiguration.kt b/src/main/kotlin/com/valensas/util/autoconfigure/JacksonConfiguration.kt index 5ebbbc1..45ab16b 100644 --- a/src/main/kotlin/com/valensas/util/autoconfigure/JacksonConfiguration.kt +++ b/src/main/kotlin/com/valensas/util/autoconfigure/JacksonConfiguration.kt @@ -19,15 +19,13 @@ class JacksonConfiguration { fun jackson2ObjectMapperBuilder( @Value("\${valensas.server.bigdecimal.scale:8}") scale: Int - ): Jackson2ObjectMapperBuilder = - Jackson2ObjectMapperBuilder() - .deserializerByType(BigDecimal::class.java, BigDecimalMoneyDeserializer(scale)) - .serializerByType(Instant::class.java, InstantSerializer()) - .createXmlMapper(false) - .featuresToDisable( - SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, - SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, - SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS - ) - .featuresToEnable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) + ): Jackson2ObjectMapperBuilder = Jackson2ObjectMapperBuilder() + .deserializerByType(BigDecimal::class.java, BigDecimalMoneyDeserializer(scale)) + .serializerByType(Instant::class.java, InstantSerializer()) + .createXmlMapper(false) + .featuresToDisable( + SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, + SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, + SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS + ).featuresToEnable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) } diff --git a/src/main/kotlin/com/valensas/util/exception/Exceptions.kt b/src/main/kotlin/com/valensas/util/exception/Exceptions.kt index 230f6fc..94775e2 100644 --- a/src/main/kotlin/com/valensas/util/exception/Exceptions.kt +++ b/src/main/kotlin/com/valensas/util/exception/Exceptions.kt @@ -2,17 +2,22 @@ package com.valensas.util.exception import com.valensas.exception.BadRequest -class InvalidPageSize(max: Int) : BadRequest( +class InvalidPageSize( + max: Int +) : BadRequest( "Page size must be between 0 and $max", "INVALID_PAGE_SIZE" ) -class InvalidPageNumber : BadRequest( - "Page number must not be less than zero", - "INVALID_PAGE_NUMBER" -) +class InvalidPageNumber : + BadRequest( + "Page number must not be less than zero", + "INVALID_PAGE_NUMBER" + ) -class InvalidSortDirection(direction: String) : BadRequest( +class InvalidSortDirection( + direction: String +) : BadRequest( "Invalid value:$direction, has to be either 'desc' or 'asc' (case insensitive)", "INVALID_SORT_DIRECTION" ) diff --git a/src/main/kotlin/com/valensas/util/extension/CollectionExtension.kt b/src/main/kotlin/com/valensas/util/extension/CollectionExtension.kt index a19fc82..3fb00aa 100644 --- a/src/main/kotlin/com/valensas/util/extension/CollectionExtension.kt +++ b/src/main/kotlin/com/valensas/util/extension/CollectionExtension.kt @@ -16,7 +16,11 @@ suspend fun Collection.parallelForEach(mapper: suspend (T) -> Unit) { suspend fun Collection.parallelMap(mapper: suspend (T) -> U): List { if (this.isEmpty()) return emptyList() - return Flux.fromIterable(this).flatMap { mono { mapper(it) } }.collectList().awaitSingle() + return Flux + .fromIterable(this) + .flatMap { mono { mapper(it) } } + .collectList() + .awaitSingle() } suspend fun Flux.parallelForEach(function: suspend (T) -> Unit) { diff --git a/src/main/kotlin/com/valensas/util/pagination/Pageable.kt b/src/main/kotlin/com/valensas/util/pagination/Pageable.kt index 8708926..aecec2d 100644 --- a/src/main/kotlin/com/valensas/util/pagination/Pageable.kt +++ b/src/main/kotlin/com/valensas/util/pagination/Pageable.kt @@ -39,7 +39,8 @@ fun Pageable.toJavaPageable(): PageRequest { } private fun parseParameterIntoSort(sort: String?): Sort { - return sort?.replace(" ", "") + return sort + ?.replace(" ", "") ?.split(";") ?.mapNotNull { part -> val element = part.split(",") @@ -58,13 +59,12 @@ private fun parseParameterIntoSort(sort: String?): Sort { } else { if (direction != null) Sort.Order(direction, property) else Sort.Order.by(property) } - } - ?.takeIf { it.isNotEmpty() } + }?.takeIf { it.isNotEmpty() } ?.let { Sort.by(it) } ?: Sort.unsorted() } -fun UriBuilder.pageable(pageable: Pageable) = - this.queryParam("page", pageable.page) - .queryParam("sort", pageable.sort) - .queryParam("size", pageable.size) +fun UriBuilder.pageable(pageable: Pageable) = this + .queryParam("page", pageable.page) + .queryParam("sort", pageable.sort) + .queryParam("size", pageable.size) diff --git a/src/main/kotlin/com/valensas/util/serializer/BigDecimalMoneyDeserializer.kt b/src/main/kotlin/com/valensas/util/serializer/BigDecimalMoneyDeserializer.kt index 03c93af..7ff1876 100644 --- a/src/main/kotlin/com/valensas/util/serializer/BigDecimalMoneyDeserializer.kt +++ b/src/main/kotlin/com/valensas/util/serializer/BigDecimalMoneyDeserializer.kt @@ -15,7 +15,5 @@ class BigDecimalMoneyDeserializer( override fun deserialize( jp: JsonParser, ctx: DeserializationContext - ): BigDecimal { - return BigDecimal(jp.valueAsString).setScale(scale, RoundingMode.HALF_UP) - } + ): BigDecimal = BigDecimal(jp.valueAsString).setScale(scale, RoundingMode.HALF_UP) }