From ab25e136dd90268340f11e1f4d6eef202b1f6844 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 27 Oct 2023 13:22:18 +0900 Subject: [PATCH 1/5] =?UTF-8?q?refactor:=20job=E3=82=92=E5=88=A5=E3=81=AE?= =?UTF-8?q?=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AB=E5=88=87=E3=82=8A=E5=87=BA?= =?UTF-8?q?=E3=81=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/service/ap/APNoteService.kt | 46 +------------ .../hideout/service/ap/APReactionService.kt | 54 +-------------- .../service/ap/APReceiveFollowService.kt | 45 +------------ .../usbharu/hideout/service/ap/APService.kt | 18 +++-- .../ap/job/APReceiveFollowJobService.kt | 8 +++ .../ap/job/APReceiveFollowJobServiceImpl.kt | 61 +++++++++++++++++ .../service/ap/job/ApNoteJobService.kt | 8 +++ .../service/ap/job/ApNoteJobServiceImpl.kt | 67 +++++++++++++++++++ .../service/ap/job/ApReactionJobService.kt | 10 +++ .../ap/job/ApReactionJobServiceImpl.kt | 65 ++++++++++++++++++ .../service/ap/APNoteServiceImplTest.kt | 7 -- .../ap/APReceiveFollowServiceImplTest.kt | 15 +---- 12 files changed, 236 insertions(+), 168 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/ap/job/APReceiveFollowJobService.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/ap/job/APReceiveFollowJobServiceImpl.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApNoteJobService.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApNoteJobServiceImpl.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApReactionJobService.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApReactionJobServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt index 9f4f87e2..6ff134d1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt @@ -1,10 +1,6 @@ package dev.usbharu.hideout.service.ap import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import dev.usbharu.hideout.config.ApplicationConfig -import dev.usbharu.hideout.domain.model.ap.Create -import dev.usbharu.hideout.domain.model.ap.Document import dev.usbharu.hideout.domain.model.ap.Note import dev.usbharu.hideout.domain.model.hideout.entity.Post import dev.usbharu.hideout.domain.model.hideout.entity.Visibility @@ -19,12 +15,10 @@ import dev.usbharu.hideout.query.UserQueryService import dev.usbharu.hideout.repository.PostRepository import dev.usbharu.hideout.service.ap.resource.APResourceResolveService import dev.usbharu.hideout.service.ap.resource.resolve -import dev.usbharu.hideout.service.core.Transaction import dev.usbharu.hideout.service.job.JobQueueParentService import dev.usbharu.hideout.service.post.PostCreateInterceptor import dev.usbharu.hideout.service.post.PostService import io.ktor.client.plugins.* -import kjob.core.job.JobProps import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Deferred import kotlinx.coroutines.Dispatchers @@ -40,7 +34,7 @@ import java.time.Instant interface APNoteService { suspend fun createNote(post: Post) - suspend fun createNoteJob(props: JobProps) + @Cacheable("fetchNote") fun fetchNoteAsync(url: String, targetActor: String? = null): Deferred { @@ -66,12 +60,9 @@ class APNoteServiceImpl( private val postQueryService: PostQueryService, private val mediaQueryService: MediaQueryService, @Qualifier("activitypub") private val objectMapper: ObjectMapper, - private val applicationConfig: ApplicationConfig, private val postService: PostService, private val apResourceResolveService: APResourceResolveService, - private val apRequestService: APRequestService, - private val postBuilder: Post.PostBuilder, - private val transaction: Transaction + private val postBuilder: Post.PostBuilder ) : APNoteService, PostCreateInterceptor { @@ -104,40 +95,7 @@ class APNoteServiceImpl( logger.debug("SUCCESS Create Local Note ${post.url}") } - override suspend fun createNoteJob(props: JobProps) { - val actor = props[DeliverPostJob.actor] - val postEntity = objectMapper.readValue(props[DeliverPostJob.post]) - val mediaList = - objectMapper.readValue>( - props[DeliverPostJob.media] - ) - val note = Note( - name = "Note", - id = postEntity.url, - attributedTo = actor, - content = postEntity.text, - published = Instant.ofEpochMilli(postEntity.createdAt).toString(), - to = listOf(public, "$actor/follower"), - attachment = mediaList.map { Document(mediaType = "image/jpeg", url = it.url) } - ) - val inbox = props[DeliverPostJob.inbox] - logger.debug("createNoteJob: actor={}, note={}, inbox={}", actor, postEntity, inbox) - - transaction.transaction { - val signer = userQueryService.findByUrl(actor) - apRequestService.apPost( - inbox, - Create( - name = "Create Note", - `object` = note, - actor = note.attributedTo, - id = "${applicationConfig.url}/create/note/${postEntity.id}" - ), - signer - ) - } - } override suspend fun fetchNote(url: String, targetActor: String?): Note { logger.debug("START Fetch Note url: {}", url) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APReactionService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APReactionService.kt index 5a8cb788..c097d3fb 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APReactionService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APReactionService.kt @@ -1,10 +1,6 @@ package dev.usbharu.hideout.service.ap import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import dev.usbharu.hideout.config.ApplicationConfig -import dev.usbharu.hideout.domain.model.ap.Like -import dev.usbharu.hideout.domain.model.ap.Undo import dev.usbharu.hideout.domain.model.hideout.entity.Reaction import dev.usbharu.hideout.domain.model.job.DeliverReactionJob import dev.usbharu.hideout.domain.model.job.DeliverRemoveReactionJob @@ -12,16 +8,12 @@ import dev.usbharu.hideout.query.FollowerQueryService import dev.usbharu.hideout.query.PostQueryService import dev.usbharu.hideout.query.UserQueryService import dev.usbharu.hideout.service.job.JobQueueParentService -import kjob.core.job.JobProps import org.springframework.beans.factory.annotation.Qualifier import org.springframework.stereotype.Service -import java.time.Instant interface APReactionService { suspend fun reaction(like: Reaction) suspend fun removeReaction(like: Reaction) - suspend fun reactionJob(props: JobProps) - suspend fun removeReactionJob(props: JobProps) } @Service @@ -30,9 +22,7 @@ class APReactionServiceImpl( private val userQueryService: UserQueryService, private val followerQueryService: FollowerQueryService, private val postQueryService: PostQueryService, - @Qualifier("activitypub") private val objectMapper: ObjectMapper, - private val applicationConfig: ApplicationConfig, - private val apRequestService: APRequestService + @Qualifier("activitypub") private val objectMapper: ObjectMapper ) : APReactionService { override suspend fun reaction(like: Reaction) { val followers = followerQueryService.findFollowersById(like.userId) @@ -64,46 +54,4 @@ class APReactionServiceImpl( } } } - - override suspend fun reactionJob(props: JobProps) { - val inbox = props[DeliverReactionJob.inbox] - val actor = props[DeliverReactionJob.actor] - val postUrl = props[DeliverReactionJob.postUrl] - val id = props[DeliverReactionJob.id] - val content = props[DeliverReactionJob.reaction] - - val signer = userQueryService.findByUrl(actor) - - apRequestService.apPost( - inbox, - Like( - name = "Like", - actor = actor, - `object` = postUrl, - id = "${applicationConfig.url}/like/note/$id", - content = content - ), - signer - ) - } - - override suspend fun removeReactionJob(props: JobProps) { - val inbox = props[DeliverRemoveReactionJob.inbox] - val actor = props[DeliverRemoveReactionJob.actor] - val like = objectMapper.readValue(props[DeliverRemoveReactionJob.like]) - - val signer = userQueryService.findByUrl(actor) - - apRequestService.apPost( - inbox, - Undo( - name = "Undo Reaction", - actor = actor, - `object` = like, - id = "${applicationConfig.url}/undo/note/${like.id}", - published = Instant.now() - ), - signer - ) - } } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowService.kt index d6d237e8..e53c5130 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowService.kt @@ -1,36 +1,24 @@ package dev.usbharu.hideout.service.ap import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue import dev.usbharu.hideout.domain.model.ActivityPubResponse import dev.usbharu.hideout.domain.model.ActivityPubStringResponse -import dev.usbharu.hideout.domain.model.ap.Accept import dev.usbharu.hideout.domain.model.ap.Follow import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob -import dev.usbharu.hideout.query.UserQueryService -import dev.usbharu.hideout.service.core.Transaction import dev.usbharu.hideout.service.job.JobQueueParentService -import dev.usbharu.hideout.service.user.UserService import io.ktor.http.* -import kjob.core.job.JobProps import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Qualifier import org.springframework.stereotype.Service interface APReceiveFollowService { suspend fun receiveFollow(follow: Follow): ActivityPubResponse - suspend fun receiveFollowJob(props: JobProps) } @Service class APReceiveFollowServiceImpl( private val jobQueueParentService: JobQueueParentService, - private val apUserService: APUserService, - private val userService: UserService, - private val userQueryService: UserQueryService, - private val transaction: Transaction, - @Qualifier("activitypub") private val objectMapper: ObjectMapper, - private val apRequestService: APRequestService + @Qualifier("activitypub") private val objectMapper: ObjectMapper ) : APReceiveFollowService { override suspend fun receiveFollow(follow: Follow): ActivityPubResponse { logger.info("FOLLOW from: {} to: {}", follow.actor, follow.`object`) @@ -42,37 +30,6 @@ class APReceiveFollowServiceImpl( return ActivityPubStringResponse(HttpStatusCode.OK, "{}", ContentType.Application.Json) } - override suspend fun receiveFollowJob(props: JobProps) { - transaction.transaction { - val actor = props[ReceiveFollowJob.actor] - val targetActor = props[ReceiveFollowJob.targetActor] - val person = apUserService.fetchPerson(actor, targetActor) - val follow = objectMapper.readValue(props[ReceiveFollowJob.follow]) - logger.info("START Follow from: {} to: {}", targetActor, actor) - - val signer = userQueryService.findByUrl(targetActor) - - val urlString = person.inbox ?: throw IllegalArgumentException("inbox is not found") - - apRequestService.apPost( - url = urlString, - body = Accept( - name = "Follow", - `object` = follow, - actor = targetActor - ), - signer = signer - ) - - val targetEntity = userQueryService.findByUrl(targetActor) - val followActorEntity = - userQueryService.findByUrl(follow.actor ?: throw java.lang.IllegalArgumentException("Actor is null")) - - userService.followRequest(targetEntity.id, followActorEntity.id) - logger.info("SUCCESS Follow from: {} to: {}", targetActor, actor) - } - } - companion object { private val logger = LoggerFactory.getLogger(APReceiveFollowServiceImpl::class.java) } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt index 9ea98a66..73fcd83b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt @@ -7,6 +7,9 @@ import dev.usbharu.hideout.domain.model.ActivityPubResponse import dev.usbharu.hideout.domain.model.ap.Follow import dev.usbharu.hideout.domain.model.job.* import dev.usbharu.hideout.exception.JsonParseException +import dev.usbharu.hideout.service.ap.job.APReceiveFollowJobService +import dev.usbharu.hideout.service.ap.job.ApNoteJobService +import dev.usbharu.hideout.service.ap.job.ApReactionJobService import kjob.core.dsl.JobContextWithProps import kjob.core.job.JobProps import org.slf4j.Logger @@ -176,13 +179,14 @@ enum class ExtendedVocabulary { @Service class APServiceImpl( private val apReceiveFollowService: APReceiveFollowService, - private val apNoteService: APNoteService, private val apUndoService: APUndoService, private val apAcceptService: APAcceptService, private val apCreateService: APCreateService, private val apLikeService: APLikeService, - private val apReactionService: APReactionService, - @Qualifier("activitypub") private val objectMapper: ObjectMapper + @Qualifier("activitypub") private val objectMapper: ObjectMapper, + private val apReceiveFollowJobService: APReceiveFollowJobService, + private val apNoteJobService: ApNoteJobService, + private val apReactionJobService: ApReactionJobService ) : APService { val logger: Logger = LoggerFactory.getLogger(APServiceImpl::class.java) @@ -237,14 +241,14 @@ class APServiceImpl( // Springで作成されるプロキシの都合上パターンマッチングが壊れるので必須 when (hideoutJob) { is ReceiveFollowJob -> { - apReceiveFollowService.receiveFollowJob( + apReceiveFollowJobService.receiveFollowJob( job.props as JobProps ) } - is DeliverPostJob -> apNoteService.createNoteJob(job.props as JobProps) - is DeliverReactionJob -> apReactionService.reactionJob(job.props as JobProps) - is DeliverRemoveReactionJob -> apReactionService.removeReactionJob( + is DeliverPostJob -> apNoteJobService.createNoteJob(job.props as JobProps) + is DeliverReactionJob -> apReactionJobService.reactionJob(job.props as JobProps) + is DeliverRemoveReactionJob -> apReactionJobService.removeReactionJob( job.props as JobProps ) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/job/APReceiveFollowJobService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/job/APReceiveFollowJobService.kt new file mode 100644 index 00000000..0aa35a9c --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/job/APReceiveFollowJobService.kt @@ -0,0 +1,8 @@ +package dev.usbharu.hideout.service.ap.job + +import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob +import kjob.core.job.JobProps + +interface APReceiveFollowJobService { + suspend fun receiveFollowJob(props: JobProps) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/job/APReceiveFollowJobServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/job/APReceiveFollowJobServiceImpl.kt new file mode 100644 index 00000000..cc12b0b1 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/job/APReceiveFollowJobServiceImpl.kt @@ -0,0 +1,61 @@ +package dev.usbharu.hideout.service.ap.job + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import dev.usbharu.hideout.domain.model.ap.Accept +import dev.usbharu.hideout.domain.model.ap.Follow +import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob +import dev.usbharu.hideout.query.UserQueryService +import dev.usbharu.hideout.service.ap.APRequestService +import dev.usbharu.hideout.service.ap.APUserService +import dev.usbharu.hideout.service.core.Transaction +import dev.usbharu.hideout.service.user.UserService +import kjob.core.job.JobProps +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.stereotype.Component + +@Component +class APReceiveFollowJobServiceImpl( + private val apUserService: APUserService, + private val userQueryService: UserQueryService, + private val apRequestService: APRequestService, + private val userService: UserService, + @Qualifier("activitypub") private val objectMapper: ObjectMapper, + private val transaction: Transaction +) : APReceiveFollowJobService { + override suspend fun receiveFollowJob(props: JobProps) { + transaction.transaction { + val actor = props[ReceiveFollowJob.actor] + val targetActor = props[ReceiveFollowJob.targetActor] + val person = apUserService.fetchPerson(actor, targetActor) + val follow = objectMapper.readValue(props[ReceiveFollowJob.follow]) + logger.info("START Follow from: {} to: {}", targetActor, actor) + + val signer = userQueryService.findByUrl(targetActor) + + val urlString = person.inbox ?: throw IllegalArgumentException("inbox is not found") + + apRequestService.apPost( + url = urlString, + body = Accept( + name = "Follow", + `object` = follow, + actor = targetActor + ), + signer = signer + ) + + val targetEntity = userQueryService.findByUrl(targetActor) + val followActorEntity = + userQueryService.findByUrl(follow.actor ?: throw java.lang.IllegalArgumentException("Actor is null")) + + userService.followRequest(targetEntity.id, followActorEntity.id) + logger.info("SUCCESS Follow from: {} to: {}", targetActor, actor) + } + } + + companion object { + private val logger = LoggerFactory.getLogger(APReceiveFollowJobServiceImpl::class.java) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApNoteJobService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApNoteJobService.kt new file mode 100644 index 00000000..35d7e3cb --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApNoteJobService.kt @@ -0,0 +1,8 @@ +package dev.usbharu.hideout.service.ap.job + +import dev.usbharu.hideout.domain.model.job.DeliverPostJob +import kjob.core.job.JobProps + +interface ApNoteJobService { + suspend fun createNoteJob(props: JobProps) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApNoteJobServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApNoteJobServiceImpl.kt new file mode 100644 index 00000000..8146a597 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApNoteJobServiceImpl.kt @@ -0,0 +1,67 @@ +package dev.usbharu.hideout.service.ap.job + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import dev.usbharu.hideout.config.ApplicationConfig +import dev.usbharu.hideout.domain.model.ap.Create +import dev.usbharu.hideout.domain.model.ap.Document +import dev.usbharu.hideout.domain.model.ap.Note +import dev.usbharu.hideout.domain.model.hideout.entity.Post +import dev.usbharu.hideout.domain.model.job.DeliverPostJob +import dev.usbharu.hideout.query.UserQueryService +import dev.usbharu.hideout.service.ap.APNoteServiceImpl +import dev.usbharu.hideout.service.ap.APRequestService +import dev.usbharu.hideout.service.core.Transaction +import kjob.core.job.JobProps +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.stereotype.Component +import java.time.Instant + +@Component +class ApNoteJobServiceImpl( + private val userQueryService: UserQueryService, + private val apRequestService: APRequestService, + @Qualifier("activitypub") private val objectMapper: ObjectMapper, + private val transaction: Transaction, + private val applicationConfig: ApplicationConfig +) : ApNoteJobService { + override suspend fun createNoteJob(props: JobProps) { + val actor = props[DeliverPostJob.actor] + val postEntity = objectMapper.readValue(props[DeliverPostJob.post]) + val mediaList = + objectMapper.readValue>( + props[DeliverPostJob.media] + ) + val note = Note( + name = "Note", + id = postEntity.url, + attributedTo = actor, + content = postEntity.text, + published = Instant.ofEpochMilli(postEntity.createdAt).toString(), + to = listOf(APNoteServiceImpl.public, "$actor/follower"), + attachment = mediaList.map { Document(mediaType = "image/jpeg", url = it.url) } + + ) + val inbox = props[DeliverPostJob.inbox] + logger.debug("createNoteJob: actor={}, note={}, inbox={}", actor, postEntity, inbox) + + transaction.transaction { + val signer = userQueryService.findByUrl(actor) + apRequestService.apPost( + inbox, + Create( + name = "Create Note", + `object` = note, + actor = note.attributedTo, + id = "${applicationConfig.url}/create/note/${postEntity.id}" + ), + signer + ) + } + } + + companion object { + private val logger = LoggerFactory.getLogger(ApNoteJobServiceImpl::class.java) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApReactionJobService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApReactionJobService.kt new file mode 100644 index 00000000..90a029ae --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApReactionJobService.kt @@ -0,0 +1,10 @@ +package dev.usbharu.hideout.service.ap.job + +import dev.usbharu.hideout.domain.model.job.DeliverReactionJob +import dev.usbharu.hideout.domain.model.job.DeliverRemoveReactionJob +import kjob.core.job.JobProps + +interface ApReactionJobService { + suspend fun reactionJob(props: JobProps) + suspend fun removeReactionJob(props: JobProps) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApReactionJobServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApReactionJobServiceImpl.kt new file mode 100644 index 00000000..45736662 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApReactionJobServiceImpl.kt @@ -0,0 +1,65 @@ +package dev.usbharu.hideout.service.ap.job + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import dev.usbharu.hideout.config.ApplicationConfig +import dev.usbharu.hideout.domain.model.ap.Like +import dev.usbharu.hideout.domain.model.ap.Undo +import dev.usbharu.hideout.domain.model.job.DeliverReactionJob +import dev.usbharu.hideout.domain.model.job.DeliverRemoveReactionJob +import dev.usbharu.hideout.query.UserQueryService +import dev.usbharu.hideout.service.ap.APRequestService +import kjob.core.job.JobProps +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.stereotype.Service +import java.time.Instant + +@Service +class ApReactionJobServiceImpl( + private val userQueryService: UserQueryService, + private val apRequestService: APRequestService, + private val applicationConfig: ApplicationConfig, + @Qualifier("activitypub") private val objectMapper: ObjectMapper +) : ApReactionJobService { + override suspend fun reactionJob(props: JobProps) { + val inbox = props[DeliverReactionJob.inbox] + val actor = props[DeliverReactionJob.actor] + val postUrl = props[DeliverReactionJob.postUrl] + val id = props[DeliverReactionJob.id] + val content = props[DeliverReactionJob.reaction] + + val signer = userQueryService.findByUrl(actor) + + apRequestService.apPost( + inbox, + Like( + name = "Like", + actor = actor, + `object` = postUrl, + id = "${applicationConfig.url}/like/note/$id", + content = content + ), + signer + ) + } + + override suspend fun removeReactionJob(props: JobProps) { + val inbox = props[DeliverRemoveReactionJob.inbox] + val actor = props[DeliverRemoveReactionJob.actor] + val like = objectMapper.readValue(props[DeliverRemoveReactionJob.like]) + + val signer = userQueryService.findByUrl(actor) + + apRequestService.apPost( + inbox, + Undo( + name = "Undo Reaction", + actor = actor, + `object` = like, + id = "${applicationConfig.url}/undo/note/${like.id}", + published = Instant.now() + ), + signer + ) + } +} diff --git a/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt index 628a8eff..089acdca 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt @@ -24,7 +24,6 @@ import org.mockito.Mockito.anyLong import org.mockito.Mockito.eq import org.mockito.kotlin.* import utils.JsonObjectMapper.objectMapper -import utils.TestApplicationConfig.testApplicationConfig import java.net.URL import java.time.Instant import kotlin.test.assertEquals @@ -104,11 +103,8 @@ class APNoteServiceImplTest { postQueryService = mock(), mediaQueryService = mediaQueryService, objectMapper = objectMapper, - applicationConfig = testApplicationConfig, postService = mock(), apResourceResolveService = mock(), - apRequestService = mock(), - transaction = mock(), postBuilder = postBuilder ) val postEntity = postBuilder.of( @@ -147,11 +143,8 @@ class APNoteServiceImplTest { postQueryService = mock(), mediaQueryService = mediaQueryService, objectMapper = objectMapper, - applicationConfig = testApplicationConfig, postService = mock(), apResourceResolveService = mock(), - apRequestService = mock(), - transaction = mock(), postBuilder = postBuilder ) activityPubNoteService.createNoteJob( diff --git a/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt index 38c266e1..d91761a2 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt @@ -25,7 +25,6 @@ import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.anyString import org.mockito.kotlin.* import utils.JsonObjectMapper.objectMapper -import utils.TestTransaction import java.net.URL import java.time.Instant @@ -42,12 +41,7 @@ class APReceiveFollowServiceImplTest { val activityPubFollowService = APReceiveFollowServiceImpl( jobQueueParentService, - mock(), - mock(), - mock(), - TestTransaction, - objectMapper, - mock() + objectMapper ) activityPubFollowService.receiveFollow( Follow( @@ -153,12 +147,7 @@ class APReceiveFollowServiceImplTest { val activityPubFollowService = APReceiveFollowServiceImpl( mock(), - apUserService, - userService, - userQueryService, - TestTransaction, - objectMapper, - mock() + objectMapper ) activityPubFollowService.receiveFollowJob( JobProps( From 61ee7ab59f4cf61b4a4bbd804eb8bfb3ee758987 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 27 Oct 2023 13:54:33 +0900 Subject: [PATCH 2/5] =?UTF-8?q?refactor:=20job=E3=82=92=E5=88=A5=E3=81=AE?= =?UTF-8?q?=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AB=E5=88=87=E3=82=8A=E5=87=BA?= =?UTF-8?q?=E3=81=972?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/usbharu/hideout/JobQueueRunner.kt | 6 +-- .../usbharu/hideout/service/ap/APService.kt | 28 ------------ .../hideout/service/ap/job/ApJobService.kt | 8 ++++ .../service/ap/job/ApJobServiceImpl.kt | 43 +++++++++++++++++++ 4 files changed, 54 insertions(+), 31 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApJobService.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApJobServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/JobQueueRunner.kt b/src/main/kotlin/dev/usbharu/hideout/JobQueueRunner.kt index 0f3a3829..697ab365 100644 --- a/src/main/kotlin/dev/usbharu/hideout/JobQueueRunner.kt +++ b/src/main/kotlin/dev/usbharu/hideout/JobQueueRunner.kt @@ -1,7 +1,7 @@ package dev.usbharu.hideout import dev.usbharu.hideout.domain.model.job.HideoutJob -import dev.usbharu.hideout.service.ap.APService +import dev.usbharu.hideout.service.ap.job.ApJobService import dev.usbharu.hideout.service.job.JobQueueParentService import dev.usbharu.hideout.service.job.JobQueueWorkerService import org.slf4j.Logger @@ -27,7 +27,7 @@ class JobQueueRunner(private val jobQueueParentService: JobQueueParentService, p class JobQueueWorkerRunner( private val jobQueueWorkerService: JobQueueWorkerService, private val jobs: List, - private val apService: APService + private val apJobService: ApJobService ) : ApplicationRunner { override fun run(args: ApplicationArguments?) { LOGGER.info("Init job queue worker.") @@ -36,7 +36,7 @@ class JobQueueWorkerRunner( it to { execute { LOGGER.debug("excute job ${it.name}") - apService.processActivity( + apJobService.processActivity( job = this, hideoutJob = it ) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt index 73fcd83b..60f2a811 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt @@ -5,13 +5,10 @@ import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.readValue import dev.usbharu.hideout.domain.model.ActivityPubResponse import dev.usbharu.hideout.domain.model.ap.Follow -import dev.usbharu.hideout.domain.model.job.* import dev.usbharu.hideout.exception.JsonParseException import dev.usbharu.hideout.service.ap.job.APReceiveFollowJobService import dev.usbharu.hideout.service.ap.job.ApNoteJobService import dev.usbharu.hideout.service.ap.job.ApReactionJobService -import kjob.core.dsl.JobContextWithProps -import kjob.core.job.JobProps import org.slf4j.Logger import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Qualifier @@ -21,8 +18,6 @@ interface APService { fun parseActivity(json: String): ActivityType suspend fun processActivity(json: String, type: ActivityType): ActivityPubResponse? - - suspend fun processActivity(job: JobContextWithProps, hideoutJob: HideoutJob) } enum class ActivityType { @@ -233,28 +228,5 @@ class APServiceImpl( } } - @Suppress("REDUNDANT_ELSE_IN_WHEN") - override suspend fun processActivity(job: JobContextWithProps, hideoutJob: HideoutJob) { - logger.debug("processActivity: ${hideoutJob.name}") - @Suppress("ElseCaseInsteadOfExhaustiveWhen") - // Springで作成されるプロキシの都合上パターンマッチングが壊れるので必須 - when (hideoutJob) { - is ReceiveFollowJob -> { - apReceiveFollowJobService.receiveFollowJob( - job.props as JobProps - ) - } - - is DeliverPostJob -> apNoteJobService.createNoteJob(job.props as JobProps) - is DeliverReactionJob -> apReactionJobService.reactionJob(job.props as JobProps) - is DeliverRemoveReactionJob -> apReactionJobService.removeReactionJob( - job.props as JobProps - ) - - else -> { - throw IllegalStateException("WTF") - } - } - } } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApJobService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApJobService.kt new file mode 100644 index 00000000..196b74c9 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApJobService.kt @@ -0,0 +1,8 @@ +package dev.usbharu.hideout.service.ap.job + +import dev.usbharu.hideout.domain.model.job.HideoutJob +import kjob.core.dsl.JobContextWithProps + +interface ApJobService { + suspend fun processActivity(job: JobContextWithProps, hideoutJob: HideoutJob) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApJobServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApJobServiceImpl.kt new file mode 100644 index 00000000..266b74d0 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/job/ApJobServiceImpl.kt @@ -0,0 +1,43 @@ +package dev.usbharu.hideout.service.ap.job + +import dev.usbharu.hideout.domain.model.job.* +import kjob.core.dsl.JobContextWithProps +import kjob.core.job.JobProps +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Service + +@Service +class ApJobServiceImpl( + private val apReceiveFollowJobService: APReceiveFollowJobService, + private val apNoteJobService: ApNoteJobService, + private val apReactionJobService: ApReactionJobService +) : ApJobService { + @Suppress("REDUNDANT_ELSE_IN_WHEN") + override suspend fun processActivity(job: JobContextWithProps, hideoutJob: HideoutJob) { + logger.debug("processActivity: ${hideoutJob.name}") + + @Suppress("ElseCaseInsteadOfExhaustiveWhen") + // Springで作成されるプロキシの都合上パターンマッチングが壊れるので必須 + when (hideoutJob) { + is ReceiveFollowJob -> { + apReceiveFollowJobService.receiveFollowJob( + job.props as JobProps + ) + } + + is DeliverPostJob -> apNoteJobService.createNoteJob(job.props as JobProps) + is DeliverReactionJob -> apReactionJobService.reactionJob(job.props as JobProps) + is DeliverRemoveReactionJob -> apReactionJobService.removeReactionJob( + job.props as JobProps + ) + + else -> { + throw IllegalStateException("WTF") + } + } + } + + companion object { + private val logger = LoggerFactory.getLogger(ApJobServiceImpl::class.java) + } +} From 2d8deb0d4f969756ff1a7e9f5a42d2c9e1a5a740 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 27 Oct 2023 14:08:38 +0900 Subject: [PATCH 3/5] style: fix lint --- .../kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt | 3 --- src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt | 5 ++--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt index 6ff134d1..0a9e4926 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt @@ -35,7 +35,6 @@ interface APNoteService { suspend fun createNote(post: Post) - @Cacheable("fetchNote") fun fetchNoteAsync(url: String, targetActor: String? = null): Deferred { return CoroutineScope(Dispatchers.IO + MDCContext()).async { @@ -95,8 +94,6 @@ class APNoteServiceImpl( logger.debug("SUCCESS Create Local Note ${post.url}") } - - override suspend fun fetchNote(url: String, targetActor: String?): Note { logger.debug("START Fetch Note url: {}", url) try { diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt index 60f2a811..9cd1cedf 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt @@ -196,7 +196,8 @@ class APServiceImpl( | |***** Trace End Activity ***** | - """.trimMargin(), readTree.toPrettyString() + """.trimMargin(), + readTree.toPrettyString() ) if (readTree.isObject.not()) { throw JsonParseException("Json is not object.") @@ -227,6 +228,4 @@ class APServiceImpl( } } } - - } From a099b637061b2507e7a7957fe23ec303b22251a8 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 27 Oct 2023 14:10:04 +0900 Subject: [PATCH 4/5] style: fix lint --- .../dev/usbharu/hideout/controller/InboxControllerImpl.kt | 1 + .../kotlin/dev/usbharu/hideout/repository/UserQueryMapper.kt | 4 +--- .../dev/usbharu/hideout/repository/UserRepositoryImpl.kt | 5 ++--- .../service/signature/HttpSignatureUserDetailsService.kt | 1 + 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/controller/InboxControllerImpl.kt b/src/main/kotlin/dev/usbharu/hideout/controller/InboxControllerImpl.kt index 235c821f..e06ec648 100644 --- a/src/main/kotlin/dev/usbharu/hideout/controller/InboxControllerImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/controller/InboxControllerImpl.kt @@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.RestController @RestController class InboxControllerImpl(private val apService: APService) : InboxController { + @Suppress("TooGenericExceptionCaught") override suspend fun inbox(@RequestBody string: String): ResponseEntity { val parseActivity = try { apService.parseActivity(string) diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserQueryMapper.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserQueryMapper.kt index 62828e72..d4969965 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserQueryMapper.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserQueryMapper.kt @@ -6,7 +6,5 @@ import org.springframework.stereotype.Component @Component class UserQueryMapper(private val userResultRowMapper: ResultRowMapper) : QueryMapper { - override fun map(query: Query): List { - return query.map(userResultRowMapper::map) - } + override fun map(query: Query): List = query.map(userResultRowMapper::map) } diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt index 0a1a9958..1a37c5d2 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt @@ -55,9 +55,8 @@ class UserRepositoryImpl( return user } - override suspend fun findById(id: Long): User? { - return Users.select { Users.id eq id }.singleOrNull()?.let(userResultRowMapper::map) - } + override suspend fun findById(id: Long): User? = + Users.select { Users.id eq id }.singleOrNull()?.let(userResultRowMapper::map) override suspend fun deleteFollowRequest(id: Long, follower: Long) { FollowRequests.deleteWhere { userId.eq(id) and followerId.eq(follower) } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureUserDetailsService.kt b/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureUserDetailsService.kt index 0f58350c..ba12cca0 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureUserDetailsService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureUserDetailsService.kt @@ -40,6 +40,7 @@ class HttpSignatureUserDetailsService( } } + @Suppress("TooGenericExceptionCaught") val verify = try { httpSignatureVerifier.verify( token.credentials as HttpRequest, From 6fe7ec0f3cf1027ef1cfd55d99c9959c579b91e3 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 27 Oct 2023 14:13:07 +0900 Subject: [PATCH 5/5] =?UTF-8?q?test:=20=E3=83=86=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/service/ap/APNoteServiceImplTest.kt | 17 +++++++---------- .../ap/APReceiveFollowServiceImplTest.kt | 10 ++++++++-- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt index 089acdca..51afa187 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/ap/APNoteServiceImplTest.kt @@ -12,6 +12,7 @@ import dev.usbharu.hideout.domain.model.job.DeliverPostJob import dev.usbharu.hideout.query.FollowerQueryService import dev.usbharu.hideout.query.MediaQueryService import dev.usbharu.hideout.query.UserQueryService +import dev.usbharu.hideout.service.ap.job.ApNoteJobServiceImpl import dev.usbharu.hideout.service.job.JobQueueParentService import io.ktor.client.* import io.ktor.client.engine.mock.* @@ -24,6 +25,7 @@ import org.mockito.Mockito.anyLong import org.mockito.Mockito.eq import org.mockito.kotlin.* import utils.JsonObjectMapper.objectMapper +import utils.TestTransaction import java.net.URL import java.time.Instant import kotlin.test.assertEquals @@ -134,18 +136,13 @@ class APNoteServiceImplTest { respondOk() } ) - val activityPubNoteService = APNoteServiceImpl( - jobQueueParentService = mock(), - postRepository = mock(), - apUserService = mock(), + val activityPubNoteService = ApNoteJobServiceImpl( + userQueryService = mock(), - followerQueryService = mock(), - postQueryService = mock(), - mediaQueryService = mediaQueryService, objectMapper = objectMapper, - postService = mock(), - apResourceResolveService = mock(), - postBuilder = postBuilder + apRequestService = mock(), + transaction = TestTransaction, + applicationConfig = ApplicationConfig(URL("https://example.com")) ) activityPubNoteService.createNoteJob( JobProps( diff --git a/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt index d91761a2..f13981e1 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowServiceImplTest.kt @@ -13,6 +13,7 @@ import dev.usbharu.hideout.domain.model.hideout.entity.Post import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob import dev.usbharu.hideout.query.UserQueryService +import dev.usbharu.hideout.service.ap.job.APReceiveFollowJobServiceImpl import dev.usbharu.hideout.service.job.JobQueueParentService import dev.usbharu.hideout.service.user.UserService import kjob.core.dsl.ScheduleContext @@ -25,6 +26,7 @@ import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.anyString import org.mockito.kotlin.* import utils.JsonObjectMapper.objectMapper +import utils.TestTransaction import java.net.URL import java.time.Instant @@ -145,9 +147,13 @@ class APReceiveFollowServiceImplTest { onBlocking { followRequest(any(), any()) } doReturn false } val activityPubFollowService = - APReceiveFollowServiceImpl( + APReceiveFollowJobServiceImpl( + apUserService, + userQueryService, mock(), - objectMapper + userService, + objectMapper, + TestTransaction ) activityPubFollowService.receiveFollowJob( JobProps(