Skip to content

Commit 41b4e77

Browse files
committed
refactor: further simplifications and improvements
1 parent d5484cc commit 41b4e77

7 files changed

Lines changed: 34 additions & 40 deletions

File tree

src/main/kotlin/io/sdkman/broker/adapter/primary/rest/HealthResponseHandlers.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import io.ktor.server.response.respond
66
import io.sdkman.broker.application.service.DatabaseHealthStatus
77
import io.sdkman.broker.application.service.HealthCheckError
88
import io.sdkman.broker.application.service.HealthStatus
9+
import kotlinx.serialization.Serializable
910

1011
enum class DatabaseName(val displayName: String) {
1112
MONGODB("MongoDB"),
@@ -33,7 +34,8 @@ suspend fun ApplicationCall.handleDatabaseHealthStatus(databaseStatus: DatabaseH
3334
val overallHealthy = databaseStatus.mongodb == HealthStatus.UP && databaseStatus.postgres == HealthStatus.UP
3435
val statusCode = if (overallHealthy) HttpStatusCode.OK else HttpStatusCode.ServiceUnavailable
3536

36-
respond(statusCode, DetailedHealthResponse(mongoDbStatus, postgresStatus))
37+
val reason = "Service is ${if (overallHealthy) "healthy" else "not healthy"}"
38+
respond(statusCode, DetailedHealthResponse(mongoDbStatus, postgresStatus, reason))
3739
}
3840

3941
suspend fun ApplicationCall.handleHealthError(error: HealthCheckError) {
@@ -110,3 +112,6 @@ private fun createDatabaseErrorResponse(
110112
)
111113
}
112114
}
115+
116+
@Serializable
117+
data class DetailedHealthResponse(val mongodb: String, val postgres: String, val reason: String)

src/main/kotlin/io/sdkman/broker/adapter/primary/rest/MetaRoutes.kt

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import io.ktor.server.response.respond
77
import io.ktor.server.routing.get
88
import io.ktor.server.routing.routing
99
import io.sdkman.broker.application.service.MetaHealthService
10-
import io.sdkman.broker.application.service.MetaError
1110
import io.sdkman.broker.application.service.MetaReleaseService
1211
import kotlinx.serialization.Serializable
1312

@@ -30,7 +29,7 @@ fun Application.metaRoutes(
3029
{ error ->
3130
call.respond(
3231
HttpStatusCode.InternalServerError,
33-
ReleaseErrorResponse("Error retrieving release: ${error.cause.message}")
32+
ReleaseErrorResponse("Error retrieving release: ${error.message}")
3433
)
3534
},
3635
{ release ->
@@ -41,17 +40,8 @@ fun Application.metaRoutes(
4140
}
4241
}
4342

44-
@Serializable
45-
data class DetailedHealthResponse(val mongodb: String, val postgres: String, val reason: String? = null)
46-
4743
@Serializable
4844
data class ReleaseResponse(val release: String)
4945

5046
@Serializable
5147
data class ReleaseErrorResponse(val error: String)
52-
53-
private val MetaError.cause: Throwable
54-
get() =
55-
when (this) {
56-
is MetaError.MetaFileError -> cause
57-
}

src/main/kotlin/io/sdkman/broker/application/service/MetaReleaseService.kt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import arrow.core.toOption
99
import java.util.Properties
1010

1111
interface MetaReleaseService {
12-
fun getReleaseVersion(): Either<MetaError, String>
12+
fun getReleaseVersion(): Either<MetaReleaseError, String>
1313
}
1414

1515
class MetaReleaseServiceImpl(
@@ -20,11 +20,11 @@ class MetaReleaseServiceImpl(
2020
private const val RELEASE_KEY = "release"
2121
}
2222

23-
override fun getReleaseVersion(): Either<MetaError, String> =
23+
override fun getReleaseVersion(): Either<MetaReleaseError, String> =
2424
loadPropertiesFile()
2525
.flatMap { properties -> getReleaseFromProperties(properties) }
2626

27-
private fun loadPropertiesFile(): Either<MetaError, Properties> =
27+
private fun loadPropertiesFile(): Either<MetaReleaseError, Properties> =
2828
Either.catch {
2929
val properties = Properties()
3030
classLoader.getResourceAsStream(RELEASE_PROPERTIES).toOption()
@@ -35,18 +35,19 @@ class MetaReleaseServiceImpl(
3535
properties
3636
}
3737
)
38-
}.mapLeft { MetaError.MetaFileError(it) }
38+
}.mapLeft { MetaReleaseError(it) }
3939

40-
private fun getReleaseFromProperties(properties: Properties): Either<MetaError, String> =
40+
private fun getReleaseFromProperties(properties: Properties): Either<MetaReleaseError, String> =
4141
properties.getProperty(RELEASE_KEY).toOption()
4242
.filter { it.isNotBlank() }
4343
.map { it.right() }
4444
.getOrElse {
45-
MetaError.MetaFileError(IllegalStateException("Release property not found in $RELEASE_PROPERTIES"))
45+
MetaReleaseError(IllegalStateException("Release property not found in $RELEASE_PROPERTIES"))
4646
.left()
4747
}
4848
}
4949

