From 8d244b74c1675dbaa725d0b2d9269431317342c7 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 16 Aug 2024 02:49:48 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=E3=83=AD=E3=83=BC=E3=82=AB=E3=83=AB?= =?UTF-8?q?=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E8=BF=BD=E5=8A=A0=E6=99=82?= =?UTF-8?q?=E3=81=AB=E8=87=AA=E5=8B=95=E3=81=A7=E3=83=9B=E3=83=BC=E3=83=A0?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=A0=E3=83=A9=E3=82=A4=E3=83=B3=E7=AD=89?= =?UTF-8?q?=E3=82=92=E4=BD=9C=E6=88=90=E3=81=99=E3=82=8B=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../subscribers/RegisterHomeTimeline.kt | 5 ++ ...isterLocalUserSetHomeTimelineSubscriber.kt | 18 +++++- ...isterTimelineSetTimelineStoreSubscriber.kt | 21 +++++++ .../TimelinePostCreateSubscriber.kt | 10 ++-- .../TimelineRelationshipFollowSubscriber.kt | 2 +- ...rRegisterHomeTimelineApplicationService.kt | 40 ++++++++++++++ .../core/application/timeline/AddPost.kt | 5 ++ .../application/timeline/RegisterTimeline.kt | 8 +++ ...melineToTimelineStoreApplicationService.kt | 29 ++++++++++ .../application/timeline/SetTimleineStore.kt | 5 ++ .../TimelineAddPostApplicationService.kt | 29 ++++++++++ .../UserRegisterTimelineApplicationService.kt | 37 +++++++++++++ .../core/domain/event/actor/ActorEvent.kt | 5 +- .../core/domain/event/post/PostEvent.kt | 10 ++-- .../domain/event/timeline/TimelineEvent.kt | 12 +++- .../event/userdetail/UserDetailEvent.kt | 29 ++++++++++ .../core/domain/model/timeline/Timeline.kt | 20 +++++++ .../domain/model/userdetails/UserDetail.kt | 13 +++-- .../DomainEventPublishableRepository.kt | 4 ++ .../UserDetailRepositoryImpl.kt | 55 +++++++++++-------- .../SpringFrameworkDomainEventPublisher.kt | 6 ++ .../SpringFrameworkDomainEventSubscriber.kt | 7 +++ 22 files changed, 328 insertions(+), 42 deletions(-) create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterHomeTimeline.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterTimelineSetTimelineStoreSubscriber.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/UserRegisterHomeTimelineApplicationService.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/AddPost.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/RegisterTimeline.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimelineToTimelineStoreApplicationService.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimleineStore.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/TimelineAddPostApplicationService.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/UserRegisterTimelineApplicationService.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/userdetail/UserDetailEvent.kt diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterHomeTimeline.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterHomeTimeline.kt new file mode 100644 index 00000000..9f2ce4b0 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterHomeTimeline.kt @@ -0,0 +1,5 @@ +package dev.usbharu.hideout.core.application.domainevent.subscribers + +data class RegisterHomeTimeline( + val userDetailId: Long +) 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 2ccceab5..49ed5925 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 @@ -1,9 +1,23 @@ package dev.usbharu.hideout.core.application.domainevent.subscribers -class RegisterLocalUserSetHomeTimelineSubscriber(private val domainEventSubscriber: DomainEventSubscriber) : +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 org.springframework.stereotype.Component + +@Component +class RegisterLocalUserSetHomeTimelineSubscriber( + domainEventSubscriber: DomainEventSubscriber, + private val userRegisterHomeTimelineApplicationService: UserRegisterHomeTimelineApplicationService +) : Subscriber { init { - domainEventSubscriber.subscribe<>() + domainEventSubscriber.subscribe(UserDetailEvent.CREATE.eventName) { + userRegisterHomeTimelineApplicationService.execute( + RegisterHomeTimeline(it.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 new file mode 100644 index 00000000..f1a93dfa --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterTimelineSetTimelineStoreSubscriber.kt @@ -0,0 +1,21 @@ +package dev.usbharu.hideout.core.application.domainevent.subscribers + +import dev.usbharu.hideout.core.application.timeline.SetTimelineToTimelineStoreApplicationService +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 org.springframework.stereotype.Component + +@Component +class RegisterTimelineSetTimelineStoreSubscriber( + domainEventSubscriber: DomainEventSubscriber, + private val setTimelineToTimelineStoreApplicationService: SetTimelineToTimelineStoreApplicationService +) : + Subscriber { + init { + domainEventSubscriber.subscribe(TimelineEvent.CREATE.eventName) { + setTimelineToTimelineStoreApplicationService.execute(SetTimleineStore(it.body.getTimelineId()), Anonymous) + } + } +} \ No newline at end of file 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 8262fcc5..dfcc87ad 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 @@ -1,19 +1,21 @@ package dev.usbharu.hideout.core.application.domainevent.subscribers +import dev.usbharu.hideout.core.application.timeline.AddPost +import dev.usbharu.hideout.core.application.timeline.TimelineAddPostApplicationService import dev.usbharu.hideout.core.domain.event.post.PostEvent import dev.usbharu.hideout.core.domain.event.post.PostEventBody -import dev.usbharu.hideout.core.external.timeline.TimelineStore +import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous import org.slf4j.LoggerFactory import org.springframework.stereotype.Component @Component class TimelinePostCreateSubscriber( - private val timelineStore: TimelineStore, - domainEventSubscriber: DomainEventSubscriber + private val timelineAddPostApplicationService: TimelineAddPostApplicationService, + domainEventSubscriber: DomainEventSubscriber, ) : Subscriber { init { domainEventSubscriber.subscribe(PostEvent.CREATE.eventName) { - timelineStore.addPost(it.body.getPost()) + timelineAddPostApplicationService.execute(AddPost(it.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 4f4cdf0b..bc13d823 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 @@ -32,7 +32,7 @@ class TimelineRelationshipFollowSubscriber( AddTimelineRelationship( TimelineRelationship( TimelineRelationshipId(idGenerateService.generateId()), - userDetail.homeTimelineId, + userDetail.homeTimelineId!!, relationship.targetActorId, Visible.FOLLOWERS ) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/UserRegisterHomeTimelineApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/UserRegisterHomeTimelineApplicationService.kt new file mode 100644 index 00000000..5394e998 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/UserRegisterHomeTimelineApplicationService.kt @@ -0,0 +1,40 @@ +package dev.usbharu.hideout.core.application.domainevent.subscribers + +import dev.usbharu.hideout.core.application.shared.AbstractApplicationService +import dev.usbharu.hideout.core.application.shared.Transaction +import dev.usbharu.hideout.core.domain.model.support.principal.Principal +import dev.usbharu.hideout.core.domain.model.timeline.* +import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId +import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository +import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component + +@Component +class UserRegisterHomeTimelineApplicationService( + private val userDetailRepository: UserDetailRepository, + private val timelineRepository: TimelineRepository, + private val idGenerateService: IdGenerateService, transaction: Transaction, +) : AbstractApplicationService(transaction, logger) { + override suspend fun internalExecute(command: RegisterHomeTimeline, principal: Principal) { + + val userDetail = (userDetailRepository.findById(UserDetailId(command.userDetailId)) + ?: throw IllegalArgumentException("UserDetail ${command.userDetailId} not found.")) + + val timeline = Timeline.create( + TimelineId(idGenerateService.generateId()), + UserDetailId(command.userDetailId), + TimelineName("System-LocalUser-HomeTimeline-${command.userDetailId}"), + TimelineVisibility.PRIVATE, + true + ) + timelineRepository.save(timeline) + userDetail.homeTimelineId = timeline.id + + userDetailRepository.save(userDetail) + } + + companion object { + private val logger = LoggerFactory.getLogger(UserRegisterHomeTimelineApplicationService::class.java) + } +} \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/AddPost.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/AddPost.kt new file mode 100644 index 00000000..bae9fc85 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/AddPost.kt @@ -0,0 +1,5 @@ +package dev.usbharu.hideout.core.application.timeline + +import dev.usbharu.hideout.core.domain.model.post.PostId + +data class AddPost(val postId: PostId) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/RegisterTimeline.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/RegisterTimeline.kt new file mode 100644 index 00000000..4283e651 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/RegisterTimeline.kt @@ -0,0 +1,8 @@ +package dev.usbharu.hideout.core.application.timeline + +import dev.usbharu.hideout.core.domain.model.timeline.TimelineVisibility + +data class RegisterTimeline( + val timelineName: String, + val visibility: TimelineVisibility +) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimelineToTimelineStoreApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimelineToTimelineStoreApplicationService.kt new file mode 100644 index 00000000..f47fcc0f --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimelineToTimelineStoreApplicationService.kt @@ -0,0 +1,29 @@ +package dev.usbharu.hideout.core.application.timeline + +import dev.usbharu.hideout.core.application.shared.AbstractApplicationService +import dev.usbharu.hideout.core.application.shared.Transaction +import dev.usbharu.hideout.core.domain.model.support.principal.Principal +import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository +import dev.usbharu.hideout.core.external.timeline.TimelineStore +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component + +@Component +class SetTimelineToTimelineStoreApplicationService( + transaction: Transaction, + private val timelineStore: TimelineStore, + private val timelineRepository: TimelineRepository +) : + AbstractApplicationService( + transaction, logger + ) { + override suspend fun internalExecute(command: SetTimleineStore, principal: Principal) { + val findById = timelineRepository.findById(command.timelineId) + ?: throw IllegalArgumentException("Timeline ${command.timelineId} not found") + timelineStore.addTimeline(findById, emptyList()) + } + + companion object { + private val logger = LoggerFactory.getLogger(SetTimelineToTimelineStoreApplicationService::class.java) + } +} \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimleineStore.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimleineStore.kt new file mode 100644 index 00000000..a2257489 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimleineStore.kt @@ -0,0 +1,5 @@ +package dev.usbharu.hideout.core.application.timeline + +import dev.usbharu.hideout.core.domain.model.timeline.TimelineId + +data class SetTimleineStore(val timelineId: TimelineId) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/TimelineAddPostApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/TimelineAddPostApplicationService.kt new file mode 100644 index 00000000..8c907a61 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/TimelineAddPostApplicationService.kt @@ -0,0 +1,29 @@ +package dev.usbharu.hideout.core.application.timeline + +import dev.usbharu.hideout.core.application.shared.AbstractApplicationService +import dev.usbharu.hideout.core.application.shared.Transaction +import dev.usbharu.hideout.core.domain.model.post.PostRepository +import dev.usbharu.hideout.core.domain.model.support.principal.Principal +import dev.usbharu.hideout.core.external.timeline.TimelineStore +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component + +@Component +class TimelineAddPostApplicationService( + private val timelineStore: TimelineStore, + private val postRepository: PostRepository, + transaction: Transaction +) : AbstractApplicationService( + transaction, + logger +) { + override suspend fun internalExecute(command: AddPost, principal: Principal) { + val findById = postRepository.findById(command.postId) + ?: throw IllegalArgumentException("Post ${command.postId} not found.") + timelineStore.addPost(findById) + } + + companion object { + private val logger = LoggerFactory.getLogger(TimelineAddPostApplicationService::class.java) + } +} \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/UserRegisterTimelineApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/UserRegisterTimelineApplicationService.kt new file mode 100644 index 00000000..0660c020 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/UserRegisterTimelineApplicationService.kt @@ -0,0 +1,37 @@ +package dev.usbharu.hideout.core.application.timeline + +import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService +import dev.usbharu.hideout.core.application.shared.Transaction +import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser +import dev.usbharu.hideout.core.domain.model.timeline.Timeline +import dev.usbharu.hideout.core.domain.model.timeline.TimelineId +import dev.usbharu.hideout.core.domain.model.timeline.TimelineName +import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository +import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component + +@Component +class UserRegisterTimelineApplicationService( + private val idGenerateService: IdGenerateService, + private val timelineRepository: TimelineRepository, + transaction: Transaction +) : + LocalUserAbstractApplicationService(transaction, logger) { + override suspend fun internalExecute(command: RegisterTimeline, principal: LocalUser): TimelineId { + val timeline = Timeline.create( + id = TimelineId(idGenerateService.generateId()), + userDetailId = principal.userDetailId, + name = TimelineName(command.timelineName), + visibility = command.visibility, + isSystem = false + ) + + timelineRepository.save(timeline) + return timeline.id + } + + companion object { + private val logger = LoggerFactory.getLogger(UserRegisterTimelineApplicationService::class.java) + } +} \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/actor/ActorEvent.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/actor/ActorEvent.kt index 98f2918a..b4239620 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/actor/ActorEvent.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/actor/ActorEvent.kt @@ -17,6 +17,7 @@ package dev.usbharu.hideout.core.domain.event.actor import dev.usbharu.hideout.core.domain.model.actor.Actor +import dev.usbharu.hideout.core.domain.model.actor.ActorId import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody @@ -24,13 +25,13 @@ class ActorDomainEventFactory(private val actor: Actor) { fun createEvent(actorEvent: ActorEvent): DomainEvent { return DomainEvent.create( actorEvent.eventName, - ActorEventBody(actor), + ActorEventBody(actor.id), actorEvent.collectable ) } } -class ActorEventBody(actor: Actor) : DomainEventBody( +class ActorEventBody(actor: ActorId) : DomainEventBody( mapOf( "actor" to actor ), diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/post/PostEvent.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/post/PostEvent.kt index 52423afd..dd64669b 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/post/PostEvent.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/post/PostEvent.kt @@ -17,7 +17,9 @@ package dev.usbharu.hideout.core.domain.event.post import dev.usbharu.hideout.core.domain.model.actor.Actor +import dev.usbharu.hideout.core.domain.model.actor.ActorId import dev.usbharu.hideout.core.domain.model.post.Post +import dev.usbharu.hideout.core.domain.model.post.PostId import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody @@ -25,14 +27,14 @@ class PostDomainEventFactory(private val post: Post, private val actor: Actor? = fun createEvent(postEvent: PostEvent): DomainEvent { return DomainEvent.create( postEvent.eventName, - PostEventBody(post, actor) + PostEventBody(post.id, actor?.id) ) } } -class PostEventBody(post: Post, actor: Actor?) : DomainEventBody(mapOf("post" to post, "actor" to actor)) { - fun getPost(): Post = toMap()["post"] as Post - fun getActor(): Actor? = toMap()["actor"] as Actor? +class PostEventBody(post: PostId, actor: ActorId?) : DomainEventBody(mapOf("post" to post, "actor" to actor)) { + fun getPostId(): PostId = toMap()["post"] as PostId + fun getActorId(): ActorId? = toMap()["actor"] as ActorId? } enum class PostEvent(val eventName: String) { diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/timeline/TimelineEvent.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/timeline/TimelineEvent.kt index a6d53cf6..af552cfc 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/timeline/TimelineEvent.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/timeline/TimelineEvent.kt @@ -1,16 +1,22 @@ package dev.usbharu.hideout.core.domain.event.timeline import dev.usbharu.hideout.core.domain.model.timeline.Timeline +import dev.usbharu.hideout.core.domain.model.timeline.TimelineId import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody class TimelineEventFactory(private val timeline: Timeline) { fun createEvent(timelineEvent: TimelineEvent): DomainEvent = - DomainEvent.create(timelineEvent.eventName, TimelineEventBody(timeline)) + DomainEvent.create(timelineEvent.eventName, TimelineEventBody(timeline.id)) } -class TimelineEventBody(timeline: Timeline) : DomainEventBody(mapOf("timeline" to timeline)) +class TimelineEventBody(timelineId: TimelineId) : DomainEventBody(mapOf("timeline" to timelineId)) { + fun getTimelineId(): TimelineId { + return toMap()["timeline"] as TimelineId + } +} enum class TimelineEvent(val eventName: String) { - CHANGE_VISIBILITY("ChangeVisibility") + CHANGE_VISIBILITY("ChangeVisibility"), + CREATE("TimelineCreate") } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/userdetail/UserDetailEvent.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/userdetail/UserDetailEvent.kt new file mode 100644 index 00000000..7493e943 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/userdetail/UserDetailEvent.kt @@ -0,0 +1,29 @@ +package dev.usbharu.hideout.core.domain.event.userdetail + +import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail +import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId +import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent +import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody + +class UserDetailDomainEventFactory(private val userDetail: UserDetail) { + fun createEvent(userDetailEvent: UserDetailEvent): DomainEvent { + return DomainEvent.create( + userDetailEvent.eventName, + UserDetailEventBody(userDetail.id) + ) + } +} + +class UserDetailEventBody(userDetail: UserDetailId) : DomainEventBody( + mapOf( + "userDetail" to userDetail + ) +) { + fun getUserDetail(): UserDetailId { + return toMap()["userDetail"] as UserDetailId + } +} + +enum class UserDetailEvent(val eventName: String) { + CREATE("UserDetailCreate"), +} \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timeline/Timeline.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timeline/Timeline.kt index 955b1621..7f09a103 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timeline/Timeline.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timeline/Timeline.kt @@ -25,4 +25,24 @@ class Timeline( var name = name private set + + companion object { + fun create( + id: TimelineId, + userDetailId: UserDetailId, + name: TimelineName, + visibility: TimelineVisibility, + isSystem: Boolean + ): Timeline { + val timeline = Timeline( + id = id, + userDetailId = userDetailId, + name = name, + visibility = visibility, + isSystem = isSystem + ) + timeline.addDomainEvent(TimelineEventFactory(timeline).createEvent(TimelineEvent.CREATE)) + return timeline + } + } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetail.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetail.kt index a272176f..4cd447a7 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetail.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetail.kt @@ -16,18 +16,21 @@ package dev.usbharu.hideout.core.domain.model.userdetails +import dev.usbharu.hideout.core.domain.event.userdetail.UserDetailDomainEventFactory +import dev.usbharu.hideout.core.domain.event.userdetail.UserDetailEvent import dev.usbharu.hideout.core.domain.model.actor.ActorId import dev.usbharu.hideout.core.domain.model.timeline.TimelineId +import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventStorable import java.time.Instant -class UserDetail private constructor( +class UserDetail( val id: UserDetailId, val actorId: ActorId, var password: UserDetailHashedPassword, var autoAcceptFolloweeFollowRequest: Boolean, var lastMigration: Instant? = null, - val homeTimelineId: TimelineId? -) { + var homeTimelineId: TimelineId? +) : DomainEventStorable() { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -49,7 +52,7 @@ class UserDetail private constructor( lastMigration: Instant? = null, homeTimelineId: TimelineId? = null ): UserDetail { - return UserDetail( + val userDetail = UserDetail( id, actorId, password, @@ -57,6 +60,8 @@ class UserDetail private constructor( lastMigration, homeTimelineId ) + userDetail.addDomainEvent(UserDetailDomainEventFactory(userDetail).createEvent(UserDetailEvent.CREATE)) + return userDetail } } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/shared/repository/DomainEventPublishableRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/shared/repository/DomainEventPublishableRepository.kt index 3b385984..ff9776bc 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/shared/repository/DomainEventPublishableRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/shared/repository/DomainEventPublishableRepository.kt @@ -2,12 +2,16 @@ package dev.usbharu.hideout.core.domain.shared.repository import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventStorable +import org.jetbrains.exposed.sql.transactions.TransactionManager import org.springframework.stereotype.Repository @Repository interface DomainEventPublishableRepository { val domainEventPublisher: DomainEventPublisher suspend fun update(entity: T) { + println(entity.getDomainEvents().joinToString()) + val current = TransactionManager.current() + current.registerInterceptor() entity.getDomainEvents().distinctBy { if (it.collectable) { it.name diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt index dc9f5908..b3ed024f 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt @@ -22,6 +22,8 @@ import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailHashedPassword import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository +import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher +import dev.usbharu.hideout.core.domain.shared.repository.DomainEventPublishableRepository import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.javatime.timestamp @@ -30,34 +32,43 @@ import org.slf4j.LoggerFactory import org.springframework.stereotype.Repository @Repository -class UserDetailRepositoryImpl : UserDetailRepository, AbstractRepository() { +class UserDetailRepositoryImpl(override val domainEventPublisher: DomainEventPublisher) : UserDetailRepository, + AbstractRepository(), DomainEventPublishableRepository { override val logger: Logger get() = Companion.logger - override suspend fun save(userDetail: UserDetail): UserDetail = query { - val singleOrNull = - UserDetails.selectAll().where { UserDetails.id eq userDetail.id.id }.forUpdate().singleOrNull() - if (singleOrNull == null) { - UserDetails.insert { - it[id] = userDetail.id.id - it[actorId] = userDetail.actorId.id - it[password] = userDetail.password.password - it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest - it[lastMigration] = userDetail.lastMigration - } - } else { - UserDetails.update({ UserDetails.id eq userDetail.id.id }) { - it[actorId] = userDetail.actorId.id - it[password] = userDetail.password.password - it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest - it[lastMigration] = userDetail.lastMigration + override suspend fun save(userDetail: UserDetail): UserDetail { + val userDetail1 = query { + val singleOrNull = + UserDetails.selectAll().where { UserDetails.id eq userDetail.id.id }.forUpdate().singleOrNull() + if (singleOrNull == null) { + UserDetails.insert { + it[id] = userDetail.id.id + it[actorId] = userDetail.actorId.id + it[password] = userDetail.password.password + it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest + it[lastMigration] = userDetail.lastMigration + } + } else { + UserDetails.update({ UserDetails.id eq userDetail.id.id }) { + it[actorId] = userDetail.actorId.id + it[password] = userDetail.password.password + it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest + it[lastMigration] = userDetail.lastMigration + } } + + userDetail } - return@query userDetail + update(userDetail) + return userDetail1 } - override suspend fun delete(userDetail: UserDetail): Unit = query { - UserDetails.deleteWhere { id eq userDetail.id.id } + override suspend fun delete(userDetail: UserDetail): Unit { + query { + UserDetails.deleteWhere { id eq userDetail.id.id } + } + update(userDetail) } override suspend fun findByActorId(actorId: Long): UserDetail? = query { @@ -89,7 +100,7 @@ class UserDetailRepositoryImpl : UserDetailRepository, AbstractRepository() { } } - private fun userDetail(it: ResultRow) = UserDetail.create( + private fun userDetail(it: ResultRow) = UserDetail( UserDetailId(it[UserDetails.id]), ActorId(it[UserDetails.actorId]), UserDetailHashedPassword(it[UserDetails.password]), 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 40794c1e..bf442ea2 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,6 +18,7 @@ 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 org.slf4j.LoggerFactory import org.springframework.context.ApplicationEventPublisher import org.springframework.stereotype.Component @@ -25,6 +26,11 @@ import org.springframework.stereotype.Component class SpringFrameworkDomainEventPublisher(private val applicationEventPublisher: ApplicationEventPublisher) : DomainEventPublisher { override suspend fun publishEvent(domainEvent: DomainEvent<*>) { + logger.trace("Publish ${domainEvent.id} ${domainEvent.name}") applicationEventPublisher.publishEvent(domainEvent) } + + companion object { + private val logger = LoggerFactory.getLogger(SpringFrameworkDomainEventPublisher::class.java) + } } 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 6c5a148d..64d7c6a0 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 @@ -4,6 +4,7 @@ import dev.usbharu.hideout.core.application.domainevent.subscribers.DomainEventC 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 org.slf4j.LoggerFactory import org.springframework.context.event.EventListener import org.springframework.stereotype.Component @@ -18,11 +19,17 @@ class SpringFrameworkDomainEventSubscriber : DomainEventSubscriber { @EventListener suspend fun onDomainEventPublished(domainEvent: DomainEvent<*>) { + logger.trace("Domain Event Published: $domainEvent") map[domainEvent.name]?.forEach { try { it.invoke(domainEvent) } catch (e: Exception) { + logger.error("", e) } } } + + companion object { + private val logger = LoggerFactory.getLogger(SpringFrameworkDomainEventSubscriber::class.java) + } }