feat: ProducerのBeanを作成できるように

This commit is contained in:
usbharu 2024-05-06 16:55:57 +09:00
parent 3a541fa4b0
commit 5ef130c94f
21 changed files with 292 additions and 34 deletions

View File

@ -192,6 +192,7 @@ dependencies {
implementation(libs.bundles.apache.tika) implementation(libs.bundles.apache.tika)
implementation(libs.bundles.openapi) implementation(libs.bundles.openapi)
implementation(libs.bundles.kjob) implementation(libs.bundles.kjob)
implementation(libs.bundles.owl.producer)
implementation(libs.bundles.spring.boot.oauth2) implementation(libs.bundles.spring.boot.oauth2)
implementation(libs.bundles.spring.boot.data.mongodb) implementation(libs.bundles.spring.boot.data.mongodb)
implementation(libs.bundles.spring.boot.data.mongodb) implementation(libs.bundles.spring.boot.data.mongodb)
@ -230,7 +231,7 @@ dependencies {
implementation("dev.usbharu:http-signature:1.0.0") implementation("dev.usbharu:http-signature:1.0.0")
implementation("dev.usbharu:emoji-kt:2.0.0") implementation("dev.usbharu:emoji-kt:2.0.0")
implementation("dev.usbharu:owl-producer-default:0.0.1")
testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("org.springframework.boot:spring-boot-starter-test")

View File

@ -0,0 +1,68 @@
/*
* Copyright (C) 2024 usbharu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.usbharu.hideout.application.config
import dev.usbharu.owl.common.retry.RetryPolicyFactory
import dev.usbharu.owl.producer.api.OWL
import dev.usbharu.owl.producer.api.OwlProducer
import dev.usbharu.owl.producer.defaultimpl.DEFAULT
import dev.usbharu.owl.producer.embedded.EMBEDDED
import dev.usbharu.owl.producer.embedded.EMBEDDED_GRPC
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration
class OwlConfig(private val producerConfig: ProducerConfig) {
@Bean
fun producer(retryPolicyFactory: RetryPolicyFactory? = null): OwlProducer {
return when (producerConfig.mode) {
ProducerMode.EMBEDDED -> {
OWL(EMBEDDED) {
if (retryPolicyFactory != null) {
this.retryPolicyFactory = retryPolicyFactory
}
if (producerConfig.port != null) {
this.port = producerConfig.port.toString()
}
}
}
ProducerMode.GRPC -> {
OWL(EMBEDDED_GRPC) {
}
}
ProducerMode.EMBEDDED_GRPC -> {
OWL(DEFAULT) {
}
}
}
}
}
@ConfigurationProperties("hideout.owl.producer")
data class ProducerConfig(val mode: ProducerMode = ProducerMode.EMBEDDED, val port: Int? = null)
enum class ProducerMode {
GRPC,
EMBEDDED,
EMBEDDED_GRPC
}

View File

@ -1,6 +1,9 @@
hideout: hideout:
url: "https://test-hideout.usbharu.dev" url: "https://test-hideout.usbharu.dev"
use-mongodb: true use-mongodb: true
owl:
producer:
standalone: embedded
security: security:
jwt: jwt:
generate: true generate: true

View File

@ -11,6 +11,7 @@ repositories {
dependencies { dependencies {
testImplementation(kotlin("test")) testImplementation(kotlin("test"))
implementation("dev.usbharu:owl-consumer:0.0.1")
} }
tasks.test { tasks.test {

View File

@ -1,5 +0,0 @@
package dev.usbharu
fun main() {
println("Hello World!")
}

View File

@ -0,0 +1,30 @@
/*
* Copyright (C) 2024 usbharu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.usbharu.hideout.worker
import dev.usbharu.owl.consumer.TaskRequest
import dev.usbharu.owl.consumer.TaskResult
import dev.usbharu.owl.consumer.TaskRunner
class DeliverAcceptTaskRunner : TaskRunner {
override val name: String
get() = ""
override suspend fun run(taskRequest: TaskRequest): TaskResult {
TODO("Not yet implemented")
}
}

View File

@ -10,6 +10,7 @@ swagger = "2.2.6"
serialization = "1.6.3" serialization = "1.6.3"
kjob = "0.6.0" kjob = "0.6.0"
tika = "2.9.1" tika = "2.9.1"
owl = "0.0.1"
[libraries] [libraries]
@ -55,6 +56,10 @@ apache-tika-parsers = { module = "org.apache.tika:tika-parsers", version.ref = "
kjon-core = { module = "org.drewcarlson:kjob-core", version.ref = "kjob" } kjon-core = { module = "org.drewcarlson:kjob-core", version.ref = "kjob" }
kjon-mongo = { module = "org.drewcarlson:kjob-mongo", version.ref = "kjob" } kjon-mongo = { module = "org.drewcarlson:kjob-mongo", version.ref = "kjob" }
owl-producer-api = { module = "dev.usbharu:owl-producer-api", version.ref = "owl" }
owl-producer-default = { module = "dev.usbharu:owl-producer-default", version.ref = "owl" }
owl-producer-embedded = { module = "dev.usbharu:owl-producer-embedded", version.ref = "owl" }
[bundles] [bundles]
exposed = ["exposed-core", "exposed-java-time", "exposed-jdbc", "exposed-spring"] exposed = ["exposed-core", "exposed-java-time", "exposed-jdbc", "exposed-spring"]
@ -66,6 +71,7 @@ openapi = ["jakarta-annotation", "jakarta-validation", "swagger-annotations", "s
serialization = ["serialization-core", "serialization-json"] serialization = ["serialization-core", "serialization-json"]
apache-tika = ["apache-tika-core", "apache-tika-parsers"] apache-tika = ["apache-tika-core", "apache-tika-parsers"]
kjob = ["kjon-core", "kjon-mongo"] kjob = ["kjon-core", "kjon-mongo"]
owl-producer = ["owl-producer-api", "owl-producer-default", "owl-producer-embedded"]
[plugins] [plugins]

View File

@ -16,9 +16,9 @@
package dev.usbharu.owl.broker package dev.usbharu.owl.broker
import dev.usbharu.owl.broker.service.DefaultRetryPolicyFactory import dev.usbharu.owl.common.retry.DefaultRetryPolicyFactory
import dev.usbharu.owl.broker.service.RetryPolicyFactory
import dev.usbharu.owl.common.retry.ExponentialRetryPolicy import dev.usbharu.owl.common.retry.ExponentialRetryPolicy
import dev.usbharu.owl.common.retry.RetryPolicyFactory
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.koin.core.context.startKoin import org.koin.core.context.startKoin
import org.koin.dsl.module import org.koin.dsl.module

View File

@ -21,3 +21,9 @@ import org.koin.core.module.Module
interface ModuleContext { interface ModuleContext {
fun module():Module fun module():Module
} }
data object EmptyModuleContext : ModuleContext {
override fun module(): Module {
return org.koin.dsl.module { }
}
}

View File

@ -24,6 +24,7 @@ import dev.usbharu.owl.broker.domain.model.task.TaskRepository
import dev.usbharu.owl.broker.domain.model.taskdefinition.TaskDefinitionRepository import dev.usbharu.owl.broker.domain.model.taskdefinition.TaskDefinitionRepository
import dev.usbharu.owl.broker.domain.model.taskresult.TaskResult import dev.usbharu.owl.broker.domain.model.taskresult.TaskResult
import dev.usbharu.owl.broker.domain.model.taskresult.TaskResultRepository import dev.usbharu.owl.broker.domain.model.taskresult.TaskResultRepository
import dev.usbharu.owl.common.retry.RetryPolicyFactory
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import org.koin.core.annotation.Singleton import org.koin.core.annotation.Singleton

View File

@ -21,6 +21,7 @@ import dev.usbharu.owl.broker.domain.model.task.Task
import dev.usbharu.owl.broker.domain.model.task.TaskRepository import dev.usbharu.owl.broker.domain.model.task.TaskRepository
import dev.usbharu.owl.broker.domain.model.taskdefinition.TaskDefinitionRepository import dev.usbharu.owl.broker.domain.model.taskdefinition.TaskDefinitionRepository
import dev.usbharu.owl.common.property.PropertyValue import dev.usbharu.owl.common.property.PropertyValue
import dev.usbharu.owl.common.retry.RetryPolicyFactory
import org.koin.core.annotation.Singleton import org.koin.core.annotation.Singleton
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.time.Instant import java.time.Instant

View File

@ -14,10 +14,9 @@
* limitations under the License. * limitations under the License.
*/ */
package dev.usbharu.owl.broker.service package dev.usbharu.owl.common.retry
import dev.usbharu.owl.broker.domain.exception.service.RetryPolicyNotFoundException
import dev.usbharu.owl.common.retry.RetryPolicy
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
interface RetryPolicyFactory { interface RetryPolicyFactory {

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package dev.usbharu.owl.broker.domain.exception.service package dev.usbharu.owl.common.retry
class RetryPolicyNotFoundException : RuntimeException { class RetryPolicyNotFoundException : RuntimeException {
constructor() : super() constructor() : super()

View File

@ -27,7 +27,8 @@ package dev.usbharu.owl.producer.api
*/ */
fun <P : OwlProducer, T : OwlProducerBuilder<P, C>, C : OwlProducerConfig> OWL( fun <P : OwlProducer, T : OwlProducerBuilder<P, C>, C : OwlProducerConfig> OWL(
owlProducerBuilder: T, owlProducerBuilder: T,
configBlock: C.() -> Unit configBlock: C.() -> Unit = {},
) { ): P {
owlProducerBuilder.apply(owlProducerBuilder.config().apply { configBlock() }) owlProducerBuilder.apply(owlProducerBuilder.config().apply { configBlock() })
return owlProducerBuilder.build()
} }

View File

@ -15,6 +15,7 @@ dependencies {
implementation(project(":owl-broker")) implementation(project(":owl-broker"))
implementation(platform("io.insert-koin:koin-bom:3.5.3")) implementation(platform("io.insert-koin:koin-bom:3.5.3"))
implementation("io.insert-koin:koin-core") implementation("io.insert-koin:koin-core")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")
} }
tasks.test { tasks.test {

View File

@ -16,9 +16,8 @@
package dev.usbharu.owl.producer.embedded package dev.usbharu.owl.producer.embedded
import dev.usbharu.owl.broker.ModuleContext
import dev.usbharu.owl.broker.OwlBrokerApplication import dev.usbharu.owl.broker.OwlBrokerApplication
import dev.usbharu.owl.broker.service.RetryPolicyFactory import dev.usbharu.owl.common.retry.RetryPolicyFactory
import dev.usbharu.owl.common.task.PublishedTask import dev.usbharu.owl.common.task.PublishedTask
import dev.usbharu.owl.common.task.Task import dev.usbharu.owl.common.task.Task
import dev.usbharu.owl.common.task.TaskDefinition import dev.usbharu.owl.common.task.TaskDefinition
@ -29,10 +28,7 @@ import org.koin.dsl.module
import org.koin.ksp.generated.defaultModule import org.koin.ksp.generated.defaultModule
class EmbeddedGrpcOwlProducer( class EmbeddedGrpcOwlProducer(
private val moduleContext: ModuleContext, private val config: EmbeddedGrpcOwlProducerConfig,
private val retryPolicyFactory: RetryPolicyFactory,
private val port: Int,
private val owlProducer: OwlProducer,
) : OwlProducer { ) : OwlProducer {
private lateinit var application: Koin private lateinit var application: Koin
@ -43,20 +39,20 @@ class EmbeddedGrpcOwlProducer(
val module = module { val module = module {
single<RetryPolicyFactory> { single<RetryPolicyFactory> {
retryPolicyFactory config.retryPolicyFactory
} }
} }
modules(module, defaultModule, moduleContext.module()) modules(module, defaultModule, config.moduleContext.module())
}.koin }.koin
application.get<OwlBrokerApplication>().start(port) application.get<OwlBrokerApplication>().start(config.port.toInt())
} }
override suspend fun <T : Task> registerTask(taskDefinition: TaskDefinition<T>) { override suspend fun <T : Task> registerTask(taskDefinition: TaskDefinition<T>) {
owlProducer.registerTask(taskDefinition) config.owlProducer.registerTask(taskDefinition)
} }
override suspend fun <T : Task> publishTask(task: T): PublishedTask<T> { override suspend fun <T : Task> publishTask(task: T): PublishedTask<T> {
return owlProducer.publishTask(task) return config.owlProducer.publishTask(task)
} }
} }

View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2024 usbharu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.usbharu.owl.producer.embedded
import dev.usbharu.owl.producer.api.OwlProducerBuilder
class EmbeddedGrpcOwlProducerBuilder : OwlProducerBuilder<EmbeddedGrpcOwlProducer, EmbeddedGrpcOwlProducerConfig> {
private var config = config()
override fun config(): EmbeddedGrpcOwlProducerConfig {
return EmbeddedGrpcOwlProducerConfig()
}
override fun build(): EmbeddedGrpcOwlProducer {
return EmbeddedGrpcOwlProducer(
config
)
}
override fun apply(owlProducerConfig: EmbeddedGrpcOwlProducerConfig) {
this.config = owlProducerConfig
}
}
val EMBEDDED_GRPC by lazy { EmbeddedGrpcOwlProducerBuilder() }

View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2024 usbharu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.usbharu.owl.producer.embedded
import dev.usbharu.owl.broker.ModuleContext
import dev.usbharu.owl.common.retry.RetryPolicyFactory
import dev.usbharu.owl.producer.api.OwlProducer
import dev.usbharu.owl.producer.api.OwlProducerConfig
class EmbeddedGrpcOwlProducerConfig : OwlProducerConfig {
lateinit var moduleContext: ModuleContext
lateinit var retryPolicyFactory: RetryPolicyFactory
lateinit var port: String
lateinit var owlProducer: OwlProducer
}

View File

@ -16,9 +16,9 @@
package dev.usbharu.owl.producer.embedded package dev.usbharu.owl.producer.embedded
import dev.usbharu.owl.broker.ModuleContext
import dev.usbharu.owl.broker.OwlBrokerApplication import dev.usbharu.owl.broker.OwlBrokerApplication
import dev.usbharu.owl.broker.service.* import dev.usbharu.owl.broker.service.*
import dev.usbharu.owl.common.retry.RetryPolicyFactory
import dev.usbharu.owl.common.task.PublishedTask import dev.usbharu.owl.common.task.PublishedTask
import dev.usbharu.owl.common.task.Task import dev.usbharu.owl.common.task.Task
import dev.usbharu.owl.common.task.TaskDefinition import dev.usbharu.owl.common.task.TaskDefinition
@ -32,10 +32,7 @@ import java.util.*
import dev.usbharu.owl.broker.domain.model.taskdefinition.TaskDefinition as BrokerTaskDefinition import dev.usbharu.owl.broker.domain.model.taskdefinition.TaskDefinition as BrokerTaskDefinition
class EmbeddedOwlProducer( class EmbeddedOwlProducer(
private val moduleContext: ModuleContext, private val embeddedOwlProducerConfig: EmbeddedOwlProducerConfig,
private val retryPolicyFactory: RetryPolicyFactory,
private val name: String,
private val port: Int,
) : OwlProducer { ) : OwlProducer {
private lateinit var producerId: UUID private lateinit var producerId: UUID
@ -50,17 +47,22 @@ class EmbeddedOwlProducer(
val module = module { val module = module {
single<RetryPolicyFactory> { single<RetryPolicyFactory> {
retryPolicyFactory embeddedOwlProducerConfig.retryPolicyFactory
} }
} }
modules(module, defaultModule, moduleContext.module()) modules(module, defaultModule, embeddedOwlProducerConfig.moduleContext.module())
}.koin }.koin
val producerService = application.get<ProducerService>() val producerService = application.get<ProducerService>()
producerId = producerService.registerProducer(RegisterProducerRequest(name, name)) producerId = producerService.registerProducer(
RegisterProducerRequest(
embeddedOwlProducerConfig.name,
embeddedOwlProducerConfig.name
)
)
application.get<OwlBrokerApplication>().start(port) application.get<OwlBrokerApplication>().start(embeddedOwlProducerConfig.port.toInt())
} }
override suspend fun <T : Task> registerTask(taskDefinition: TaskDefinition<T>) { override suspend fun <T : Task> registerTask(taskDefinition: TaskDefinition<T>) {

View File

@ -0,0 +1,51 @@
/*
* Copyright (C) 2024 usbharu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.usbharu.owl.producer.embedded
import dev.usbharu.owl.broker.EmptyModuleContext
import dev.usbharu.owl.common.retry.DefaultRetryPolicyFactory
import dev.usbharu.owl.producer.api.OwlProducerBuilder
class EmbeddedOwlProducerBuilder : OwlProducerBuilder<EmbeddedOwlProducer, EmbeddedOwlProducerConfig> {
var config: EmbeddedOwlProducerConfig = config()
override fun config(): EmbeddedOwlProducerConfig {
val embeddedOwlProducerConfig = EmbeddedOwlProducerConfig()
with(embeddedOwlProducerConfig) {
moduleContext = EmptyModuleContext
retryPolicyFactory = DefaultRetryPolicyFactory(emptyMap())
name = "embedded-owl-producer"
port = "50051"
}
return embeddedOwlProducerConfig
}
override fun build(): EmbeddedOwlProducer {
return EmbeddedOwlProducer(
config
)
}
override fun apply(owlProducerConfig: EmbeddedOwlProducerConfig) {
this.config = owlProducerConfig
}
}
val EMBEDDED by lazy { EmbeddedOwlProducerBuilder() }

View File

@ -0,0 +1,28 @@
/*
* Copyright (C) 2024 usbharu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.usbharu.owl.producer.embedded
import dev.usbharu.owl.broker.ModuleContext
import dev.usbharu.owl.common.retry.RetryPolicyFactory
import dev.usbharu.owl.producer.api.OwlProducerConfig
class EmbeddedOwlProducerConfig : OwlProducerConfig {
lateinit var moduleContext: ModuleContext
lateinit var retryPolicyFactory: RetryPolicyFactory
lateinit var name: String
lateinit var port: String
}