Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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")
21 changes: 21 additions & 0 deletions contracts/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -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"],
)
52 changes: 52 additions & 0 deletions contracts/proto/configuration.proto
Original file line number Diff line number Diff line change
@@ -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;
}
14 changes: 14 additions & 0 deletions kotlin.MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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")
14 changes: 13 additions & 1 deletion systems/configuration/configuration-adapter-in/deps.bzl
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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<EnvironmentVariableResponse>,
) {
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<EnvironmentVariableResponse>,
) {
val result = readUseCase.findByKey(request.key)
responseObserver.onNext(result.toResponse())
responseObserver.onCompleted()
}

override fun getAllEnvironmentVariables(
request: GetAllEnvironmentVariablesRequest,
responseObserver: StreamObserver<GetAllEnvironmentVariablesResponse>,
) {
val items = readUseCase.findAll().map { it.toResponse() }
responseObserver.onNext(
GetAllEnvironmentVariablesResponse.newBuilder()
.addAllItems(items)
.build()
)
responseObserver.onCompleted()
}

override fun updateEnvironmentVariable(
request: UpdateEnvironmentVariableRequest,
responseObserver: StreamObserver<EnvironmentVariableResponse>,
) {
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<DeleteEnvironmentVariableResponse>,
) {
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()
}
}
6 changes: 5 additions & 1 deletion systems/configuration/configuration-adapter-out/deps.bzl
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
Original file line number Diff line number Diff line change
@@ -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<EnvironmentVariable> =
environmentVariableJpaRepository.findAll().map { it.toDomain() }

override fun deleteByKey(key: String) =
environmentVariableJpaRepository.deleteByKey(key)

override fun existsByKey(key: String): Boolean =
environmentVariableJpaRepository.existsByKey(key)
}
Original file line number Diff line number Diff line change
@@ -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,
)
}
}
Original file line number Diff line number Diff line change
@@ -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<EnvironmentVariableJpaEntity, Long> {
fun findByKey(key: String): EnvironmentVariableJpaEntity?
fun deleteByKey(key: String)
fun existsByKey(key: String): Boolean
}
5 changes: 4 additions & 1 deletion systems/configuration/configuration-application/deps.bzl
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
Loading
Loading