50-
sealed class MetaError {
51-
data class MetaFileError(val cause: Throwable) : MetaError()
50+
class MetaReleaseError(e: Throwable) : Throwable(e) {
51+
override val message: String
52+
get() = super.message ?: "An error occurred while retrieving the release version."
5253
}

src/test/kotlin/io/sdkman/broker/acceptance/MetaReleaseEndpointAcceptanceSpec.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import io.ktor.client.call.body
88
import io.ktor.client.request.get
99
import io.ktor.http.HttpStatusCode
1010
import io.ktor.server.testing.testApplication
11-
import io.sdkman.broker.application.service.MetaError
11+
import io.sdkman.broker.application.service.MetaReleaseError
1212
import io.sdkman.broker.application.service.MetaReleaseService
1313
import io.sdkman.broker.support.TestDependencyInjection
1414
import io.sdkman.broker.support.configureAppForTesting
@@ -47,8 +47,8 @@ class MetaReleaseEndpointAcceptanceSpec : ShouldSpec({
4747
// Using a service that can't find the file
4848
val mockService =
4949
object : MetaReleaseService {
50-
override fun getReleaseVersion(): Either<MetaError, String> =
51-
MetaError.MetaFileError(
50+
override fun getReleaseVersion(): Either<MetaReleaseError, String> =
51+
MetaReleaseError(
5252
IllegalStateException("Could not load release.properties")
5353
).left()
5454
}

src/test/kotlin/io/sdkman/broker/application/service/ReleaseServiceSpec.kt renamed to src/test/kotlin/io/sdkman/broker/application/service/MetaReleaseServiceSpec.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import io.sdkman.broker.support.beLeftAnd
99
import io.sdkman.broker.support.shouldBeRight
1010
import java.io.ByteArrayInputStream
1111

12-
class ReleaseServiceSpec : ShouldSpec({
12+
class MetaReleaseServiceSpec : ShouldSpec({
1313

1414
should("successfully return release when properties file exists with valid release") {
1515
// given: a mocked classloader that returns a valid properties file
@@ -47,9 +47,9 @@ class ReleaseServiceSpec : ShouldSpec({
4747

4848
// then: release file error is returned
4949
result should
50-
beLeftAnd<MetaError, String> { error ->
51-
error.shouldBeInstanceOf<MetaError.MetaFileError>()
52-
error.cause.message?.contains("Release property not found") ?: false
50+
beLeftAnd { error ->
51+
error.shouldBeInstanceOf<MetaReleaseError>()
52+
error.message.contains("Release property not found")
5353
}
5454
}
5555

@@ -70,9 +70,9 @@ class ReleaseServiceSpec : ShouldSpec({
7070

7171
// then: release file error is returned
7272
result should
73-
beLeftAnd<MetaError, String> { error ->
74-
error.shouldBeInstanceOf<MetaError.MetaFileError>()
75-
error.cause.message?.contains("Release property not found") ?: false
73+
beLeftAnd<MetaReleaseError, String> { error ->
74+
error.shouldBeInstanceOf<MetaReleaseError>()
75+
error.message.contains("Release property not found")
7676
}
7777
}
7878

@@ -91,9 +91,9 @@ class ReleaseServiceSpec : ShouldSpec({
9191

9292
// then: release file error is returned
9393
result should
94-
beLeftAnd<MetaError, String> { error ->
95-
error.shouldBeInstanceOf<MetaError.MetaFileError>()
96-
error.cause.message?.contains("Could not load") ?: false
94+
beLeftAnd { error ->
95+
error.shouldBeInstanceOf<MetaReleaseError>()
96+
error.message.contains("Could not load")
9797
}
9898
}
9999
})

src/test/kotlin/io/sdkman/broker/domain/HealthServiceSpec.kt renamed to src/test/kotlin/io/sdkman/broker/domain/MetaHealthServiceSpec.kt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@ package io.sdkman.broker.domain
33
import arrow.core.Either
44
import arrow.core.None
55
import arrow.core.Some
6+
import arrow.core.getOrElse
67
import arrow.core.left
78
import arrow.core.right
89
import io.kotest.core.spec.style.ShouldSpec
910
import io.mockk.every
1011
import io.mockk.mockk
1112
import io.sdkman.broker.application.service.DatabaseHealthStatus
1213
import io.sdkman.broker.application.service.HealthCheckError
13-
import io.sdkman.broker.application.service.MetaHealthServiceImpl
1414
import io.sdkman.broker.application.service.HealthStatus
15+
import io.sdkman.broker.application.service.MetaHealthServiceImpl
1516
import io.sdkman.broker.domain.model.Application
1617
import io.sdkman.broker.domain.repository.ApplicationRepository
1718
import io.sdkman.broker.domain.repository.DatabaseFailure
@@ -21,12 +22,10 @@ import io.sdkman.broker.domain.repository.RepositoryError
2122
import io.sdkman.broker.support.shouldBeLeftAnd
2223
import io.sdkman.broker.support.shouldBeRight
2324

24-
class HealthServiceSpec : ShouldSpec({
25+
class MetaHealthServiceSpec : ShouldSpec({
2526
val applicationOK =
26-
Application.of("OK").fold(
27-
{ error -> throw IllegalStateException("Failed to create test application: $error") },
28-
{ it }
29-
)
27+
Application.of("OK")
28+
.getOrElse { throw IllegalStateException("Failed to create test application: $it") }
3029

3130
context("HealthServiceImpl with dual database checks") {
3231

src/test/kotlin/io/sdkman/broker/support/TestDependencyInjection.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import javax.sql.DataSource
1414
// Dependency injection for tests
1515
// Uses the shared MongoTestListener and PostgresTestListener to provide consistent database access across all tests
1616
object TestDependencyInjection {
17-
1817
// Use the database from MongoTestListener directly
1918
val database by lazy { MongoTestListener.database }
2019

0 commit comments

Comments
 (0)