From 4dc6b947b67e1d855c0fd93c746a13f6e97a3247 Mon Sep 17 00:00:00 2001 From: HyunSu1768 Date: Tue, 30 Jul 2024 07:37:54 +0900 Subject: [PATCH] =?UTF-8?q?feat=20::=20=EB=B0=B0=ED=8F=AC=20=EB=82=B4?= =?UTF-8?q?=EC=97=AD=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/V2ContainerWebAdapter.kt | 19 +++- .../GetContainerDeployHistoryResponse.kt | 17 ++++ .../in/GetContainerDeployHistoryUseCase.kt | 9 ++ .../GetContainerDeployHistoryService.kt | 44 +++++++++ .../feign/client/gocd/GocdClient.kt | 21 ++++ .../response/GetPipelinesHistoryResponse.kt | 97 +++++++++++++++++++ src/main/resources/application.yaml | 1 + 7 files changed, 203 insertions(+), 5 deletions(-) create mode 100644 src/main/kotlin/xquare/app/xquareinfra/domain/container/adapter/dto/response/GetContainerDeployHistoryResponse.kt create mode 100644 src/main/kotlin/xquare/app/xquareinfra/domain/container/application/port/in/GetContainerDeployHistoryUseCase.kt create mode 100644 src/main/kotlin/xquare/app/xquareinfra/domain/container/application/service/GetContainerDeployHistoryService.kt create mode 100644 src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/gocd/GocdClient.kt create mode 100644 src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/gocd/dto/response/GetPipelinesHistoryResponse.kt diff --git a/src/main/kotlin/xquare/app/xquareinfra/domain/container/adapter/V2ContainerWebAdapter.kt b/src/main/kotlin/xquare/app/xquareinfra/domain/container/adapter/V2ContainerWebAdapter.kt index dbc1caf..b4ce9ac 100644 --- a/src/main/kotlin/xquare/app/xquareinfra/domain/container/adapter/V2ContainerWebAdapter.kt +++ b/src/main/kotlin/xquare/app/xquareinfra/domain/container/adapter/V2ContainerWebAdapter.kt @@ -5,10 +5,9 @@ import xquare.app.xquareinfra.domain.container.adapter.dto.request.CreateGradleD import xquare.app.xquareinfra.domain.container.adapter.dto.request.CreateNodeDockerfileRequest import xquare.app.xquareinfra.domain.container.adapter.dto.request.CreateNodeWithNginxDockerfileRequest import xquare.app.xquareinfra.domain.container.adapter.dto.request.SetContainerConfigRequest -import xquare.app.xquareinfra.domain.container.application.port.`in`.CreateGradleDockerfileUseCase -import xquare.app.xquareinfra.domain.container.application.port.`in`.CreateNodeDockerfileUseCase -import xquare.app.xquareinfra.domain.container.application.port.`in`.CreateNodeWithNginxDockerfileUseCase -import xquare.app.xquareinfra.domain.container.application.port.`in`.SetContainerConfigUseCase +import xquare.app.xquareinfra.domain.container.adapter.dto.response.GetContainerDeployHistoryResponse +import xquare.app.xquareinfra.domain.container.application.port.`in`.* +import xquare.app.xquareinfra.domain.container.application.service.GetContainerDeployHistoryService import xquare.app.xquareinfra.domain.container.domain.ContainerEnvironment import java.util.* @@ -18,7 +17,9 @@ class V2ContainerWebAdapter( private val setContainerConfigUseCase: SetContainerConfigUseCase, private val createGradleDockerfileUseCase: CreateGradleDockerfileUseCase, private val createNodeWithNginxDockerfileUseCase: CreateNodeWithNginxDockerfileUseCase, - private val createNodeDockerfileUseCase: CreateNodeDockerfileUseCase + private val createNodeDockerfileUseCase: CreateNodeDockerfileUseCase, + private val getContainerDeployHistoryUseCase: GetContainerDeployHistoryUseCase, + private val getContainerDeployHistoryService: GetContainerDeployHistoryService ) { @PutMapping("/config") fun setContainerConfig( @@ -57,4 +58,12 @@ class V2ContainerWebAdapter( @RequestBody createNodeWithNginxDockerfileRequest: CreateNodeWithNginxDockerfileRequest ) = createNodeWithNginxDockerfileUseCase.createNodeWithNginxDockerfile(deployId, containerEnvironment, createNodeWithNginxDockerfileRequest) + + @GetMapping("/history") + fun getContainerDeployHistory( + @RequestParam(name = "deployId", required = true) + deployId: UUID, + @RequestParam(name = "environment", required = true) + containerEnvironment: ContainerEnvironment, + ): GetContainerDeployHistoryResponse = getContainerDeployHistoryUseCase.getContainerDeployHistory(deployId, containerEnvironment) } \ No newline at end of file diff --git a/src/main/kotlin/xquare/app/xquareinfra/domain/container/adapter/dto/response/GetContainerDeployHistoryResponse.kt b/src/main/kotlin/xquare/app/xquareinfra/domain/container/adapter/dto/response/GetContainerDeployHistoryResponse.kt new file mode 100644 index 0000000..330cc0e --- /dev/null +++ b/src/main/kotlin/xquare/app/xquareinfra/domain/container/adapter/dto/response/GetContainerDeployHistoryResponse.kt @@ -0,0 +1,17 @@ +package xquare.app.xquareinfra.domain.container.adapter.dto.response + +data class GetContainerDeployHistoryResponse( + val histories: List +) + +data class DeployHistoryResponse( + val name: String, + val scheduledDate: Long, + val commitMessage: String, + val stages: List +) + +data class StageStatus( + val name: String, + val isSuccessful: Boolean +) \ No newline at end of file diff --git a/src/main/kotlin/xquare/app/xquareinfra/domain/container/application/port/in/GetContainerDeployHistoryUseCase.kt b/src/main/kotlin/xquare/app/xquareinfra/domain/container/application/port/in/GetContainerDeployHistoryUseCase.kt new file mode 100644 index 0000000..8c91688 --- /dev/null +++ b/src/main/kotlin/xquare/app/xquareinfra/domain/container/application/port/in/GetContainerDeployHistoryUseCase.kt @@ -0,0 +1,9 @@ +package xquare.app.xquareinfra.domain.container.application.port.`in` + +import xquare.app.xquareinfra.domain.container.adapter.dto.response.GetContainerDeployHistoryResponse +import xquare.app.xquareinfra.domain.container.domain.ContainerEnvironment +import java.util.UUID + +interface GetContainerDeployHistoryUseCase { + fun getContainerDeployHistory(deployId: UUID, containerEnvironment: ContainerEnvironment): GetContainerDeployHistoryResponse +} \ No newline at end of file diff --git a/src/main/kotlin/xquare/app/xquareinfra/domain/container/application/service/GetContainerDeployHistoryService.kt b/src/main/kotlin/xquare/app/xquareinfra/domain/container/application/service/GetContainerDeployHistoryService.kt new file mode 100644 index 0000000..b8418f8 --- /dev/null +++ b/src/main/kotlin/xquare/app/xquareinfra/domain/container/application/service/GetContainerDeployHistoryService.kt @@ -0,0 +1,44 @@ +package xquare.app.xquareinfra.domain.container.application.service + +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional +import xquare.app.xquareinfra.domain.container.adapter.dto.response.DeployHistoryResponse +import xquare.app.xquareinfra.domain.container.adapter.dto.response.GetContainerDeployHistoryResponse +import xquare.app.xquareinfra.domain.container.adapter.dto.response.StageStatus +import xquare.app.xquareinfra.domain.container.application.port.`in`.GetContainerDeployHistoryUseCase +import xquare.app.xquareinfra.domain.container.domain.ContainerEnvironment +import xquare.app.xquareinfra.domain.deploy.application.port.out.FindDeployPort +import xquare.app.xquareinfra.infrastructure.exception.BusinessLogicException +import xquare.app.xquareinfra.infrastructure.feign.client.gocd.GocdClient +import java.util.* + +@Transactional +@Service +class GetContainerDeployHistoryService( + private val findDeployPort: FindDeployPort, + private val gocdClient: GocdClient +) : GetContainerDeployHistoryUseCase{ + override fun getContainerDeployHistory( + deployId: UUID, + containerEnvironment: ContainerEnvironment + ): GetContainerDeployHistoryResponse { + val deploy = findDeployPort.findById(deployId) ?: throw BusinessLogicException.DEPLOY_NOT_FOUND + val histories = gocdClient.getPipelinesHistory("build-${deploy.deployName}-${containerEnvironment.name}", "application/vnd.go.cd.v1+json") + + val response = histories.pipelines.map { + DeployHistoryResponse( + name = it.buildCause.materialRevisions[0].modifications.get(0).userName, + scheduledDate = it.scheduledDate, + stages = it.stages.map { + StageStatus( + name = it.name, + isSuccessful = it.status == "Passed" + ) + }.toList(), + commitMessage = it.buildCause.materialRevisions[0].modifications.get(0).comment + ) + }.sortedByDescending { it.scheduledDate }.toList() + + return GetContainerDeployHistoryResponse(response) + } +} \ No newline at end of file diff --git a/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/gocd/GocdClient.kt b/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/gocd/GocdClient.kt new file mode 100644 index 0000000..02027d6 --- /dev/null +++ b/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/gocd/GocdClient.kt @@ -0,0 +1,21 @@ +package xquare.app.xquareinfra.infrastructure.feign.client.gocd + +import org.springframework.cloud.openfeign.FeignClient +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestHeader +import xquare.app.xquareinfra.infrastructure.feign.client.gocd.dto.response.GetPipelinesHistoryResponse +import xquare.app.xquareinfra.infrastructure.feign.config.FeignConfig + +@FeignClient( + name = "gocd-client", + url = "\${url.gocd}", + configuration = [FeignConfig::class] +) +interface GocdClient { + @GetMapping("/api/pipelines/{pipeline_name}/history") + fun getPipelinesHistory( + @PathVariable("pipeline_name") pipelineName: String, + @RequestHeader("Accept") accept: String + ): GetPipelinesHistoryResponse +} diff --git a/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/gocd/dto/response/GetPipelinesHistoryResponse.kt b/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/gocd/dto/response/GetPipelinesHistoryResponse.kt new file mode 100644 index 0000000..7151f16 --- /dev/null +++ b/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/gocd/dto/response/GetPipelinesHistoryResponse.kt @@ -0,0 +1,97 @@ +package xquare.app.xquareinfra.infrastructure.feign.client.gocd.dto.response + +import com.fasterxml.jackson.annotation.JsonProperty + +data class GetPipelinesHistoryResponse( + @JsonProperty("_links") + val links: Links, + val pipelines: List, +) + +data class Links( + val next: Next, +) + +data class Next( + val href: String, +) + +data class Pipeline( + val name: String, + val counter: Long, + val label: String, + @JsonProperty("natural_order") + val naturalOrder: Double, + @JsonProperty("can_run") + val canRun: Boolean, + @JsonProperty("preparing_to_schedule") + val preparingToSchedule: Boolean, + val comment: Any?, + @JsonProperty("scheduled_date") + val scheduledDate: Long, + @JsonProperty("build_cause") + val buildCause: BuildCause, + val stages: List, +) + +data class BuildCause( + @JsonProperty("trigger_message") + val triggerMessage: String, + @JsonProperty("trigger_forced") + val triggerForced: Boolean, + val approver: String, + @JsonProperty("material_revisions") + val materialRevisions: List, +) + +data class MaterialRevision( + val changed: Boolean, + val material: Material, + val modifications: List, +) + +data class Material( + val name: String, + val fingerprint: String, + val type: String, + val description: String, +) + +data class Modification( + val revision: String, + @JsonProperty("modified_time") + val modifiedTime: Long, + @JsonProperty("user_name") + val userName: String, + val comment: String, + @JsonProperty("email_address") + val emailAddress: Any?, +) + +data class Stage( + val result: String, + val status: String, + @JsonProperty("rerun_of_counter") + val rerunOfCounter: Any?, + val name: String, + val counter: String, + val scheduled: Boolean, + @JsonProperty("approval_type") + val approvalType: String, + @JsonProperty("approved_by") + val approvedBy: String, + @JsonProperty("operate_permission") + val operatePermission: Boolean, + @JsonProperty("can_run") + val canRun: Boolean, + val jobs: List, +) + +data class Job( + val name: String, + @JsonProperty("scheduled_date") + val scheduledDate: Long, + val state: String, + val result: String, +) + diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 86fe14b..fe58d11 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -60,6 +60,7 @@ server: url: deploy: ${DEPLOY_URL} log: ${LOG_URL} + gocd: ${GOCD_URL} secret: projectSecret: ${PROJECT_SECRET}