feat(deployment): 배포 식별자 엔드포인트를 추가한다
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
package kr.co.vividnext.sodalive.deployment
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint
|
||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
@Endpoint(id = "deployment")
|
||||
class DeploymentEndpoint(
|
||||
@Value("\${deployment.artifact-version}")
|
||||
private val artifactVersion: String,
|
||||
@Value("\${deployment.config-commit}")
|
||||
private val configCommit: String
|
||||
) {
|
||||
@ReadOperation
|
||||
fun deployment(): Map<String, String> = mapOf(
|
||||
"application_artifact_version" to artifactVersion,
|
||||
"config_commit" to configCommit
|
||||
)
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package kr.co.vividnext.sodalive.deployment
|
||||
|
||||
import kr.co.vividnext.sodalive.support.EmbeddedRedisInitializer
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate
|
||||
import org.springframework.boot.test.web.server.LocalManagementPort
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.test.annotation.DirtiesContext
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
|
||||
@SpringBootTest(
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = [
|
||||
"management.server.port=0",
|
||||
"deployment.artifact-version=1.2.3-20260914",
|
||||
"deployment.config-commit=1a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d",
|
||||
"spring.datasource.url=jdbc:h2:mem:deployment-endpoint-injected-integration;" +
|
||||
"MODE=MySQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=VALUE;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"
|
||||
]
|
||||
)
|
||||
@ContextConfiguration(initializers = [EmbeddedRedisInitializer::class])
|
||||
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
|
||||
class DeploymentEndpointInjectedValueIntegrationTest @Autowired constructor(
|
||||
private val restTemplate: TestRestTemplate
|
||||
) {
|
||||
@LocalManagementPort
|
||||
private var managementPort: Int = 0
|
||||
|
||||
@Test
|
||||
@DisplayName("배포 식별자가 주입되면 /actuator/deployment는 주입된 값을 반환한다")
|
||||
fun shouldReturnInjectedDeploymentIdentity() {
|
||||
val response = restTemplate.getForEntity(
|
||||
"http://localhost:$managementPort/actuator/deployment",
|
||||
Map::class.java
|
||||
)
|
||||
|
||||
assertEquals(HttpStatus.OK, response.statusCode)
|
||||
assertEquals(
|
||||
mapOf(
|
||||
"application_artifact_version" to "1.2.3-20260914",
|
||||
"config_commit" to "1a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d"
|
||||
),
|
||||
response.body
|
||||
)
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
package kr.co.vividnext.sodalive.deployment
|
||||
|
||||
import kr.co.vividnext.sodalive.support.EmbeddedRedisInitializer
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Assertions.assertNotEquals
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate
|
||||
import org.springframework.boot.test.web.server.LocalManagementPort
|
||||
import org.springframework.boot.test.web.server.LocalServerPort
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.test.annotation.DirtiesContext
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
|
||||
@SpringBootTest(
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = [
|
||||
"management.server.port=0",
|
||||
"spring.datasource.url=jdbc:h2:mem:deployment-endpoint-integration;" +
|
||||
"MODE=MySQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=VALUE;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"
|
||||
]
|
||||
)
|
||||
@ContextConfiguration(initializers = [EmbeddedRedisInitializer::class])
|
||||
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
|
||||
class DeploymentEndpointIntegrationTest @Autowired constructor(
|
||||
private val restTemplate: TestRestTemplate
|
||||
) {
|
||||
@LocalServerPort
|
||||
private var serverPort: Int = 0
|
||||
|
||||
@LocalManagementPort
|
||||
private var managementPort: Int = 0
|
||||
|
||||
@Test
|
||||
@DisplayName("애플리케이션 포트의 /readyz는 인증 없이 200을 반환한다")
|
||||
fun shouldReturnOkWhenReadyzIsCalledOnServerPort() {
|
||||
val response = restTemplate.getForEntity("http://localhost:$serverPort/readyz", String::class.java)
|
||||
|
||||
assertEquals(HttpStatus.OK, response.statusCode)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("management 포트의 /actuator/health/readiness는 인증 없이 200을 반환한다")
|
||||
fun shouldReturnOkWhenReadinessProbeIsCalledOnManagementPort() {
|
||||
val response = restTemplate.getForEntity(
|
||||
"http://localhost:$managementPort/actuator/health/readiness",
|
||||
String::class.java
|
||||
)
|
||||
|
||||
assertEquals(HttpStatus.OK, response.statusCode)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("환경변수가 없으면 /actuator/deployment는 기본 배포 식별자를 snake_case로 반환한다")
|
||||
fun shouldReturnDefaultDeploymentIdentityWhenEnvironmentVariablesAreNotProvided() {
|
||||
val response = restTemplate.getForEntity(
|
||||
"http://localhost:$managementPort/actuator/deployment",
|
||||
Map::class.java
|
||||
)
|
||||
|
||||
assertEquals(HttpStatus.OK, response.statusCode)
|
||||
assertEquals(
|
||||
mapOf(
|
||||
"application_artifact_version" to "local",
|
||||
"config_commit" to "0000000000000000000000000000000000000000"
|
||||
),
|
||||
response.body
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("애플리케이션 포트에서는 /actuator/deployment에 접근할 수 없다")
|
||||
fun shouldNotExposeDeploymentEndpointOnServerPort() {
|
||||
val response = restTemplate.getForEntity(
|
||||
"http://localhost:$serverPort/actuator/deployment",
|
||||
String::class.java
|
||||
)
|
||||
|
||||
assertNotEquals(HttpStatus.OK, response.statusCode)
|
||||
assertFalse(response.body?.contains("application_artifact_version") ?: false)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user