From 1c809113651905cb92c05aa58f9af98f095e1657 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 13 Sep 2024 13:40:52 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=E3=83=89=E3=83=A1=E3=82=A4=E3=83=B3?= =?UTF-8?q?=E3=82=A4=E3=83=99=E3=83=B3=E3=83=88=E3=81=AE=E3=82=B5=E3=83=96?= =?UTF-8?q?=E3=82=B9=E3=82=AF=E3=83=A9=E3=82=A4=E3=83=90=E3=83=BC=E4=B8=80?= =?UTF-8?q?=E8=A6=A7=E3=82=92=E5=87=BA=E5=8A=9B=E3=81=A7=E3=81=8D=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- develop/docker-compose.yml | 2 - .../subscribers/DomainEventSubscriber.kt | 1 + ...isterLocalUserSetHomeTimelineSubscriber.kt | 17 +++++--- ...isterTimelineSetTimelineStoreSubscriber.kt | 11 +++-- .../subscribers/SubscriberRunner.kt | 37 +++++++++++++++- .../TimelinePostCreateSubscriber.kt | 11 +++-- .../TimelineRelationshipFollowSubscriber.kt | 40 +++++++++-------- .../TimelineRelationshipUnfollowSubscriber.kt | 43 ++++++++++--------- .../SpringFrameworkDomainEventPublisher.kt | 12 +++++- .../SpringFrameworkDomainEventSubscriber.kt | 43 +++++++++++++++---- 10 files changed, 151 insertions(+), 66 deletions(-) diff --git a/develop/docker-compose.yml b/develop/docker-compose.yml index 4abaed5f..630152e8 100644 --- a/develop/docker-compose.yml +++ b/develop/docker-compose.yml @@ -30,7 +30,6 @@ services: - "9200:9200" volumes: - elasticsearch-data:/usr/share/elasticsearch/data - restart: always kibana: image: docker.elastic.co/kibana/kibana:7.17.24 container_name: kibana @@ -42,7 +41,6 @@ services: - ELASTICSEARCH_PASSWORD=Passw0rd depends_on: - elasticsearch - restart: always fluentd: build: ./fluentd diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/DomainEventSubscriber.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/DomainEventSubscriber.kt index 364bf92a..af70e1ef 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/DomainEventSubscriber.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/DomainEventSubscriber.kt @@ -5,6 +5,7 @@ import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody interface DomainEventSubscriber { fun subscribe(eventName: String, domainEventConsumer: DomainEventConsumer) + fun getSubscribers(): Map>> } typealias DomainEventConsumer = suspend (DomainEvent) -> Unit diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterLocalUserSetHomeTimelineSubscriber.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterLocalUserSetHomeTimelineSubscriber.kt index a63918ee..776c040c 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterLocalUserSetHomeTimelineSubscriber.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterLocalUserSetHomeTimelineSubscriber.kt @@ -3,19 +3,22 @@ package dev.usbharu.hideout.core.application.domainevent.subscribers import dev.usbharu.hideout.core.domain.event.userdetail.UserDetailEvent import dev.usbharu.hideout.core.domain.event.userdetail.UserDetailEventBody import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous +import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent import org.springframework.stereotype.Component @Component class RegisterLocalUserSetHomeTimelineSubscriber( private val domainEventSubscriber: DomainEventSubscriber, private val userRegisterHomeTimelineApplicationService: UserRegisterHomeTimelineApplicationService -) : Subscriber { +) : Subscriber, DomainEventConsumer { override fun init() { - domainEventSubscriber.subscribe(UserDetailEvent.CREATE.eventName) { - userRegisterHomeTimelineApplicationService.execute( - RegisterHomeTimeline(it.body.getUserDetail().id), - Anonymous - ) - } + domainEventSubscriber.subscribe(UserDetailEvent.CREATE.eventName, this) + } + + override suspend fun invoke(p1: DomainEvent) { + userRegisterHomeTimelineApplicationService.execute( + RegisterHomeTimeline(p1.body.getUserDetail().id), + Anonymous + ) } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterTimelineSetTimelineStoreSubscriber.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterTimelineSetTimelineStoreSubscriber.kt index 2b8ec1cb..05c92128 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterTimelineSetTimelineStoreSubscriber.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterTimelineSetTimelineStoreSubscriber.kt @@ -5,17 +5,20 @@ import dev.usbharu.hideout.core.application.timeline.SetTimleineStore import dev.usbharu.hideout.core.domain.event.timeline.TimelineEvent import dev.usbharu.hideout.core.domain.event.timeline.TimelineEventBody import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous +import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent import org.springframework.stereotype.Component @Component class RegisterTimelineSetTimelineStoreSubscriber( private val domainEventSubscriber: DomainEventSubscriber, private val setTimelineToTimelineStoreApplicationService: SetTimelineToTimelineStoreApplicationService -) : Subscriber { +) : Subscriber, DomainEventConsumer { override fun init() { - domainEventSubscriber.subscribe(TimelineEvent.CREATE.eventName) { - setTimelineToTimelineStoreApplicationService.execute(SetTimleineStore(it.body.getTimelineId()), Anonymous) - } + domainEventSubscriber.subscribe(TimelineEvent.CREATE.eventName, this) + } + + override suspend fun invoke(p1: DomainEvent) { + setTimelineToTimelineStoreApplicationService.execute(SetTimleineStore(p1.body.getTimelineId()), Anonymous) } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/SubscriberRunner.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/SubscriberRunner.kt index 1990c2f6..fe04ccbc 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/SubscriberRunner.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/SubscriberRunner.kt @@ -1,12 +1,47 @@ package dev.usbharu.hideout.core.application.domainevent.subscribers +import org.slf4j.LoggerFactory import org.springframework.boot.ApplicationArguments import org.springframework.boot.ApplicationRunner import org.springframework.stereotype.Component @Component -class SubscriberRunner(private val subscribers: List) : ApplicationRunner { +class SubscriberRunner( + private val subscribers: List, + private val domainEventSubscriber: DomainEventSubscriber +) : ApplicationRunner { override fun run(args: ApplicationArguments?) { subscribers.forEach { it.init() } + + if (logger.isDebugEnabled) { + val stringListMap = domainEventSubscriber.getSubscribers() + + val header = """ + |====== Domain Event Subscribers Report ===== + | + | + | + """.trimMargin() + + val value = stringListMap.map { + it.key + "\n\t" + it.value.joinToString("\n", "[", "]") { suspendFunction1 -> + suspendFunction1::class.qualifiedName.orEmpty() + } + }.joinToString("\n\n\n") + + val footer = """ + | + | + | + |===== Domain Event Subscribers Report ===== + """.trimMargin() + + logger.debug("{}{}{}", header, value, footer) + } + + } + + companion object { + private val logger = LoggerFactory.getLogger(SubscriberRunner::class.java) } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelinePostCreateSubscriber.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelinePostCreateSubscriber.kt index 663367b2..3252e2bc 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelinePostCreateSubscriber.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelinePostCreateSubscriber.kt @@ -5,16 +5,19 @@ import dev.usbharu.hideout.core.application.timeline.TimelineAddPostApplicationS import dev.usbharu.hideout.core.domain.event.post.PostEvent import dev.usbharu.hideout.core.domain.event.post.PostEventBody import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous +import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent import org.springframework.stereotype.Component @Component class TimelinePostCreateSubscriber( private val timelineAddPostApplicationService: TimelineAddPostApplicationService, private val domainEventSubscriber: DomainEventSubscriber, -) : Subscriber { +) : Subscriber, DomainEventConsumer { override fun init() { - domainEventSubscriber.subscribe(PostEvent.CREATE.eventName) { - timelineAddPostApplicationService.execute(AddPost(it.body.getPostId()), Anonymous) - } + domainEventSubscriber.subscribe(PostEvent.CREATE.eventName, this) + } + + override suspend fun invoke(p1: DomainEvent) { + timelineAddPostApplicationService.execute(AddPost(p1.body.getPostId()), Anonymous) } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelineRelationshipFollowSubscriber.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelineRelationshipFollowSubscriber.kt index 0707c496..cbef86c0 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelineRelationshipFollowSubscriber.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelineRelationshipFollowSubscriber.kt @@ -7,6 +7,7 @@ import dev.usbharu.hideout.core.domain.event.relationship.RelationshipEvent import dev.usbharu.hideout.core.domain.event.relationship.RelationshipEventBody import dev.usbharu.hideout.core.domain.model.timelinerelationship.Visible import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository +import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent import org.slf4j.LoggerFactory import org.springframework.stereotype.Component @@ -15,28 +16,31 @@ class TimelineRelationshipFollowSubscriber( private val userAddTimelineRelationshipApplicationService: UserAddTimelineRelationshipApplicationService, private val userDetailRepository: UserDetailRepository, private val domainEventSubscriber: DomainEventSubscriber -) : Subscriber { +) : Subscriber, DomainEventConsumer { override fun init() { - domainEventSubscriber.subscribe(RelationshipEvent.ACCEPT_FOLLOW.eventName) { - val relationship = it.body.getRelationship() - val userDetail = userDetailRepository.findByActorId(relationship.actorId.id) - ?: throw InternalServerException("Userdetail ${relationship.actorId} not found by actorid.") - if (userDetail.homeTimelineId == null) { - logger.warn("Home timeline for ${relationship.actorId} is not found") - return@subscribe - } + domainEventSubscriber.subscribe(RelationshipEvent.ACCEPT_FOLLOW.eventName, this) + } - @Suppress("UnsafeCallOnNullableType") - userAddTimelineRelationshipApplicationService.execute( - AddTimelineRelationship( - userDetail.homeTimelineId!!, - relationship.targetActorId, - Visible.FOLLOWERS - ), - it.body.principal - ) + + override suspend fun invoke(p1: DomainEvent) { + val relationship = p1.body.getRelationship() + val userDetail = userDetailRepository.findByActorId(relationship.actorId.id) + ?: throw InternalServerException("Userdetail ${relationship.actorId} not found by actorid.") + if (userDetail.homeTimelineId == null) { + logger.warn("Home timeline for ${relationship.actorId} is not found") + return } + + @Suppress("UnsafeCallOnNullableType") + userAddTimelineRelationshipApplicationService.execute( + AddTimelineRelationship( + userDetail.homeTimelineId!!, + relationship.targetActorId, + Visible.FOLLOWERS + ), + p1.body.principal + ) } companion object { diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelineRelationshipUnfollowSubscriber.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelineRelationshipUnfollowSubscriber.kt index 0430a7a2..0fc5b665 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelineRelationshipUnfollowSubscriber.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelineRelationshipUnfollowSubscriber.kt @@ -6,6 +6,7 @@ import dev.usbharu.hideout.core.domain.event.relationship.RelationshipEvent import dev.usbharu.hideout.core.domain.event.relationship.RelationshipEventBody import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationshipRepository import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository +import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent import org.slf4j.LoggerFactory import org.springframework.stereotype.Component @@ -15,29 +16,31 @@ class TimelineRelationshipUnfollowSubscriber( private val userRemoveTimelineRelationshipApplicationService: UserRemoveTimelineRelationshipApplicationService, private val userDetailRepository: UserDetailRepository, private val timelineRelationshipRepository: TimelineRelationshipRepository, -) : Subscriber { +) : Subscriber, DomainEventConsumer { override fun init() { - domainEventSubscriber.subscribe(RelationshipEvent.UNFOLLOW.eventName) { - val relationship = it.body.getRelationship() - val userDetail = userDetailRepository.findByActorId(relationship.actorId.id) ?: throw IllegalStateException( - "UserDetail ${relationship.actorId} not found by actorId." - ) - if (userDetail.homeTimelineId == null) { - logger.warn("HomeTimeline for ${userDetail.id} not found.") - return@subscribe - } + domainEventSubscriber.subscribe(RelationshipEvent.UNFOLLOW.eventName, this) + } - val timelineRelationship = timelineRelationshipRepository.findByTimelineIdAndActorId( - userDetail.homeTimelineId!!, - relationship.targetActorId - ) - ?: throw IllegalStateException("TimelineRelationship ${userDetail.homeTimelineId} to ${relationship.targetActorId} not found by timelineId and ActorId") - - userRemoveTimelineRelationshipApplicationService.execute( - RemoveTimelineRelationship(timelineRelationship.id), - it.body.principal - ) + override suspend fun invoke(p1: DomainEvent) { + val relationship = p1.body.getRelationship() + val userDetail = userDetailRepository.findByActorId(relationship.actorId.id) ?: throw IllegalStateException( + "UserDetail ${relationship.actorId} not found by actorId." + ) + if (userDetail.homeTimelineId == null) { + logger.warn("HomeTimeline for ${userDetail.id} not found.") + return } + + val timelineRelationship = timelineRelationshipRepository.findByTimelineIdAndActorId( + userDetail.homeTimelineId!!, + relationship.targetActorId + ) + ?: throw IllegalStateException("TimelineRelationship ${userDetail.homeTimelineId} to ${relationship.targetActorId} not found by timelineId and ActorId") + + userRemoveTimelineRelationshipApplicationService.execute( + RemoveTimelineRelationship(timelineRelationship.id), + p1.body.principal + ) } companion object { diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/domainevent/SpringFrameworkDomainEventPublisher.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/domainevent/SpringFrameworkDomainEventPublisher.kt index bf442ea2..b278e1d9 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/domainevent/SpringFrameworkDomainEventPublisher.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/domainevent/SpringFrameworkDomainEventPublisher.kt @@ -18,7 +18,9 @@ package dev.usbharu.hideout.core.infrastructure.springframework.domainevent import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher +import dev.usbharu.hideout.core.infrastructure.springframework.ApplicationRequestLogInterceptor import org.slf4j.LoggerFactory +import org.slf4j.MDC import org.springframework.context.ApplicationEventPublisher import org.springframework.stereotype.Component @@ -27,10 +29,18 @@ class SpringFrameworkDomainEventPublisher(private val applicationEventPublisher: DomainEventPublisher { override suspend fun publishEvent(domainEvent: DomainEvent<*>) { logger.trace("Publish ${domainEvent.id} ${domainEvent.name}") - applicationEventPublisher.publishEvent(domainEvent) + + val requestId: String? = MDC.get(ApplicationRequestLogInterceptor.requestId) + val springDomainEvent = SpringDomainEvent( + requestId, domainEvent + ) + + applicationEventPublisher.publishEvent(springDomainEvent) } companion object { private val logger = LoggerFactory.getLogger(SpringFrameworkDomainEventPublisher::class.java) } } + +data class SpringDomainEvent(val requestId: String?, val domainEvent: DomainEvent<*>) \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/domainevent/SpringFrameworkDomainEventSubscriber.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/domainevent/SpringFrameworkDomainEventSubscriber.kt index 184cab62..c0617ec0 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/domainevent/SpringFrameworkDomainEventSubscriber.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/domainevent/SpringFrameworkDomainEventSubscriber.kt @@ -2,9 +2,14 @@ package dev.usbharu.hideout.core.infrastructure.springframework.domainevent import dev.usbharu.hideout.core.application.domainevent.subscribers.DomainEventConsumer import dev.usbharu.hideout.core.application.domainevent.subscribers.DomainEventSubscriber -import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody +import dev.usbharu.hideout.core.infrastructure.springframework.ApplicationRequestLogInterceptor.Companion.requestId +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.slf4j.MDCContext import org.slf4j.LoggerFactory +import org.slf4j.MDC import org.springframework.context.event.EventListener import org.springframework.stereotype.Component @@ -17,15 +22,35 @@ class SpringFrameworkDomainEventSubscriber : DomainEventSubscriber { map.getOrPut(eventName) { mutableListOf() }.add(domainEventConsumer as DomainEventConsumer<*>) } + override fun getSubscribers(): Map>> { + return map + } + @EventListener - suspend fun onDomainEventPublished(domainEvent: DomainEvent<*>) { - logger.trace("Domain Event Published: $domainEvent") - map[domainEvent.name]?.forEach { - try { - it.invoke(domainEvent) - } catch (@Suppress("TooGenericExceptionCaught") e: Exception) { - logger.error("", e) - } + suspend fun onDomainEventPublished(domainEvent: SpringDomainEvent) { + + logger.debug( + "Domain Event Published: {} id: {} requestId: {}", + domainEvent.domainEvent.name, + domainEvent.domainEvent.id, + domainEvent.requestId + ) + coroutineScope { + + map[domainEvent.domainEvent.name]?.map { + async(MDCContext()) { + try { + MDC.put(requestId, domainEvent.requestId) + it.invoke(domainEvent.domainEvent) + } catch (@Suppress("TooGenericExceptionCaught") e: Exception) { + logger.warn("", e) + null + } finally { + MDC.remove(requestId) + } + } + }?.awaitAll() + } }