From ca46a92ff02e2b9d176b14934522d4bdd313672d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B7=B8=EB=B6=84?= <1210thatman@gmail.com> Date: Sun, 10 May 2026 17:01:39 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat(ci):=20gRPC,=20JPA,=20MySQL=20?= =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80=20#36?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- MODULE.bazel | 2 ++ kotlin.MODULE.bazel | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/MODULE.bazel b/MODULE.bazel index 7985818..e67454e 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -7,6 +7,8 @@ bazel_dep(name = "rules_kotlin", version = "2.1.0") bazel_dep(name = "rules_jvm_external", version = "6.7") bazel_dep(name = "rules_go", version = "0.59.0") bazel_dep(name = "gazelle", version = "0.47.0") +bazel_dep(name = "rules_proto", version = "7.0.2") +bazel_dep(name = "grpc-java", version = "1.70.0") include("//:kotlin.MODULE.bazel") include("//:go.MODULE.bazel") diff --git a/kotlin.MODULE.bazel b/kotlin.MODULE.bazel index 9b67dc4..3c689fc 100644 --- a/kotlin.MODULE.bazel +++ b/kotlin.MODULE.bazel @@ -9,4 +9,18 @@ maven.artifact(artifact = "kotlin-reflect", group = "org.jetbrains.kotlin", vers maven.artifact(artifact = "kotlin-allopen-compiler-plugin", group = "org.jetbrains.kotlin", version = "2.1.0") maven.artifact(artifact = "jackson-module-kotlin", group = "com.fasterxml.jackson.module", version = "2.18.2") +# JPA / DB +maven.artifact(artifact = "spring-boot-starter-data-jpa", group = "org.springframework.boot", version = "4.0.1") +maven.artifact(artifact = "spring-boot-starter", group = "org.springframework.boot", version = "4.0.1") +maven.artifact(artifact = "mysql-connector-j", group = "com.mysql", version = "9.3.0") + +# gRPC +maven.artifact(artifact = "grpc-netty-shaded", group = "io.grpc", version = "1.70.0") +maven.artifact(artifact = "grpc-protobuf", group = "io.grpc", version = "1.70.0") +maven.artifact(artifact = "grpc-stub", group = "io.grpc", version = "1.70.0") +maven.artifact(artifact = "grpc-kotlin-stub", group = "io.grpc", version = "1.4.1") +maven.artifact(artifact = "protobuf-java", group = "com.google.protobuf", version = "4.30.2") +maven.artifact(artifact = "protobuf-kotlin", group = "com.google.protobuf", version = "4.30.2") +maven.artifact(artifact = "javax.annotation-api", group = "javax.annotation", version = "1.3.2") + use_repo(maven, "maven") From 98b8f51458646e649ca5e176815329a6954d38f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B7=B8=EB=B6=84?= <1210thatman@gmail.com> Date: Sun, 10 May 2026 17:02:05 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat(contracts):=20configuration=20gRPC=20?= =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=20proto=20=EC=A0=95=EC=9D=98=20#36?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- contracts/BUILD.bazel | 21 ++++++++++++ contracts/proto/configuration.proto | 52 +++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 contracts/BUILD.bazel create mode 100644 contracts/proto/configuration.proto diff --git a/contracts/BUILD.bazel b/contracts/BUILD.bazel new file mode 100644 index 0000000..a2019d7 --- /dev/null +++ b/contracts/BUILD.bazel @@ -0,0 +1,21 @@ +load("@rules_proto//proto:defs.bzl", "proto_library") +load("@grpc-java//:java_grpc_library.bzl", "java_grpc_library") +load("@rules_java//java:defs.bzl", "java_proto_library") + +package(default_visibility = ["//visibility:public"]) + +proto_library( + name = "configuration_proto", + srcs = ["proto/configuration.proto"], +) + +java_proto_library( + name = "configuration_java_proto", + deps = [":configuration_proto"], +) + +java_grpc_library( + name = "configuration_grpc_java", + srcs = [":configuration_proto"], + deps = [":configuration_java_proto"], +) diff --git a/contracts/proto/configuration.proto b/contracts/proto/configuration.proto new file mode 100644 index 0000000..be9f5c2 --- /dev/null +++ b/contracts/proto/configuration.proto @@ -0,0 +1,52 @@ +syntax = "proto3"; + +package entrydsm.configuration.v1; + +option java_package = "hs.kr.entrydsm.configuration.grpc"; +option java_multiple_files = true; +option java_outer_classname = "ConfigurationProto"; + +service ConfigurationService { + rpc CreateEnvironmentVariable(CreateEnvironmentVariableRequest) returns (EnvironmentVariableResponse); + rpc GetEnvironmentVariable(GetEnvironmentVariableRequest) returns (EnvironmentVariableResponse); + rpc GetAllEnvironmentVariables(GetAllEnvironmentVariablesRequest) returns (GetAllEnvironmentVariablesResponse); + rpc UpdateEnvironmentVariable(UpdateEnvironmentVariableRequest) returns (EnvironmentVariableResponse); + rpc DeleteEnvironmentVariable(DeleteEnvironmentVariableRequest) returns (DeleteEnvironmentVariableResponse); +} + +message CreateEnvironmentVariableRequest { + string key = 1; + string value = 2; + optional string description = 3; +} + +message GetEnvironmentVariableRequest { + string key = 1; +} + +message GetAllEnvironmentVariablesRequest {} + +message UpdateEnvironmentVariableRequest { + string key = 1; + string value = 2; + optional string description = 3; +} + +message DeleteEnvironmentVariableRequest { + string key = 1; +} + +message EnvironmentVariableResponse { + int64 id = 1; + string key = 2; + string value = 3; + optional string description = 4; +} + +message GetAllEnvironmentVariablesResponse { + repeated EnvironmentVariableResponse items = 1; +} + +message DeleteEnvironmentVariableResponse { + bool success = 1; +} From f15dad1a475d95be28cae9708d640140a482fdc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B7=B8=EB=B6=84?= <1210thatman@gmail.com> Date: Sun, 10 May 2026 17:03:00 +0900 Subject: [PATCH 3/7] =?UTF-8?q?feat(configuration):=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=20=EA=B5=AC=ED=98=84=20#36?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- .../configuration/domain/EnvironmentVariable.kt | 8 ++++++++ .../command/CreateEnvironmentVariableCommand.kt | 7 +++++++ .../command/UpdateEnvironmentVariableCommand.kt | 7 +++++++ .../EnvironmentVariableAlreadyExistsException.kt | 4 ++++ .../exception/EnvironmentVariableNotFoundException.kt | 4 ++++ .../port/in/CreateEnvironmentVariableUseCase.kt | 8 ++++++++ .../port/in/DeleteEnvironmentVariableUseCase.kt | 5 +++++ .../domain/port/in/ReadEnvironmentVariableUseCase.kt | 8 ++++++++ .../port/in/UpdateEnvironmentVariableUseCase.kt | 8 ++++++++ .../domain/port/out/EnvironmentVariableRepository.kt | 11 +++++++++++ 10 files changed, 70 insertions(+) create mode 100644 systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/EnvironmentVariable.kt create mode 100644 systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/command/CreateEnvironmentVariableCommand.kt create mode 100644 systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/command/UpdateEnvironmentVariableCommand.kt create mode 100644 systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/exception/EnvironmentVariableAlreadyExistsException.kt create mode 100644 systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/exception/EnvironmentVariableNotFoundException.kt create mode 100644 systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/in/CreateEnvironmentVariableUseCase.kt create mode 100644 systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/in/DeleteEnvironmentVariableUseCase.kt create mode 100644 systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/in/ReadEnvironmentVariableUseCase.kt create mode 100644 systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/in/UpdateEnvironmentVariableUseCase.kt create mode 100644 systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/out/EnvironmentVariableRepository.kt diff --git a/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/EnvironmentVariable.kt b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/EnvironmentVariable.kt new file mode 100644 index 0000000..7d3d935 --- /dev/null +++ b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/EnvironmentVariable.kt @@ -0,0 +1,8 @@ +package hs.kr.entrydsm.configuration.domain + +data class EnvironmentVariable( + val id: Long? = null, + val key: String, + val value: String, + val description: String? = null, +) diff --git a/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/command/CreateEnvironmentVariableCommand.kt b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/command/CreateEnvironmentVariableCommand.kt new file mode 100644 index 0000000..e338350 --- /dev/null +++ b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/command/CreateEnvironmentVariableCommand.kt @@ -0,0 +1,7 @@ +package hs.kr.entrydsm.configuration.domain.command + +data class CreateEnvironmentVariableCommand( + val key: String, + val value: String, + val description: String? = null, +) diff --git a/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/command/UpdateEnvironmentVariableCommand.kt b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/command/UpdateEnvironmentVariableCommand.kt new file mode 100644 index 0000000..6f0d6cd --- /dev/null +++ b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/command/UpdateEnvironmentVariableCommand.kt @@ -0,0 +1,7 @@ +package hs.kr.entrydsm.configuration.domain.command + +data class UpdateEnvironmentVariableCommand( + val key: String, + val value: String, + val description: String? = null, +) diff --git a/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/exception/EnvironmentVariableAlreadyExistsException.kt b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/exception/EnvironmentVariableAlreadyExistsException.kt new file mode 100644 index 0000000..3855a6b --- /dev/null +++ b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/exception/EnvironmentVariableAlreadyExistsException.kt @@ -0,0 +1,4 @@ +package hs.kr.entrydsm.configuration.domain.exception + +class EnvironmentVariableAlreadyExistsException(key: String) : + RuntimeException("Environment variable already exists: $key") diff --git a/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/exception/EnvironmentVariableNotFoundException.kt b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/exception/EnvironmentVariableNotFoundException.kt new file mode 100644 index 0000000..c34025a --- /dev/null +++ b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/exception/EnvironmentVariableNotFoundException.kt @@ -0,0 +1,4 @@ +package hs.kr.entrydsm.configuration.domain.exception + +class EnvironmentVariableNotFoundException(key: String) : + RuntimeException("Environment variable not found: $key") diff --git a/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/in/CreateEnvironmentVariableUseCase.kt b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/in/CreateEnvironmentVariableUseCase.kt new file mode 100644 index 0000000..d42a53a --- /dev/null +++ b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/in/CreateEnvironmentVariableUseCase.kt @@ -0,0 +1,8 @@ +package hs.kr.entrydsm.configuration.domain.port.`in` + +import hs.kr.entrydsm.configuration.domain.EnvironmentVariable +import hs.kr.entrydsm.configuration.domain.command.CreateEnvironmentVariableCommand + +interface CreateEnvironmentVariableUseCase { + fun create(command: CreateEnvironmentVariableCommand): EnvironmentVariable +} diff --git a/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/in/DeleteEnvironmentVariableUseCase.kt b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/in/DeleteEnvironmentVariableUseCase.kt new file mode 100644 index 0000000..b8caf46 --- /dev/null +++ b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/in/DeleteEnvironmentVariableUseCase.kt @@ -0,0 +1,5 @@ +package hs.kr.entrydsm.configuration.domain.port.`in` + +interface DeleteEnvironmentVariableUseCase { + fun delete(key: String) +} diff --git a/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/in/ReadEnvironmentVariableUseCase.kt b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/in/ReadEnvironmentVariableUseCase.kt new file mode 100644 index 0000000..9a5ae98 --- /dev/null +++ b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/in/ReadEnvironmentVariableUseCase.kt @@ -0,0 +1,8 @@ +package hs.kr.entrydsm.configuration.domain.port.`in` + +import hs.kr.entrydsm.configuration.domain.EnvironmentVariable + +interface ReadEnvironmentVariableUseCase { + fun findByKey(key: String): EnvironmentVariable + fun findAll(): List +} diff --git a/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/in/UpdateEnvironmentVariableUseCase.kt b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/in/UpdateEnvironmentVariableUseCase.kt new file mode 100644 index 0000000..8ff9904 --- /dev/null +++ b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/in/UpdateEnvironmentVariableUseCase.kt @@ -0,0 +1,8 @@ +package hs.kr.entrydsm.configuration.domain.port.`in` + +import hs.kr.entrydsm.configuration.domain.EnvironmentVariable +import hs.kr.entrydsm.configuration.domain.command.UpdateEnvironmentVariableCommand + +interface UpdateEnvironmentVariableUseCase { + fun update(command: UpdateEnvironmentVariableCommand): EnvironmentVariable +} diff --git a/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/out/EnvironmentVariableRepository.kt b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/out/EnvironmentVariableRepository.kt new file mode 100644 index 0000000..538b2ff --- /dev/null +++ b/systems/configuration/configuration-domain/src/main/kotlin/hs/kr/entrydsm/configuration/domain/port/out/EnvironmentVariableRepository.kt @@ -0,0 +1,11 @@ +package hs.kr.entrydsm.configuration.domain.port.out + +import hs.kr.entrydsm.configuration.domain.EnvironmentVariable + +interface EnvironmentVariableRepository { + fun save(environmentVariable: EnvironmentVariable): EnvironmentVariable + fun findByKey(key: String): EnvironmentVariable? + fun findAll(): List + fun deleteByKey(key: String) + fun existsByKey(key: String): Boolean +} From 97ff34bd6f4649671bfde263861e7a263162085f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B7=B8=EB=B6=84?= <1210thatman@gmail.com> Date: Sun, 10 May 2026 17:03:31 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat(configuration):=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=9C=A0=EC=A6=88=EC=BC=80=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=20=EA=B5=AC=ED=98=84=20#36?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- .../configuration-application/deps.bzl | 5 +- .../application/EnvironmentVariableService.kt | 65 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 systems/configuration/configuration-application/src/main/kotlin/hs/kr/entrydsm/configuration/application/EnvironmentVariableService.kt diff --git a/systems/configuration/configuration-application/deps.bzl b/systems/configuration/configuration-application/deps.bzl index 5cf0364..b6319a2 100644 --- a/systems/configuration/configuration-application/deps.bzl +++ b/systems/configuration/configuration-application/deps.bzl @@ -1,4 +1,7 @@ -KOTLIN_DEPS = [] +KOTLIN_DEPS = [ + "@maven//:org_springframework_boot_spring_boot_starter", + "//systems/configuration/configuration-domain:main", +] TEST_DEPS = [ "@maven//:junit_junit", diff --git a/systems/configuration/configuration-application/src/main/kotlin/hs/kr/entrydsm/configuration/application/EnvironmentVariableService.kt b/systems/configuration/configuration-application/src/main/kotlin/hs/kr/entrydsm/configuration/application/EnvironmentVariableService.kt new file mode 100644 index 0000000..f89b3c8 --- /dev/null +++ b/systems/configuration/configuration-application/src/main/kotlin/hs/kr/entrydsm/configuration/application/EnvironmentVariableService.kt @@ -0,0 +1,65 @@ +package hs.kr.entrydsm.configuration.application + +import hs.kr.entrydsm.configuration.domain.EnvironmentVariable +import hs.kr.entrydsm.configuration.domain.command.CreateEnvironmentVariableCommand +import hs.kr.entrydsm.configuration.domain.command.UpdateEnvironmentVariableCommand +import hs.kr.entrydsm.configuration.domain.exception.EnvironmentVariableAlreadyExistsException +import hs.kr.entrydsm.configuration.domain.exception.EnvironmentVariableNotFoundException +import hs.kr.entrydsm.configuration.domain.port.`in`.CreateEnvironmentVariableUseCase +import hs.kr.entrydsm.configuration.domain.port.`in`.DeleteEnvironmentVariableUseCase +import hs.kr.entrydsm.configuration.domain.port.`in`.ReadEnvironmentVariableUseCase +import hs.kr.entrydsm.configuration.domain.port.`in`.UpdateEnvironmentVariableUseCase +import hs.kr.entrydsm.configuration.domain.port.out.EnvironmentVariableRepository +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional + +@Service +@Transactional(readOnly = true) +class EnvironmentVariableService( + private val environmentVariableRepository: EnvironmentVariableRepository, +) : CreateEnvironmentVariableUseCase, + ReadEnvironmentVariableUseCase, + UpdateEnvironmentVariableUseCase, + DeleteEnvironmentVariableUseCase { + + @Transactional + override fun create(command: CreateEnvironmentVariableCommand): EnvironmentVariable { + if (environmentVariableRepository.existsByKey(command.key)) { + throw EnvironmentVariableAlreadyExistsException(command.key) + } + return environmentVariableRepository.save( + EnvironmentVariable( + key = command.key, + value = command.value, + description = command.description, + ) + ) + } + + override fun findByKey(key: String): EnvironmentVariable = + environmentVariableRepository.findByKey(key) + ?: throw EnvironmentVariableNotFoundException(key) + + override fun findAll(): List = + environmentVariableRepository.findAll() + + @Transactional + override fun update(command: UpdateEnvironmentVariableCommand): EnvironmentVariable { + val existing = environmentVariableRepository.findByKey(command.key) + ?: throw EnvironmentVariableNotFoundException(command.key) + return environmentVariableRepository.save( + existing.copy( + value = command.value, + description = command.description, + ) + ) + } + + @Transactional + override fun delete(key: String) { + if (!environmentVariableRepository.existsByKey(key)) { + throw EnvironmentVariableNotFoundException(key) + } + environmentVariableRepository.deleteByKey(key) + } +} From 1ca30ae364de875023bee077f7a0c06217a73a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B7=B8=EB=B6=84?= <1210thatman@gmail.com> Date: Sun, 10 May 2026 17:04:10 +0900 Subject: [PATCH 5/7] =?UTF-8?q?feat(configuration):=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=EB=B3=80=EC=88=98=20JPA=20=EC=98=81=EC=86=8D=EC=84=B1=20?= =?UTF-8?q?=EC=96=B4=EB=8C=91=ED=84=B0=20=EA=B5=AC=ED=98=84=20#36?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- .../configuration-adapter-out/deps.bzl | 6 ++- .../EnvironmentVariablePersistenceAdapter.kt | 30 +++++++++++++ .../entity/EnvironmentVariableJpaEntity.kt | 42 +++++++++++++++++++ .../EnvironmentVariableJpaRepository.kt | 10 +++++ 4 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 systems/configuration/configuration-adapter-out/src/main/kotlin/hs/kr/entrydsm/configuration/adapterout/EnvironmentVariablePersistenceAdapter.kt create mode 100644 systems/configuration/configuration-adapter-out/src/main/kotlin/hs/kr/entrydsm/configuration/adapterout/entity/EnvironmentVariableJpaEntity.kt create mode 100644 systems/configuration/configuration-adapter-out/src/main/kotlin/hs/kr/entrydsm/configuration/adapterout/repository/EnvironmentVariableJpaRepository.kt diff --git a/systems/configuration/configuration-adapter-out/deps.bzl b/systems/configuration/configuration-adapter-out/deps.bzl index 5cf0364..26e291c 100644 --- a/systems/configuration/configuration-adapter-out/deps.bzl +++ b/systems/configuration/configuration-adapter-out/deps.bzl @@ -1,4 +1,8 @@ -KOTLIN_DEPS = [] +KOTLIN_DEPS = [ + "@maven//:org_springframework_boot_spring_boot_starter_data_jpa", + "@maven//:com_mysql_mysql_connector_j", + "//systems/configuration/configuration-domain:main", +] TEST_DEPS = [ "@maven//:junit_junit", diff --git a/systems/configuration/configuration-adapter-out/src/main/kotlin/hs/kr/entrydsm/configuration/adapterout/EnvironmentVariablePersistenceAdapter.kt b/systems/configuration/configuration-adapter-out/src/main/kotlin/hs/kr/entrydsm/configuration/adapterout/EnvironmentVariablePersistenceAdapter.kt new file mode 100644 index 0000000..3e3e112 --- /dev/null +++ b/systems/configuration/configuration-adapter-out/src/main/kotlin/hs/kr/entrydsm/configuration/adapterout/EnvironmentVariablePersistenceAdapter.kt @@ -0,0 +1,30 @@ +package hs.kr.entrydsm.configuration.adapterout + +import hs.kr.entrydsm.configuration.adapterout.entity.EnvironmentVariableJpaEntity +import hs.kr.entrydsm.configuration.adapterout.repository.EnvironmentVariableJpaRepository +import hs.kr.entrydsm.configuration.domain.EnvironmentVariable +import hs.kr.entrydsm.configuration.domain.port.out.EnvironmentVariableRepository +import org.springframework.stereotype.Component + +@Component +class EnvironmentVariablePersistenceAdapter( + private val environmentVariableJpaRepository: EnvironmentVariableJpaRepository, +) : EnvironmentVariableRepository { + + override fun save(environmentVariable: EnvironmentVariable): EnvironmentVariable = + environmentVariableJpaRepository.save( + EnvironmentVariableJpaEntity.from(environmentVariable) + ).toDomain() + + override fun findByKey(key: String): EnvironmentVariable? = + environmentVariableJpaRepository.findByKey(key)?.toDomain() + + override fun findAll(): List = + environmentVariableJpaRepository.findAll().map { it.toDomain() } + + override fun deleteByKey(key: String) = + environmentVariableJpaRepository.deleteByKey(key) + + override fun existsByKey(key: String): Boolean = + environmentVariableJpaRepository.existsByKey(key) +} diff --git a/systems/configuration/configuration-adapter-out/src/main/kotlin/hs/kr/entrydsm/configuration/adapterout/entity/EnvironmentVariableJpaEntity.kt b/systems/configuration/configuration-adapter-out/src/main/kotlin/hs/kr/entrydsm/configuration/adapterout/entity/EnvironmentVariableJpaEntity.kt new file mode 100644 index 0000000..6449468 --- /dev/null +++ b/systems/configuration/configuration-adapter-out/src/main/kotlin/hs/kr/entrydsm/configuration/adapterout/entity/EnvironmentVariableJpaEntity.kt @@ -0,0 +1,42 @@ +package hs.kr.entrydsm.configuration.adapterout.entity + +import hs.kr.entrydsm.configuration.domain.EnvironmentVariable +import jakarta.persistence.Column +import jakarta.persistence.Entity +import jakarta.persistence.GeneratedValue +import jakarta.persistence.GenerationType +import jakarta.persistence.Id +import jakarta.persistence.Table + +@Entity +@Table(name = "environment_variable") +class EnvironmentVariableJpaEntity( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + val id: Long? = null, + + @Column(name = "env_key", unique = true, nullable = false, length = 255) + val key: String, + + @Column(name = "env_value", nullable = false, columnDefinition = "TEXT") + val value: String, + + @Column(name = "description", columnDefinition = "TEXT") + val description: String? = null, +) { + fun toDomain() = EnvironmentVariable( + id = id, + key = key, + value = value, + description = description, + ) + + companion object { + fun from(domain: EnvironmentVariable) = EnvironmentVariableJpaEntity( + id = domain.id, + key = domain.key, + value = domain.value, + description = domain.description, + ) + } +} diff --git a/systems/configuration/configuration-adapter-out/src/main/kotlin/hs/kr/entrydsm/configuration/adapterout/repository/EnvironmentVariableJpaRepository.kt b/systems/configuration/configuration-adapter-out/src/main/kotlin/hs/kr/entrydsm/configuration/adapterout/repository/EnvironmentVariableJpaRepository.kt new file mode 100644 index 0000000..bf2447f --- /dev/null +++ b/systems/configuration/configuration-adapter-out/src/main/kotlin/hs/kr/entrydsm/configuration/adapterout/repository/EnvironmentVariableJpaRepository.kt @@ -0,0 +1,10 @@ +package hs.kr.entrydsm.configuration.adapterout.repository + +import hs.kr.entrydsm.configuration.adapterout.entity.EnvironmentVariableJpaEntity +import org.springframework.data.jpa.repository.JpaRepository + +interface EnvironmentVariableJpaRepository : JpaRepository { + fun findByKey(key: String): EnvironmentVariableJpaEntity? + fun deleteByKey(key: String) + fun existsByKey(key: String): Boolean +} From 63f3d78654b485fecd3e4662b1332b63c0d880ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B7=B8=EB=B6=84?= <1210thatman@gmail.com> Date: Sun, 10 May 2026 17:05:01 +0900 Subject: [PATCH 6/7] =?UTF-8?q?feat(configuration):=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=EB=B3=80=EC=88=98=20gRPC=20=EC=84=9C=EB=B2=84=20=EC=96=B4?= =?UTF-8?q?=EB=8C=91=ED=84=B0=20=EA=B5=AC=ED=98=84=20#36?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- .../configuration-adapter-in/deps.bzl | 14 ++- .../adapterin/grpc/ConfigurationGrpcServer.kt | 33 ++++++ .../grpc/ConfigurationGrpcService.kt | 102 ++++++++++++++++++ 3 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 systems/configuration/configuration-adapter-in/src/main/kotlin/hs/kr/entrydsm/configuration/adapterin/grpc/ConfigurationGrpcServer.kt create mode 100644 systems/configuration/configuration-adapter-in/src/main/kotlin/hs/kr/entrydsm/configuration/adapterin/grpc/ConfigurationGrpcService.kt diff --git a/systems/configuration/configuration-adapter-in/deps.bzl b/systems/configuration/configuration-adapter-in/deps.bzl index 5cf0364..aff538e 100644 --- a/systems/configuration/configuration-adapter-in/deps.bzl +++ b/systems/configuration/configuration-adapter-in/deps.bzl @@ -1,4 +1,16 @@ -KOTLIN_DEPS = [] +KOTLIN_DEPS = [ + "@maven//:io_grpc_grpc_netty_shaded", + "@maven//:io_grpc_grpc_protobuf", + "@maven//:io_grpc_grpc_stub", + "@maven//:io_grpc_grpc_kotlin_stub", + "@maven//:com_google_protobuf_protobuf_java", + "@maven//:com_google_protobuf_protobuf_kotlin", + "@maven//:javax_annotation_javax_annotation_api", + "@maven//:org_springframework_boot_spring_boot_starter", + "//contracts:configuration_grpc_java", + "//contracts:configuration_java_proto", + "//systems/configuration/configuration-domain:main", +] TEST_DEPS = [ "@maven//:junit_junit", diff --git a/systems/configuration/configuration-adapter-in/src/main/kotlin/hs/kr/entrydsm/configuration/adapterin/grpc/ConfigurationGrpcServer.kt b/systems/configuration/configuration-adapter-in/src/main/kotlin/hs/kr/entrydsm/configuration/adapterin/grpc/ConfigurationGrpcServer.kt new file mode 100644 index 0000000..7ee7571 --- /dev/null +++ b/systems/configuration/configuration-adapter-in/src/main/kotlin/hs/kr/entrydsm/configuration/adapterin/grpc/ConfigurationGrpcServer.kt @@ -0,0 +1,33 @@ +package hs.kr.entrydsm.configuration.adapterin.grpc + +import io.grpc.Server +import io.grpc.ServerBuilder +import org.springframework.beans.factory.annotation.Value +import org.springframework.context.SmartLifecycle +import org.springframework.stereotype.Component +import java.util.concurrent.TimeUnit + +@Component +class ConfigurationGrpcServer( + @Value("\${grpc.port:9090}") private val port: Int, + private val configurationGrpcService: ConfigurationGrpcService, +) : SmartLifecycle { + + private var server: Server? = null + private var running = false + + override fun start() { + server = ServerBuilder.forPort(port) + .addService(configurationGrpcService) + .build() + .start() + running = true + } + + override fun stop() { + server?.shutdown()?.awaitTermination(30, TimeUnit.SECONDS) + running = false + } + + override fun isRunning(): Boolean = running +} diff --git a/systems/configuration/configuration-adapter-in/src/main/kotlin/hs/kr/entrydsm/configuration/adapterin/grpc/ConfigurationGrpcService.kt b/systems/configuration/configuration-adapter-in/src/main/kotlin/hs/kr/entrydsm/configuration/adapterin/grpc/ConfigurationGrpcService.kt new file mode 100644 index 0000000..19fd076 --- /dev/null +++ b/systems/configuration/configuration-adapter-in/src/main/kotlin/hs/kr/entrydsm/configuration/adapterin/grpc/ConfigurationGrpcService.kt @@ -0,0 +1,102 @@ +package hs.kr.entrydsm.configuration.adapterin.grpc + +import hs.kr.entrydsm.configuration.domain.command.CreateEnvironmentVariableCommand +import hs.kr.entrydsm.configuration.domain.command.UpdateEnvironmentVariableCommand +import hs.kr.entrydsm.configuration.domain.port.`in`.CreateEnvironmentVariableUseCase +import hs.kr.entrydsm.configuration.domain.port.`in`.DeleteEnvironmentVariableUseCase +import hs.kr.entrydsm.configuration.domain.port.`in`.ReadEnvironmentVariableUseCase +import hs.kr.entrydsm.configuration.domain.port.`in`.UpdateEnvironmentVariableUseCase +import hs.kr.entrydsm.configuration.grpc.ConfigurationServiceGrpc +import hs.kr.entrydsm.configuration.grpc.CreateEnvironmentVariableRequest +import hs.kr.entrydsm.configuration.grpc.DeleteEnvironmentVariableRequest +import hs.kr.entrydsm.configuration.grpc.DeleteEnvironmentVariableResponse +import hs.kr.entrydsm.configuration.grpc.EnvironmentVariableResponse +import hs.kr.entrydsm.configuration.grpc.GetAllEnvironmentVariablesRequest +import hs.kr.entrydsm.configuration.grpc.GetAllEnvironmentVariablesResponse +import hs.kr.entrydsm.configuration.grpc.GetEnvironmentVariableRequest +import hs.kr.entrydsm.configuration.grpc.UpdateEnvironmentVariableRequest +import io.grpc.stub.StreamObserver +import org.springframework.stereotype.Component + +@Component +class ConfigurationGrpcService( + private val createUseCase: CreateEnvironmentVariableUseCase, + private val readUseCase: ReadEnvironmentVariableUseCase, + private val updateUseCase: UpdateEnvironmentVariableUseCase, + private val deleteUseCase: DeleteEnvironmentVariableUseCase, +) : ConfigurationServiceGrpc.ConfigurationServiceImplBase() { + + override fun createEnvironmentVariable( + request: CreateEnvironmentVariableRequest, + responseObserver: StreamObserver, + ) { + val result = createUseCase.create( + CreateEnvironmentVariableCommand( + key = request.key, + value = request.value, + description = if (request.hasDescription()) request.description else null, + ) + ) + responseObserver.onNext(result.toResponse()) + responseObserver.onCompleted() + } + + override fun getEnvironmentVariable( + request: GetEnvironmentVariableRequest, + responseObserver: StreamObserver, + ) { + val result = readUseCase.findByKey(request.key) + responseObserver.onNext(result.toResponse()) + responseObserver.onCompleted() + } + + override fun getAllEnvironmentVariables( + request: GetAllEnvironmentVariablesRequest, + responseObserver: StreamObserver, + ) { + val items = readUseCase.findAll().map { it.toResponse() } + responseObserver.onNext( + GetAllEnvironmentVariablesResponse.newBuilder() + .addAllItems(items) + .build() + ) + responseObserver.onCompleted() + } + + override fun updateEnvironmentVariable( + request: UpdateEnvironmentVariableRequest, + responseObserver: StreamObserver, + ) { + val result = updateUseCase.update( + UpdateEnvironmentVariableCommand( + key = request.key, + value = request.value, + description = if (request.hasDescription()) request.description else null, + ) + ) + responseObserver.onNext(result.toResponse()) + responseObserver.onCompleted() + } + + override fun deleteEnvironmentVariable( + request: DeleteEnvironmentVariableRequest, + responseObserver: StreamObserver, + ) { + deleteUseCase.delete(request.key) + responseObserver.onNext( + DeleteEnvironmentVariableResponse.newBuilder() + .setSuccess(true) + .build() + ) + responseObserver.onCompleted() + } + + private fun hs.kr.entrydsm.configuration.domain.EnvironmentVariable.toResponse(): EnvironmentVariableResponse { + val builder = EnvironmentVariableResponse.newBuilder() + .setId(id ?: 0L) + .setKey(key) + .setValue(value) + description?.let { builder.setDescription(it) } + return builder.build() + } +} From e1b6e0abccff46a0ab663e752ae3cc4437959372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B7=B8=EB=B6=84?= <1210thatman@gmail.com> Date: Sun, 10 May 2026 17:05:32 +0900 Subject: [PATCH 7/7] =?UTF-8?q?feat(configuration):=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EB=B6=80=ED=8A=B8=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=9E=A9=20=EC=84=A4=EC=A0=95=20#36?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- .../configuration-bootstrap/deps.bzl | 2 ++ .../src/main/resources/application.yaml | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/systems/configuration/configuration-bootstrap/deps.bzl b/systems/configuration/configuration-bootstrap/deps.bzl index bfdb5ae..4d5535f 100644 --- a/systems/configuration/configuration-bootstrap/deps.bzl +++ b/systems/configuration/configuration-bootstrap/deps.bzl @@ -1,11 +1,13 @@ SPRING_DEPS = [ "@maven//:org_springframework_boot_spring_boot_starter_web", "@maven//:org_springframework_boot_spring_boot_starter_actuator", + "@maven//:org_springframework_boot_spring_boot_starter_data_jpa", ] KOTLIN_DEPS = [ "@maven//:org_jetbrains_kotlin_kotlin_reflect", "@maven//:com_fasterxml_jackson_module_jackson_module_kotlin", + "@maven//:com_mysql_mysql_connector_j", ] TEST_DEPS = [ diff --git a/systems/configuration/configuration-bootstrap/src/main/resources/application.yaml b/systems/configuration/configuration-bootstrap/src/main/resources/application.yaml index 5c1fdd3..f92a34d 100644 --- a/systems/configuration/configuration-bootstrap/src/main/resources/application.yaml +++ b/systems/configuration/configuration-bootstrap/src/main/resources/application.yaml @@ -5,8 +5,25 @@ spring: default: local main: lazy-initialization: true + datasource: + url: jdbc:mysql://localhost:3306/configuration_db?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true + username: ${DB_USERNAME:root} + password: ${DB_PASSWORD:password} + driver-class-name: com.mysql.cj.jdbc.Driver + jpa: + hibernate: + ddl-auto: validate + show-sql: false + properties: + hibernate: + dialect: org.hibernate.dialect.MySQLDialect + server: shutdown: graceful + +grpc: + port: ${GRPC_PORT:9090} + management: endpoints: web: @@ -16,6 +33,7 @@ management: health: probes: enabled: true + logging: level: root: INFO