diff --git a/src/main/kotlin/com/dcd/server/core/domain/application/dto/request/CreateApplicationReqDto.kt b/src/main/kotlin/com/dcd/server/core/domain/application/dto/request/CreateApplicationReqDto.kt index 60de825d..0aa3b977 100644 --- a/src/main/kotlin/com/dcd/server/core/domain/application/dto/request/CreateApplicationReqDto.kt +++ b/src/main/kotlin/com/dcd/server/core/domain/application/dto/request/CreateApplicationReqDto.kt @@ -9,5 +9,6 @@ data class CreateApplicationReqDto( val applicationType: ApplicationType, val port: Int, val version: String, + val initialScripts: List, val labels: List ) \ No newline at end of file diff --git a/src/main/kotlin/com/dcd/server/core/domain/application/dto/request/UpdateApplicationReqDto.kt b/src/main/kotlin/com/dcd/server/core/domain/application/dto/request/UpdateApplicationReqDto.kt index 1ba347f3..702d5c31 100644 --- a/src/main/kotlin/com/dcd/server/core/domain/application/dto/request/UpdateApplicationReqDto.kt +++ b/src/main/kotlin/com/dcd/server/core/domain/application/dto/request/UpdateApplicationReqDto.kt @@ -5,8 +5,9 @@ import com.dcd.server.core.domain.application.model.enums.ApplicationType data class UpdateApplicationReqDto( val name: String, val description: String?, - val applicationType: ApplicationType, val githubUrl: String?, + val applicationType: ApplicationType, + val port: Int, val version: String, - val port: Int + val initialScripts: List, ) diff --git a/src/main/kotlin/com/dcd/server/core/domain/application/service/InitialScriptService.kt b/src/main/kotlin/com/dcd/server/core/domain/application/service/InitialScriptService.kt new file mode 100644 index 00000000..bd58b5d3 --- /dev/null +++ b/src/main/kotlin/com/dcd/server/core/domain/application/service/InitialScriptService.kt @@ -0,0 +1,7 @@ +package com.dcd.server.core.domain.application.service + +import com.dcd.server.core.domain.application.model.Application + +interface InitialScriptService { + fun write(application: Application, initialScripts: List) +} \ No newline at end of file diff --git a/src/main/kotlin/com/dcd/server/core/domain/application/service/impl/InitialScriptServiceImpl.kt b/src/main/kotlin/com/dcd/server/core/domain/application/service/impl/InitialScriptServiceImpl.kt new file mode 100644 index 00000000..34082fe2 --- /dev/null +++ b/src/main/kotlin/com/dcd/server/core/domain/application/service/impl/InitialScriptServiceImpl.kt @@ -0,0 +1,29 @@ +package com.dcd.server.core.domain.application.service.impl + +import com.dcd.server.core.domain.application.model.Application +import com.dcd.server.core.domain.application.model.ApplicationInitialScript +import com.dcd.server.core.domain.application.service.InitialScriptService +import com.dcd.server.core.domain.application.spi.CommandApplicationInitialScriptPort +import org.springframework.stereotype.Service +import java.util.UUID + +@Service +class InitialScriptServiceImpl( + private val commandApplicationInitialScriptPort: CommandApplicationInitialScriptPort +) : InitialScriptService { + override fun write( + application: Application, + initialScripts: List, + ) { + commandApplicationInitialScriptPort.deleteByApplication(application) + + val initialScriptList = initialScripts.map { script -> + ApplicationInitialScript( + id = UUID.randomUUID(), + script = script, + application = application, + ) + } + commandApplicationInitialScriptPort.saveAll(initialScriptList) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/dcd/server/core/domain/application/usecase/CreateApplicationUseCase.kt b/src/main/kotlin/com/dcd/server/core/domain/application/usecase/CreateApplicationUseCase.kt index 67a93a19..6d849b70 100644 --- a/src/main/kotlin/com/dcd/server/core/domain/application/usecase/CreateApplicationUseCase.kt +++ b/src/main/kotlin/com/dcd/server/core/domain/application/usecase/CreateApplicationUseCase.kt @@ -27,7 +27,8 @@ class CreateApplicationUseCase( private val buildDockerImageService: BuildDockerImageService, private val createContainerService: CreateContainerService, private val deleteApplicationDirectoryService: DeleteApplicationDirectoryService, - private val envAutoMatchService: EnvAutoMatchService + private val envAutoMatchService: EnvAutoMatchService, + private val initialScriptService: InitialScriptService ) : CoroutineScope by CoroutineScope(Dispatchers.IO) { fun execute(createApplicationReqDto: CreateApplicationReqDto): CreateApplicationResDto { val workspace = workspaceInfo.workspace @@ -44,6 +45,7 @@ class CreateApplicationUseCase( val version = application.version envAutoMatchService.match(workspace, application) + initialScriptService.write(application, createApplicationReqDto.initialScripts) launch { val applicationType = application.applicationType diff --git a/src/main/kotlin/com/dcd/server/core/domain/application/usecase/UpdateApplicationUseCase.kt b/src/main/kotlin/com/dcd/server/core/domain/application/usecase/UpdateApplicationUseCase.kt index 437489ef..d4aa17f5 100644 --- a/src/main/kotlin/com/dcd/server/core/domain/application/usecase/UpdateApplicationUseCase.kt +++ b/src/main/kotlin/com/dcd/server/core/domain/application/usecase/UpdateApplicationUseCase.kt @@ -9,6 +9,7 @@ import com.dcd.server.core.domain.application.exception.ApplicationNotFoundExcep import com.dcd.server.core.domain.application.model.enums.ApplicationStatus import com.dcd.server.core.domain.application.service.DeleteContainerService import com.dcd.server.core.domain.application.service.DeleteImageService +import com.dcd.server.core.domain.application.service.InitialScriptService import com.dcd.server.core.domain.application.spi.CommandApplicationPort import com.dcd.server.core.domain.application.spi.QueryApplicationPort import kotlinx.coroutines.CoroutineScope @@ -22,7 +23,8 @@ class UpdateApplicationUseCase( private val commandApplicationPort: CommandApplicationPort, private val deleteContainerService: DeleteContainerService, private val deleteImageService: DeleteImageService, - private val eventPublisher: ApplicationEventPublisher + private val eventPublisher: ApplicationEventPublisher, + private val initialScriptService: InitialScriptService ) : CoroutineScope by CoroutineScope(Dispatchers.IO) { @Lock("#id") fun execute(id: String, updateApplicationReqDto: UpdateApplicationReqDto) { @@ -50,5 +52,7 @@ class UpdateApplicationUseCase( port = updateApplicationReqDto.port ) commandApplicationPort.save(updatedApplication) + + initialScriptService.write(updatedApplication, updateApplicationReqDto.initialScripts) } } \ No newline at end of file diff --git a/src/main/kotlin/com/dcd/server/presentation/domain/application/data/exetension/ApplicationRequestDataExtension.kt b/src/main/kotlin/com/dcd/server/presentation/domain/application/data/exetension/ApplicationRequestDataExtension.kt index 17065839..6b104b19 100644 --- a/src/main/kotlin/com/dcd/server/presentation/domain/application/data/exetension/ApplicationRequestDataExtension.kt +++ b/src/main/kotlin/com/dcd/server/presentation/domain/application/data/exetension/ApplicationRequestDataExtension.kt @@ -19,6 +19,7 @@ fun CreateApplicationRequest.toDto(): CreateApplicationReqDto = applicationType = this.applicationType, port = this.port, version = this.version, + initialScripts = this.initialScripts, labels = this.labels ) @@ -29,7 +30,8 @@ fun UpdateApplicationRequest.toDto(): UpdateApplicationReqDto = applicationType = this.applicationType, githubUrl = this.githubUrl, version = this.version, - port = this.port + port = this.port, + initialScripts = this.initialScripts, ) fun ExecuteCommandRequest.toDto(): ExecuteCommandReqDto = diff --git a/src/main/kotlin/com/dcd/server/presentation/domain/application/data/request/CreateApplicationRequest.kt b/src/main/kotlin/com/dcd/server/presentation/domain/application/data/request/CreateApplicationRequest.kt index e234f00f..8bd857de 100644 --- a/src/main/kotlin/com/dcd/server/presentation/domain/application/data/request/CreateApplicationRequest.kt +++ b/src/main/kotlin/com/dcd/server/presentation/domain/application/data/request/CreateApplicationRequest.kt @@ -13,5 +13,6 @@ data class CreateApplicationRequest( val applicationType: ApplicationType, val port: Int, val version: String, + val initialScripts: List = listOf(), val labels: List = listOf() ) \ No newline at end of file diff --git a/src/main/kotlin/com/dcd/server/presentation/domain/application/data/request/UpdateApplicationRequest.kt b/src/main/kotlin/com/dcd/server/presentation/domain/application/data/request/UpdateApplicationRequest.kt index 1a54bd77..030cf382 100644 --- a/src/main/kotlin/com/dcd/server/presentation/domain/application/data/request/UpdateApplicationRequest.kt +++ b/src/main/kotlin/com/dcd/server/presentation/domain/application/data/request/UpdateApplicationRequest.kt @@ -9,8 +9,9 @@ data class UpdateApplicationRequest( @field:Pattern(regexp = "^[a-zA-Z0-9 ]{1,26}$") val name: String, val description: String?, - val applicationType: ApplicationType, val githubUrl: String?, + val applicationType: ApplicationType, + val port: Int, val version: String, - val port: Int + val initialScripts: List = listOf(), ) diff --git a/src/test/kotlin/com/dcd/server/core/domain/application/usecase/CreateApplicationUseCaseTest.kt b/src/test/kotlin/com/dcd/server/core/domain/application/usecase/CreateApplicationUseCaseTest.kt index 6ec64153..a0f05c7e 100644 --- a/src/test/kotlin/com/dcd/server/core/domain/application/usecase/CreateApplicationUseCaseTest.kt +++ b/src/test/kotlin/com/dcd/server/core/domain/application/usecase/CreateApplicationUseCaseTest.kt @@ -5,6 +5,7 @@ import com.dcd.server.core.domain.application.dto.request.CreateApplicationReqDt import com.dcd.server.core.domain.application.exception.AlreadyExistsApplicationException import com.dcd.server.core.domain.application.model.enums.ApplicationType import com.dcd.server.core.domain.application.spi.CommandApplicationPort +import com.dcd.server.core.domain.application.spi.QueryApplicationInitialScriptPort import com.dcd.server.core.domain.application.spi.QueryApplicationPort import com.dcd.server.core.domain.env.model.ApplicationEnv import com.dcd.server.core.domain.env.model.ApplicationEnvDetail @@ -19,6 +20,7 @@ import io.kotest.core.spec.style.BehaviorSpec import util.workspace.WorkspaceGenerator import io.kotest.assertions.throwables.shouldThrow import io.kotest.matchers.shouldBe +import io.kotest.matchers.shouldNotBe import kotlinx.coroutines.cancel import org.springframework.boot.test.context.SpringBootTest import org.springframework.test.context.ActiveProfiles @@ -33,6 +35,7 @@ class CreateApplicationUseCaseTest( private val queryUserPort: QueryUserPort, private val commandWorkspacePort: CommandWorkspacePort, private val queryApplicationPort: QueryApplicationPort, + private val queryApplicationInitialScriptPort: QueryApplicationInitialScriptPort, private val queryWorkspacePort: QueryWorkspacePort, private val commandApplicationPort: CommandApplicationPort, private val commandApplicationEnvPort: CommandApplicationEnvPort, @@ -56,6 +59,7 @@ class CreateApplicationUseCaseTest( githubUrl = "testGithub", version = "17", port = 8080, + initialScripts = listOf(), labels = listOf() ) @@ -82,6 +86,7 @@ class CreateApplicationUseCaseTest( githubUrl = "testGithub", version = "17", port = 8080, + initialScripts = listOf(), labels = listOf() ) @@ -104,6 +109,7 @@ class CreateApplicationUseCaseTest( githubUrl = "testGithub", version = "17", port = 8080, + initialScripts = listOf(), labels = listOf() ) @@ -142,6 +148,7 @@ class CreateApplicationUseCaseTest( githubUrl = "testGithub", version = "17", port = 8080, + initialScripts = listOf(), labels = listOf("testLabel") ) @@ -164,4 +171,28 @@ class CreateApplicationUseCaseTest( } } } + + given("초기화 스크립트 내용을 가진 애플리케이션 생성 정보가 주어지고") { + val request = CreateApplicationReqDto( + name = "testCreateApplication", + description = "testDescription", + applicationType = ApplicationType.SPRING_BOOT, + githubUrl = "testGithub", + version = "17", + port = 8080, + initialScripts = listOf("echo test"), + labels = listOf() + ) + + `when`("usecase를 실행하면") { + val applicationId = createApplicationUseCase.execute(request).applicationId + + then("생성된 애플리케이션에 초기화 스크립트가 존재해야함") { + val application = queryApplicationPort.findById(applicationId).also { it shouldNotBe null }!! + val initialScript = queryApplicationInitialScriptPort.findAllByApplication(application) + initialScript.size shouldBe 1 + initialScript[0].script shouldBe request.initialScripts.first() + } + } + } }) \ No newline at end of file diff --git a/src/test/kotlin/com/dcd/server/core/domain/application/usecase/UpdateApplicationUseCaseTest.kt b/src/test/kotlin/com/dcd/server/core/domain/application/usecase/UpdateApplicationUseCaseTest.kt index 7c7d259d..0f9e7cdf 100644 --- a/src/test/kotlin/com/dcd/server/core/domain/application/usecase/UpdateApplicationUseCaseTest.kt +++ b/src/test/kotlin/com/dcd/server/core/domain/application/usecase/UpdateApplicationUseCaseTest.kt @@ -7,12 +7,14 @@ import com.dcd.server.core.domain.application.exception.ApplicationNotFoundExcep import com.dcd.server.core.domain.application.model.enums.ApplicationStatus import com.dcd.server.core.domain.application.model.enums.ApplicationType import com.dcd.server.core.domain.application.spi.CommandApplicationPort +import com.dcd.server.core.domain.application.spi.QueryApplicationInitialScriptPort import com.dcd.server.core.domain.application.spi.QueryApplicationPort import com.dcd.server.core.domain.user.spi.QueryUserPort import com.dcd.server.core.domain.workspace.spi.QueryWorkspacePort import com.ninjasquad.springmockk.MockkBean import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec +import io.kotest.matchers.collections.shouldHaveSize import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe import io.mockk.coVerify @@ -29,13 +31,14 @@ class UpdateApplicationUseCaseTest( private val queryUserPort: QueryUserPort, private val queryWorkspacePort: QueryWorkspacePort, private val queryApplicationPort: QueryApplicationPort, + private val queryApplicationInitialScriptPort: QueryApplicationInitialScriptPort, private val commandApplicationPort: CommandApplicationPort, @MockkBean(relaxed = true) private val commandPort: CommandPort ) : BehaviorSpec({ val targetUserId = "923a6407-a5f8-4e1e-bffd-0621910ddfc8" - val updateReqDto = UpdateApplicationReqDto(name = "updated application", description = "dldl", applicationType = ApplicationType.SPRING_BOOT, githubUrl = null, version = "11", port = 8080) + val updateReqDto = UpdateApplicationReqDto(name = "updated application", description = "dldl", applicationType = ApplicationType.SPRING_BOOT, githubUrl = null, version = "11", port = 8080, initialScripts = listOf("echo test")) given("애플리케이션 아이디가 주어지고") { val targetUser = queryUserPort.findById(targetUserId)!! @@ -59,6 +62,13 @@ class UpdateApplicationUseCaseTest( coVerify { commandPort.executeShellCommand("docker rm ${targetApplication.containerName}") } coVerify { commandPort.executeShellCommand("docker rmi ${targetApplication.containerName}") } } + + then("변경된 초기화 스크립트를 가지고 있어야함") { + val result = queryApplicationPort.findById(applicationId).also { it shouldNotBe null }!! + val initialScripts = queryApplicationInitialScriptPort.findAllByApplication(result) + initialScripts shouldHaveSize 1 + initialScripts[0].script shouldBe updateReqDto.initialScripts.first() + } } `when`("애플리케이션이 실행중이라면") { diff --git a/src/test/kotlin/com/dcd/server/presentation/domain/application/ApplicationWebAdapterTest.kt b/src/test/kotlin/com/dcd/server/presentation/domain/application/ApplicationWebAdapterTest.kt index 8daefd96..8684cace 100644 --- a/src/test/kotlin/com/dcd/server/presentation/domain/application/ApplicationWebAdapterTest.kt +++ b/src/test/kotlin/com/dcd/server/presentation/domain/application/ApplicationWebAdapterTest.kt @@ -39,6 +39,7 @@ class ApplicationWebAdapterTest : BehaviorSpec({ applicationType = ApplicationType.SPRING_BOOT, githubUrl = "testUrl", port = 8080, + initialScripts = emptyList(), version = "17", ) @@ -157,7 +158,7 @@ class ApplicationWebAdapterTest : BehaviorSpec({ given("UpdateRequest가 주어지고") { val testId ="testId" - val request = UpdateApplicationRequest(name = "update", description = null, applicationType = ApplicationType.SPRING_BOOT, githubUrl = null, version = "11", port = 8080) + val request = UpdateApplicationRequest(name = "update", description = null, applicationType = ApplicationType.SPRING_BOOT, githubUrl = null, version = "11", port = 8080, initialScripts = emptyList()) `when`("updateApplication 메서드를 실행할때") { val result = applicationWebAdapter.updateApplication(testWorkspaceId, testId, request) diff --git a/src/test/resources/data.sql b/src/test/resources/data.sql index 8503e0aa..67c3a8e7 100644 --- a/src/test/resources/data.sql +++ b/src/test/resources/data.sql @@ -36,8 +36,8 @@ alter table if exists application_env_matcher_entity add constraint FKqfkw6tgy65 alter table if exists application_env_entity add constraint FKm22cqdjjl434jyqenpa4nf78p foreign key (workspace_id) references workspace_entity (id); alter table if exists application_env_label_entity add constraint FKgd5b8upn11w2uh6voe20dm6df foreign key (application_env_id) references application_env_entity (id); alter table if exists application_entity add constraint FKn9drxkrx2h6wlorxfy00mr45h foreign key (workspace_id) references workspace_entity; -alter table if exists application_label_entity add constraint FKq6iovxq5tdx2i1lwrx34kg0b9 foreign key (application_id) references application_entity; -alter table if exists application_initial_script_entity add constraint FKq6iovxq5tdx2i1lwrx34kg0b0 foreign key (application_id) references application_entity; +alter table if exists application_label_entity add constraint FKq6iovxq5tdx2i1lwrx34kg0b9 foreign key (application_id) references application_entity (id); +alter table if exists application_initial_script_entity add constraint FKq6iovxq5tdx2i1lwrx34kg0b0 foreign key (application_id) references application_entity (id); alter table if exists role_entity add constraint FKrot6fehcor0f3sux5s6kgl0a4 foreign key (user_id) references user_entity; alter table if exists workspace_entity add constraint FKlfxk1bhw5knckt8vv28xvx5g2 foreign key (owner_id) references user_entity; alter table if exists domain_entity add constraint FKh7b0t3y0a7x5boh75j8lanww6 foreign key (application_id) references application_entity;