From 2dbbed9a5a7206b762b5484801dea91db6dd3041 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 22 Nov 2023 00:56:12 +0900 Subject: [PATCH 01/21] =?UTF-8?q?feat:=20ActivityPub=E3=81=AE=E5=87=A6?= =?UTF-8?q?=E7=90=86=E5=85=B1=E9=80=9Ainterface=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/ActivityPubProcessException.kt | 21 +++++++++++++++ .../exception/FailedProcessException.kt | 14 ++++++++++ .../tmp/AbstractActivityPubProcessor.kt | 27 +++++++++++++++++++ .../service/tmp/ActivityPubProcessor.kt | 10 +++++++ 4 files changed, 72 insertions(+) create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/ActivityPubProcessException.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/FailedProcessException.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/AbstractActivityPubProcessor.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessor.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/ActivityPubProcessException.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/ActivityPubProcessException.kt new file mode 100644 index 00000000..c8cf6a0c --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/ActivityPubProcessException.kt @@ -0,0 +1,21 @@ +package dev.usbharu.hideout.activitypub.domain.exception + +import java.io.Serial + +class ActivityPubProcessException : RuntimeException { + constructor() : super() + constructor(message: String?) : super(message) + constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor(cause: Throwable?) : super(cause) + constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super( + message, + cause, + enableSuppression, + writableStackTrace + ) + + companion object { + @Serial + private const val serialVersionUID: Long = 5370068873167636639L + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/FailedProcessException.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/FailedProcessException.kt new file mode 100644 index 00000000..31c4b47e --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/FailedProcessException.kt @@ -0,0 +1,14 @@ +package dev.usbharu.hideout.activitypub.domain.exception + +class FailedProcessException : RuntimeException { + constructor() : super() + constructor(message: String?) : super(message) + constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor(cause: Throwable?) : super(cause) + constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super( + message, + cause, + enableSuppression, + writableStackTrace + ) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/AbstractActivityPubProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/AbstractActivityPubProcessor.kt new file mode 100644 index 00000000..ff23a65e --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/AbstractActivityPubProcessor.kt @@ -0,0 +1,27 @@ +package dev.usbharu.hideout.activitypub.service.tmp + +import dev.usbharu.hideout.activitypub.domain.exception.ActivityPubProcessException +import dev.usbharu.hideout.activitypub.domain.exception.FailedProcessException +import dev.usbharu.hideout.activitypub.domain.model.objects.Object +import dev.usbharu.hideout.application.external.Transaction +import org.slf4j.LoggerFactory + +abstract class AbstractActivityPubProcessor(val transaction: Transaction) : ActivityPubProcessor { + private val logger = LoggerFactory.getLogger(this::class.java) + + override suspend fun process(activity: T) { + logger.info("START ActivityPub process") + try { + transaction.transaction { + internalProcess(activity) + } + } catch (e: ActivityPubProcessException) { + logger.warn("FAILED ActivityPub process", e) + throw FailedProcessException("Failed process", e) + } + logger.info("SUCCESS ActivityPub process") + } + + abstract suspend fun internalProcess(activity: T) + +} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessor.kt new file mode 100644 index 00000000..919bf836 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessor.kt @@ -0,0 +1,10 @@ +package dev.usbharu.hideout.activitypub.service.tmp + +import dev.usbharu.hideout.activitypub.domain.model.objects.Object +import dev.usbharu.hideout.activitypub.service.common.ActivityType + +interface ActivityPubProcessor { + suspend fun process(activity: T) + + fun isSupported(activityType: ActivityType): Boolean +} From c4c9b4872220ad40f8dc1f8929be4f976cf06f72 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 22 Nov 2023 01:57:42 +0900 Subject: [PATCH 02/21] =?UTF-8?q?feat:=20InboxJobProcessor=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tmp/AbstractActivityPubProcessor.kt | 4 +- .../service/tmp/ActivityPubProcessContext.kt | 14 +++ .../service/tmp/ActivityPubProcessor.kt | 4 +- .../service/tmp/InboxJobProcessor.kt | 94 +++++++++++++++++++ 4 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessContext.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/AbstractActivityPubProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/AbstractActivityPubProcessor.kt index ff23a65e..6a3aba7e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/AbstractActivityPubProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/AbstractActivityPubProcessor.kt @@ -9,7 +9,7 @@ import org.slf4j.LoggerFactory abstract class AbstractActivityPubProcessor(val transaction: Transaction) : ActivityPubProcessor { private val logger = LoggerFactory.getLogger(this::class.java) - override suspend fun process(activity: T) { + override suspend fun process(activity: ActivityPubProcessContext) { logger.info("START ActivityPub process") try { transaction.transaction { @@ -22,6 +22,6 @@ abstract class AbstractActivityPubProcessor(val transaction: Transac logger.info("SUCCESS ActivityPub process") } - abstract suspend fun internalProcess(activity: T) + abstract suspend fun internalProcess(activity: ActivityPubProcessContext) } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessContext.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessContext.kt new file mode 100644 index 00000000..6f45fd20 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessContext.kt @@ -0,0 +1,14 @@ +package dev.usbharu.hideout.activitypub.service.tmp + +import com.fasterxml.jackson.databind.JsonNode +import dev.usbharu.hideout.activitypub.domain.model.objects.Object +import dev.usbharu.httpsignature.common.HttpRequest +import dev.usbharu.httpsignature.verify.Signature + +data class ActivityPubProcessContext( + val activity: T, + val jsonNode: JsonNode, + val httpRequest: HttpRequest, + val signature: Signature?, + val isAuthorized: Boolean +) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessor.kt index 919bf836..350f1aea 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessor.kt @@ -4,7 +4,9 @@ import dev.usbharu.hideout.activitypub.domain.model.objects.Object import dev.usbharu.hideout.activitypub.service.common.ActivityType interface ActivityPubProcessor { - suspend fun process(activity: T) + suspend fun process(activity: ActivityPubProcessContext) fun isSupported(activityType: ActivityType): Boolean + + fun type(): Class } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt new file mode 100644 index 00000000..1489765c --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt @@ -0,0 +1,94 @@ +package dev.usbharu.hideout.activitypub.service.tmp + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import dev.usbharu.hideout.activitypub.domain.model.objects.Object +import dev.usbharu.hideout.activitypub.service.common.ActivityType +import dev.usbharu.hideout.activitypub.service.objects.user.APUserService +import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.external.job.InboxJob +import dev.usbharu.hideout.core.query.UserQueryService +import dev.usbharu.hideout.util.RsaUtil +import dev.usbharu.httpsignature.common.HttpHeaders +import dev.usbharu.httpsignature.common.HttpRequest +import dev.usbharu.httpsignature.common.PublicKey +import dev.usbharu.httpsignature.verify.HttpSignatureVerifier +import dev.usbharu.httpsignature.verify.Signature +import dev.usbharu.httpsignature.verify.SignatureHeaderParser +import kjob.core.job.JobProps +import org.slf4j.LoggerFactory + +class InboxJobProcessor( + private val activityPubProcessorList: List>, + private val objectMapper: ObjectMapper, + private val signatureHeaderParser: SignatureHeaderParser, + private val signatureVerifier: HttpSignatureVerifier, + private val userQueryService: UserQueryService, + private val apUserService: APUserService +) { + suspend fun process(props: JobProps) { + + val type = ActivityType.valueOf(props[InboxJob.type]) + val jsonString = objectMapper.readTree(props[InboxJob.json]) + val httpRequestString = props[InboxJob.httpRequest] + val headersString = props[InboxJob.headers] + + logger.info("START Process inbox. type: {}", type) + logger.trace("type: {} \njson: \n{}", type, jsonString.toPrettyString()) + + val map = objectMapper.readValue>>(headersString) + + val httpRequest = + objectMapper.readValue(httpRequestString).copy(headers = HttpHeaders(map)) + + logger.trace("request: {}\nheaders: {}", httpRequest, map) + + val signature = parseSignatureHeader(httpRequest.headers) + + logger.debug("Has signature? {}", signature != null) + + val verify = signature?.let { verifyHttpSignature(httpRequest, it) } ?: false + + logger.debug("Is verifying success? {}", verify) + + val activityPubProcessor = activityPubProcessorList.firstOrNull { it.isSupported(type) } + + if (activityPubProcessor == null) { + logger.warn("ActivityType {} is not support.", type) + throw IllegalStateException("ActivityPubProcessor not found.") + } + + val value = objectMapper.treeToValue(jsonString, activityPubProcessor.type()) + activityPubProcessor.process(ActivityPubProcessContext(value, jsonString, httpRequest, signature, verify)) + + logger.info("SUCCESS Process inbox. type: {}", type) + } + + private suspend fun verifyHttpSignature(httpRequest: HttpRequest, signature: Signature): Boolean { + val user = try { + userQueryService.findByKeyId(signature.keyId) + } catch (_: FailedToGetResourcesException) { + apUserService.fetchPersonWithEntity(signature.keyId).second + } + + val verify = signatureVerifier.verify( + httpRequest, + PublicKey(RsaUtil.decodeRsaPublicKeyPem(user.publicKey), signature.keyId) + ) + + return verify.success + } + + private fun parseSignatureHeader(httpHeaders: HttpHeaders): Signature? { + return try { + signatureHeaderParser.parse(httpHeaders) + } catch (e: RuntimeException) { + logger.trace("FAILED parse signature header", e) + null + } + } + + companion object { + private val logger = LoggerFactory.getLogger(InboxJobProcessor::class.java) + } +} From 89c299d3c0270d2f2eba39efa3226b82368d9fe5 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 22 Nov 2023 02:00:19 +0900 Subject: [PATCH 03/21] =?UTF-8?q?feat:=20InboxJobProcessor=E3=82=92?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/common/ApJobServiceImpl.kt | 73 +------------------ .../service/tmp/InboxJobProcessor.kt | 2 + 2 files changed, 5 insertions(+), 70 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt index 0020fbd0..5da0356c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt @@ -1,28 +1,11 @@ package dev.usbharu.hideout.activitypub.service.common import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import dev.usbharu.hideout.activitypub.domain.model.Follow -import dev.usbharu.hideout.activitypub.service.activity.accept.APAcceptServiceImpl -import dev.usbharu.hideout.activitypub.service.activity.create.APCreateServiceImpl -import dev.usbharu.hideout.activitypub.service.activity.delete.APReceiveDeleteServiceImpl import dev.usbharu.hideout.activitypub.service.activity.follow.APReceiveFollowJobService -import dev.usbharu.hideout.activitypub.service.activity.follow.APReceiveFollowServiceImpl -import dev.usbharu.hideout.activitypub.service.activity.like.APLikeServiceImpl import dev.usbharu.hideout.activitypub.service.activity.like.ApReactionJobService -import dev.usbharu.hideout.activitypub.service.activity.undo.APUndoServiceImpl import dev.usbharu.hideout.activitypub.service.objects.note.ApNoteJobService -import dev.usbharu.hideout.activitypub.service.objects.user.APUserService -import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.activitypub.service.tmp.InboxJobProcessor import dev.usbharu.hideout.core.external.job.* -import dev.usbharu.hideout.core.query.UserQueryService -import dev.usbharu.hideout.util.RsaUtil -import dev.usbharu.httpsignature.common.HttpHeaders -import dev.usbharu.httpsignature.common.HttpRequest -import dev.usbharu.httpsignature.common.PublicKey -import dev.usbharu.httpsignature.verify.DefaultSignatureHeaderParser -import dev.usbharu.httpsignature.verify.RsaSha256HttpSignatureVerifier import kjob.core.dsl.JobContextWithProps import kjob.core.job.JobProps import org.slf4j.LoggerFactory @@ -34,18 +17,8 @@ class ApJobServiceImpl( private val apReceiveFollowJobService: APReceiveFollowJobService, private val apNoteJobService: ApNoteJobService, private val apReactionJobService: ApReactionJobService, - private val APAcceptServiceImpl: APAcceptServiceImpl, - private val APReceiveFollowServiceImpl: APReceiveFollowServiceImpl, - private val APCreateServiceImpl: APCreateServiceImpl, - private val APLikeServiceImpl: APLikeServiceImpl, - private val APUndoServiceImpl: APUndoServiceImpl, - private val APReceiveDeleteServiceImpl: APReceiveDeleteServiceImpl, @Qualifier("activitypub") private val objectMapper: ObjectMapper, - private val httpSignatureVerifier: RsaSha256HttpSignatureVerifier, - private val signatureHeaderParser: DefaultSignatureHeaderParser, - private val apUserService: APUserService, - private val userQueryService: UserQueryService, - private val transaction: Transaction + private val inboxJobProcessor: InboxJobProcessor ) : ApJobService { @Suppress("REDUNDANT_ELSE_IN_WHEN") override suspend fun processActivity(job: JobContextWithProps, hideoutJob: HideoutJob) { @@ -55,47 +28,7 @@ class ApJobServiceImpl( // Springで作成されるプロキシの都合上パターンマッチングが壊れるので必須 when (hideoutJob) { is InboxJob -> { - val httpRequestString = (job.props as JobProps)[InboxJob.httpRequest] - println(httpRequestString) - val headerString = (job.props as JobProps)[InboxJob.headers] - - val readValue = objectMapper.readValue>>(headerString) - - val httpRequest = - objectMapper.readValue(httpRequestString).copy(headers = HttpHeaders(readValue)) - val signature = signatureHeaderParser.parse(httpRequest.headers) - - val publicKey = transaction.transaction { - try { - userQueryService.findByKeyId(signature.keyId) - } catch (e: FailedToGetResourcesException) { - apUserService.fetchPersonWithEntity(signature.keyId).second - }.publicKey - } - - httpSignatureVerifier.verify( - httpRequest, - PublicKey(RsaUtil.decodeRsaPublicKeyPem(publicKey), signature.keyId) - ) - - val typeString = (job.props as JobProps)[InboxJob.type] - val json = (job.props as JobProps)[InboxJob.json] - val type = ActivityType.valueOf(typeString) - when (type) { - ActivityType.Accept -> APAcceptServiceImpl.receiveAccept(objectMapper.readValue(json)) - ActivityType.Follow -> - APReceiveFollowServiceImpl - .receiveFollow(objectMapper.readValue(json, Follow::class.java)) - - ActivityType.Create -> APCreateServiceImpl.receiveCreate(objectMapper.readValue(json)) - ActivityType.Like -> APLikeServiceImpl.receiveLike(objectMapper.readValue(json)) - ActivityType.Undo -> APUndoServiceImpl.receiveUndo(objectMapper.readValue(json)) - ActivityType.Delete -> APReceiveDeleteServiceImpl.receiveDelete(objectMapper.readValue(json)) - - else -> { - throw IllegalArgumentException("$type is not supported.") - } - } + inboxJobProcessor.process(job.props as JobProps) } is ReceiveFollowJob -> { diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt index 1489765c..99ad3fb9 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt @@ -17,7 +17,9 @@ import dev.usbharu.httpsignature.verify.Signature import dev.usbharu.httpsignature.verify.SignatureHeaderParser import kjob.core.job.JobProps import org.slf4j.LoggerFactory +import org.springframework.stereotype.Service +@Service class InboxJobProcessor( private val activityPubProcessorList: List>, private val objectMapper: ObjectMapper, From 3009ca153290a5c9d8e8f26f7ed73cf77e6bfa68 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 22 Nov 2023 02:14:21 +0900 Subject: [PATCH 04/21] =?UTF-8?q?feat:=20Create=E3=81=AE=E3=82=A2=E3=82=AF?= =?UTF-8?q?=E3=83=86=E3=82=A3=E3=83=93=E3=83=86=E3=82=A3=E3=81=AB=E5=AF=BE?= =?UTF-8?q?=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HttpSignatureUnauthorizedException.kt | 14 ++++++++++++ .../tmp/AbstractActivityPubProcessor.kt | 9 +++++++- .../tmp/impl/CreateActivityProcessor.kt | 22 +++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/HttpSignatureUnauthorizedException.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/impl/CreateActivityProcessor.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/HttpSignatureUnauthorizedException.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/HttpSignatureUnauthorizedException.kt new file mode 100644 index 00000000..9abccec6 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/exception/HttpSignatureUnauthorizedException.kt @@ -0,0 +1,14 @@ +package dev.usbharu.hideout.activitypub.domain.exception + +class HttpSignatureUnauthorizedException : RuntimeException { + constructor() : super() + constructor(message: String?) : super(message) + constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor(cause: Throwable?) : super(cause) + constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super( + message, + cause, + enableSuppression, + writableStackTrace + ) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/AbstractActivityPubProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/AbstractActivityPubProcessor.kt index 6a3aba7e..c5d927c9 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/AbstractActivityPubProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/AbstractActivityPubProcessor.kt @@ -2,14 +2,21 @@ package dev.usbharu.hideout.activitypub.service.tmp import dev.usbharu.hideout.activitypub.domain.exception.ActivityPubProcessException import dev.usbharu.hideout.activitypub.domain.exception.FailedProcessException +import dev.usbharu.hideout.activitypub.domain.exception.HttpSignatureUnauthorizedException import dev.usbharu.hideout.activitypub.domain.model.objects.Object import dev.usbharu.hideout.application.external.Transaction import org.slf4j.LoggerFactory -abstract class AbstractActivityPubProcessor(val transaction: Transaction) : ActivityPubProcessor { +abstract class AbstractActivityPubProcessor( + private val transaction: Transaction, + private val allowUnauthorized: Boolean = false +) : ActivityPubProcessor { private val logger = LoggerFactory.getLogger(this::class.java) override suspend fun process(activity: ActivityPubProcessContext) { + if (activity.isAuthorized.not() && allowUnauthorized.not()) { + throw HttpSignatureUnauthorizedException() + } logger.info("START ActivityPub process") try { transaction.transaction { diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/impl/CreateActivityProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/impl/CreateActivityProcessor.kt new file mode 100644 index 00000000..60918d01 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/impl/CreateActivityProcessor.kt @@ -0,0 +1,22 @@ +package dev.usbharu.hideout.activitypub.service.tmp.impl + +import dev.usbharu.hideout.activitypub.domain.model.Create +import dev.usbharu.hideout.activitypub.domain.model.Note +import dev.usbharu.hideout.activitypub.service.common.ActivityType +import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService +import dev.usbharu.hideout.activitypub.service.tmp.AbstractActivityPubProcessor +import dev.usbharu.hideout.activitypub.service.tmp.ActivityPubProcessContext +import dev.usbharu.hideout.application.external.Transaction +import org.springframework.stereotype.Service + +@Service +class CreateActivityProcessor(transaction: Transaction, private val apNoteService: APNoteService) : + AbstractActivityPubProcessor(transaction, false) { + override suspend fun internalProcess(activity: ActivityPubProcessContext) { + apNoteService.fetchNote(activity.activity.`object` as Note) + } + + override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Create + + override fun type(): Class = Create::class.java +} From ea9a999ae96270b8335c83658a532940796fc0b0 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 25 Nov 2023 16:23:00 +0900 Subject: [PATCH 05/21] =?UTF-8?q?feat:=20=E5=9E=8B=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E3=82=B8=E3=83=A7=E3=83=96=E3=82=AD=E3=83=A5=E3=83=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/core/external/job/HideoutJob.kt | 30 +++++++++++++++---- .../kjobexposed/KJobJobQueueParentService.kt | 6 ++++ .../core/service/job/JobQueueParentService.kt | 2 ++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt b/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt index 238b809f..9c4687d6 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt @@ -2,26 +2,44 @@ package dev.usbharu.hideout.core.external.job import kjob.core.Job import kjob.core.Prop +import kjob.core.dsl.ScheduleContext +import kjob.core.job.JobProps import org.springframework.stereotype.Component -sealed class HideoutJob(name: String = "") : Job(name) +abstract class HideoutJob>(name: String = "") : Job(name) { + abstract fun convert(value: T): ScheduleContext.(R) -> Unit + abstract fun convert(props: JobProps): T +} @Component -object ReceiveFollowJob : HideoutJob("ReceiveFollowJob") { +object ReceiveFollowJob : HideoutJob("ReceiveFollowJob") { val actor: Prop = string("actor") val follow: Prop = string("follow") val targetActor: Prop = string("targetActor") + + override fun convert(value: String): ScheduleContext.(ReceiveFollowJob) -> Unit = { + props[it.follow] = value + } + + override fun convert(props: JobProps): String = TODO("Not yet implemented") } @Component -object DeliverPostJob : HideoutJob("DeliverPostJob") { +object DeliverPostJob : HideoutJob("DeliverPostJob") { val create = string("create") val inbox = string("inbox") val actor = string("actor") + override fun convert(value: String): ScheduleContext.(DeliverPostJob) -> Unit { + TODO("Not yet implemented") + } + + override fun convert(props: JobProps): String { + TODO("Not yet implemented") + } } @Component -object DeliverReactionJob : HideoutJob("DeliverReactionJob") { +object DeliverReactionJob : HideoutJob("DeliverReactionJob") { val reaction: Prop = string("reaction") val postUrl: Prop = string("postUrl") val actor: Prop = string("actor") @@ -30,7 +48,7 @@ object DeliverReactionJob : HideoutJob("DeliverReactionJob") { } @Component -object DeliverRemoveReactionJob : HideoutJob("DeliverRemoveReactionJob") { +object DeliverRemoveReactionJob : HideoutJob("DeliverRemoveReactionJob") { val id: Prop = string("id") val inbox: Prop = string("inbox") val actor: Prop = string("actor") @@ -38,7 +56,7 @@ object DeliverRemoveReactionJob : HideoutJob("DeliverRemoveReactionJob") { } @Component -object InboxJob : HideoutJob("InboxJob") { +object InboxJob : HideoutJob("InboxJob") { val json = string("json") val type = string("type") val httpRequest = string("http_request") diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueParentService.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueParentService.kt index 0e02b011..5bc3ec89 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueParentService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueParentService.kt @@ -1,5 +1,6 @@ package dev.usbharu.hideout.core.infrastructure.kjobexposed +import dev.usbharu.hideout.core.external.job.HideoutJob import dev.usbharu.hideout.core.service.job.JobQueueParentService import kjob.core.Job import kjob.core.KJob @@ -29,4 +30,9 @@ class KJobJobQueueParentService() : JobQueueParentService { logger.debug("schedule job={}", job.name) kjob.schedule(job, block) } + + override suspend fun > scheduleTypeSafe(job: J, jobProps: T) { + val convert: ScheduleContext.(J) -> Unit = job.convert(jobProps) + kjob.schedule(job, convert) + } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueParentService.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueParentService.kt index 38f8111f..eee6d660 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueParentService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueParentService.kt @@ -1,5 +1,6 @@ package dev.usbharu.hideout.core.service.job +import dev.usbharu.hideout.core.external.job.HideoutJob import kjob.core.Job import kjob.core.dsl.ScheduleContext import org.springframework.stereotype.Service @@ -9,4 +10,5 @@ interface JobQueueParentService { fun init(jobDefines: List) suspend fun schedule(job: J, block: ScheduleContext.(J) -> Unit = {}) + suspend fun > scheduleTypeSafe(job: J, jobProps: T) } From dcac609b9432837fe38270301364d6e3e5345069 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 25 Nov 2023 16:46:03 +0900 Subject: [PATCH 06/21] =?UTF-8?q?feat:=20=E5=9E=8B=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E3=82=B8=E3=83=A7=E3=83=96=E3=82=AD=E3=83=A5=E3=83=BC=E3=82=92?= =?UTF-8?q?=E3=81=99=E3=81=B9=E3=81=A6=E3=81=AE=E3=82=B8=E3=83=A7=E3=83=96?= =?UTF-8?q?=E3=82=AD=E3=83=A5=E3=83=BC=E3=81=AB=E9=81=A9=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/core/external/job/HideoutJob.kt | 118 ++++++++++++++++-- .../core/service/job/JobQueueParentService.kt | 2 + 2 files changed, 107 insertions(+), 13 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt b/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt index 9c4687d6..30c02371 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt @@ -11,54 +11,146 @@ abstract class HideoutJob>(name: String = "") : Job(name abstract fun convert(props: JobProps): T } +data class ReceiveFollowJobParam( + val actor: String, + val follow: String, + val targetActor: String +) + @Component -object ReceiveFollowJob : HideoutJob("ReceiveFollowJob") { +object ReceiveFollowJob : HideoutJob("ReceiveFollowJob") { val actor: Prop = string("actor") val follow: Prop = string("follow") val targetActor: Prop = string("targetActor") - override fun convert(value: String): ScheduleContext.(ReceiveFollowJob) -> Unit = { - props[it.follow] = value + override fun convert(value: ReceiveFollowJobParam): ScheduleContext.(ReceiveFollowJob) -> Unit = { + props[follow] = value.follow + props[actor] = value.actor + props[targetActor] = value.targetActor + } - override fun convert(props: JobProps): String = TODO("Not yet implemented") + override fun convert(props: JobProps): ReceiveFollowJobParam = ReceiveFollowJobParam( + actor = props[actor], + follow = props[follow], + targetActor = props[targetActor] + ) } +data class DeliverPostJobParam( + val create: String, + val inbox: String, + val actor: String +) + @Component -object DeliverPostJob : HideoutJob("DeliverPostJob") { +object DeliverPostJob : HideoutJob("DeliverPostJob") { val create = string("create") val inbox = string("inbox") val actor = string("actor") - override fun convert(value: String): ScheduleContext.(DeliverPostJob) -> Unit { - TODO("Not yet implemented") + override fun convert(value: DeliverPostJobParam): ScheduleContext.(DeliverPostJob) -> Unit = { + props[create] = value.create + props[inbox] = value.inbox + props[actor] = value.actor } - override fun convert(props: JobProps): String { - TODO("Not yet implemented") - } + override fun convert(props: JobProps): DeliverPostJobParam = DeliverPostJobParam( + create = props[create], + inbox = props[inbox], + actor = props[actor] + ) } +data class DeliverReactionJobParam( + val reaction: String, + val postUrl: String, + val actor: String, + val inbox: String, + val id: String +) + @Component -object DeliverReactionJob : HideoutJob("DeliverReactionJob") { +object DeliverReactionJob : HideoutJob("DeliverReactionJob") { val reaction: Prop = string("reaction") val postUrl: Prop = string("postUrl") val actor: Prop = string("actor") val inbox: Prop = string("inbox") val id: Prop = string("id") + override fun convert(value: DeliverReactionJobParam): ScheduleContext.(DeliverReactionJob) -> Unit = + { + props[reaction] = value.reaction + props[postUrl] = value.postUrl + props[actor] = value.actor + props[inbox] = value.inbox + props[id] = value.id + } + + override fun convert(props: JobProps): DeliverReactionJobParam = DeliverReactionJobParam( + props[reaction], + props[postUrl], + props[actor], + props[inbox], + props[id] + ) } +data class DeliverRemoveReactionJobParam( + val id: String, + val inbox: String, + val actor: String, + val like: String +) + @Component -object DeliverRemoveReactionJob : HideoutJob("DeliverRemoveReactionJob") { +object DeliverRemoveReactionJob : + HideoutJob("DeliverRemoveReactionJob") { val id: Prop = string("id") val inbox: Prop = string("inbox") val actor: Prop = string("actor") val like: Prop = string("like") + + override fun convert(value: DeliverRemoveReactionJobParam): ScheduleContext.(DeliverRemoveReactionJob) -> Unit = + { + props[id] = value.id + props[inbox] = value.inbox + props[actor] = value.actor + props[like] = value.like + } + + override fun convert(props: JobProps): DeliverRemoveReactionJobParam = + DeliverRemoveReactionJobParam( + id = props[id], + inbox = props[inbox], + actor = props[actor], + like = props[like] + ) } +data class InboxJobParam( + val json: String, + val type: String, + val httpRequest: String, + val headers: String +) + @Component -object InboxJob : HideoutJob("InboxJob") { +object InboxJob : HideoutJob("InboxJob") { val json = string("json") val type = string("type") val httpRequest = string("http_request") val headers = string("headers") + + override fun convert(value: InboxJobParam): ScheduleContext.(InboxJob) -> Unit = { + props[json] = value.json + props[type] = value.type + props[httpRequest] = value.httpRequest + props[headers] = value.headers + } + + override fun convert(props: JobProps): InboxJobParam = InboxJobParam( + props[json], + props[type], + props[httpRequest], + props[headers] + ) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueParentService.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueParentService.kt index eee6d660..acec3f4a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueParentService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueParentService.kt @@ -9,6 +9,8 @@ import org.springframework.stereotype.Service interface JobQueueParentService { fun init(jobDefines: List) + + @Deprecated("use type safe → scheduleTypeSafe") suspend fun schedule(job: J, block: ScheduleContext.(J) -> Unit = {}) suspend fun > scheduleTypeSafe(job: J, jobProps: T) } From 1e8f49b5544117ce92159cfa97f190cc9a7a2de5 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sun, 26 Nov 2023 11:19:25 +0900 Subject: [PATCH 07/21] =?UTF-8?q?feat:=20=E5=9E=8B=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E3=81=AA=E3=82=B8=E3=83=A7=E3=83=96=E3=82=AD=E3=83=A5=E3=83=BC?= =?UTF-8?q?=E3=81=AE=E3=83=97=E3=83=AD=E3=82=BB=E3=83=83=E3=82=B5=E3=83=BC?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kjobexposed/KJobJobQueueWorkerService.kt | 8 +++----- .../hideout/core/service/job/JobProcessorService.kt | 8 ++++++++ .../hideout/core/service/job/JobQueueWorkerService.kt | 4 ++-- 3 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessorService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueWorkerService.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueWorkerService.kt index 98c3a488..8404a2db 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueWorkerService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueWorkerService.kt @@ -1,14 +1,14 @@ package dev.usbharu.hideout.core.infrastructure.kjobexposed +import dev.usbharu.hideout.core.external.job.HideoutJob import dev.usbharu.hideout.core.service.job.JobQueueWorkerService +import kjob.core.dsl.JobContextWithProps import kjob.core.dsl.JobRegisterContext import kjob.core.dsl.KJobFunctions import kjob.core.kjob import org.jetbrains.exposed.sql.transactions.TransactionManager import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.stereotype.Service -import dev.usbharu.hideout.core.external.job.HideoutJob as HJ -import kjob.core.dsl.JobContextWithProps as JCWP @Service @ConditionalOnProperty(name = ["hideout.use-mongodb"], havingValue = "false", matchIfMissing = true) @@ -23,9 +23,7 @@ class KJobJobQueueWorkerService() : JobQueueWorkerService { }.start() } - override fun init( - defines: List>.(HJ) -> KJobFunctions>>> - ) { + override fun > init(defines: List>.(R) -> KJobFunctions>>>) { defines.forEach { job -> kjob.register(job.first, job.second) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessorService.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessorService.kt new file mode 100644 index 00000000..07798007 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessorService.kt @@ -0,0 +1,8 @@ +package dev.usbharu.hideout.core.service.job + +import dev.usbharu.hideout.core.external.job.HideoutJob + +interface JobProcessorService> { + suspend fun process(param: T) + suspend fun job(): Class +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueWorkerService.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueWorkerService.kt index 982dbeb0..9496470e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueWorkerService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobQueueWorkerService.kt @@ -8,7 +8,7 @@ import kjob.core.dsl.JobRegisterContext as JRC @Service interface JobQueueWorkerService { - fun init( - defines: List>.(HJ) -> KJobFunctions>>> + fun > init( + defines: List>.(R) -> KJobFunctions>>> ) } From 25b689b73ae15c20099a4c57ddd52a5b3b18d4f8 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sun, 26 Nov 2023 12:40:59 +0900 Subject: [PATCH 08/21] =?UTF-8?q?feat:=20=E5=9E=8B=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E3=82=B8=E3=83=A7=E3=83=96=E3=82=AD=E3=83=A5=E3=83=BC=E3=81=AE?= =?UTF-8?q?=E9=AA=A8=E7=B5=84=E3=81=BF=E3=82=92=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activitypub/service/common/ApJobService.kt | 2 +- .../activitypub/service/common/ApJobServiceImpl.kt | 5 ++++- .../hideout/application/config/JobQueueRunner.kt | 7 +++++-- .../usbharu/hideout/core/external/job/HideoutJob.kt | 7 ++++--- .../kjobexposed/KJobJobQueueWorkerService.kt | 12 +++++++++++- .../kjobmongodb/KJobMongoJobQueueWorkerService.kt | 8 +++----- .../kjobmongodb/KjobMongoJobQueueParentService.kt | 6 ++++++ .../usbharu/hideout/core/service/job/JobProcessor.kt | 8 ++++++++ .../hideout/core/service/job/JobProcessorService.kt | 8 -------- 9 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessor.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessorService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobService.kt index fe909b0d..3b50b777 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobService.kt @@ -4,5 +4,5 @@ import dev.usbharu.hideout.core.external.job.HideoutJob import kjob.core.dsl.JobContextWithProps interface ApJobService { - suspend fun processActivity(job: JobContextWithProps, hideoutJob: HideoutJob) + suspend fun > processActivity(job: JobContextWithProps, hideoutJob: HideoutJob) } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt index 5da0356c..150e93a3 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt @@ -21,7 +21,10 @@ class ApJobServiceImpl( private val inboxJobProcessor: InboxJobProcessor ) : ApJobService { @Suppress("REDUNDANT_ELSE_IN_WHEN") - override suspend fun processActivity(job: JobContextWithProps, hideoutJob: HideoutJob) { + override suspend fun > processActivity( + job: JobContextWithProps, + hideoutJob: HideoutJob + ) { logger.debug("processActivity: ${hideoutJob.name}") @Suppress("ElseCaseInsteadOfExhaustiveWhen") diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/JobQueueRunner.kt b/src/main/kotlin/dev/usbharu/hideout/application/config/JobQueueRunner.kt index 4f7f1aaf..bb22e6d6 100644 --- a/src/main/kotlin/dev/usbharu/hideout/application/config/JobQueueRunner.kt +++ b/src/main/kotlin/dev/usbharu/hideout/application/config/JobQueueRunner.kt @@ -11,7 +11,10 @@ import org.springframework.boot.ApplicationRunner import org.springframework.stereotype.Component @Component -class JobQueueRunner(private val jobQueueParentService: JobQueueParentService, private val jobs: List) : +class JobQueueRunner( + private val jobQueueParentService: JobQueueParentService, + private val jobs: List> +) : ApplicationRunner { override fun run(args: ApplicationArguments?) { LOGGER.info("Init job queue. ${jobs.size}") @@ -26,7 +29,7 @@ class JobQueueRunner(private val jobQueueParentService: JobQueueParentService, p @Component class JobQueueWorkerRunner( private val jobQueueWorkerService: JobQueueWorkerService, - private val jobs: List, + private val jobs: List>, private val apJobService: ApJobService ) : ApplicationRunner { override fun run(args: ApplicationArguments?) { diff --git a/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt b/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt index 30c02371..72878f6e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt @@ -6,9 +6,10 @@ import kjob.core.dsl.ScheduleContext import kjob.core.job.JobProps import org.springframework.stereotype.Component -abstract class HideoutJob>(name: String = "") : Job(name) { - abstract fun convert(value: T): ScheduleContext.(R) -> Unit - abstract fun convert(props: JobProps): T +abstract class HideoutJob>(name: String = "") : Job(name) { + abstract fun convert(value: @UnsafeVariance T): ScheduleContext<@UnsafeVariance R>.(@UnsafeVariance R) -> Unit + fun convertUnsafe(props: JobProps<*>): T = convert(props as JobProps) + abstract fun convert(props: JobProps<@UnsafeVariance R>): T } data class ReceiveFollowJobParam( diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueWorkerService.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueWorkerService.kt index 8404a2db..872a3249 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueWorkerService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueWorkerService.kt @@ -1,6 +1,7 @@ package dev.usbharu.hideout.core.infrastructure.kjobexposed import dev.usbharu.hideout.core.external.job.HideoutJob +import dev.usbharu.hideout.core.service.job.JobProcessor import dev.usbharu.hideout.core.service.job.JobQueueWorkerService import kjob.core.dsl.JobContextWithProps import kjob.core.dsl.JobRegisterContext @@ -12,7 +13,7 @@ import org.springframework.stereotype.Service @Service @ConditionalOnProperty(name = ["hideout.use-mongodb"], havingValue = "false", matchIfMissing = true) -class KJobJobQueueWorkerService() : JobQueueWorkerService { +class KJobJobQueueWorkerService(private val jobQueueProcessorList: List>) : JobQueueWorkerService { val kjob by lazy { kjob(ExposedKJob) { @@ -27,5 +28,14 @@ class KJobJobQueueWorkerService() : JobQueueWorkerService { defines.forEach { job -> kjob.register(job.first, job.second) } + + for (jobProcessor in jobQueueProcessorList) { + kjob.register(jobProcessor.job()) { + execute { + val param = it.convertUnsafe(props) + jobProcessor.process(param) + } + } + } } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KJobMongoJobQueueWorkerService.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KJobMongoJobQueueWorkerService.kt index 5d4ed22c..25fbdefe 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KJobMongoJobQueueWorkerService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KJobMongoJobQueueWorkerService.kt @@ -1,15 +1,15 @@ package dev.usbharu.hideout.core.infrastructure.kjobmongodb import com.mongodb.reactivestreams.client.MongoClient +import dev.usbharu.hideout.core.external.job.HideoutJob import dev.usbharu.hideout.core.service.job.JobQueueWorkerService +import kjob.core.dsl.JobContextWithProps import kjob.core.dsl.JobRegisterContext import kjob.core.dsl.KJobFunctions import kjob.core.kjob import kjob.mongo.Mongo import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.stereotype.Service -import dev.usbharu.hideout.core.external.job.HideoutJob as HJ -import kjob.core.dsl.JobContextWithProps as JCWP @Service @ConditionalOnProperty(name = ["hideout.use-mongodb"], havingValue = "true", matchIfMissing = false) @@ -23,9 +23,7 @@ class KJobMongoJobQueueWorkerService(private val mongoClient: MongoClient) : Job }.start() } - override fun init( - defines: List>.(HJ) -> KJobFunctions>>> - ) { + override fun > init(defines: List>.(R) -> KJobFunctions>>>) { defines.forEach { job -> kjob.register(job.first, job.second) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KjobMongoJobQueueParentService.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KjobMongoJobQueueParentService.kt index 0875325d..846e8dff 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KjobMongoJobQueueParentService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KjobMongoJobQueueParentService.kt @@ -1,6 +1,7 @@ package dev.usbharu.hideout.core.infrastructure.kjobmongodb import com.mongodb.reactivestreams.client.MongoClient +import dev.usbharu.hideout.core.external.job.HideoutJob import dev.usbharu.hideout.core.service.job.JobQueueParentService import kjob.core.Job import kjob.core.dsl.ScheduleContext @@ -23,10 +24,15 @@ class KjobMongoJobQueueParentService(private val mongoClient: MongoClient) : Job override fun init(jobDefines: List) = Unit + @Deprecated("use type safe → scheduleTypeSafe") override suspend fun schedule(job: J, block: ScheduleContext.(J) -> Unit) { kjob.schedule(job, block) } + override suspend fun > scheduleTypeSafe(job: J, jobProps: T) { + TODO("Not yet implemented") + } + override fun close() { kjob.shutdown() } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessor.kt new file mode 100644 index 00000000..f6adc74b --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessor.kt @@ -0,0 +1,8 @@ +package dev.usbharu.hideout.core.service.job + +import dev.usbharu.hideout.core.external.job.HideoutJob + +interface JobProcessor> { + suspend fun process(param: @UnsafeVariance T) + fun job(): R +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessorService.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessorService.kt deleted file mode 100644 index 07798007..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessorService.kt +++ /dev/null @@ -1,8 +0,0 @@ -package dev.usbharu.hideout.core.service.job - -import dev.usbharu.hideout.core.external.job.HideoutJob - -interface JobProcessorService> { - suspend fun process(param: T) - suspend fun job(): Class -} From abce56e52df4691344d042ab8098aef61be2f686 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sun, 26 Nov 2023 13:17:49 +0900 Subject: [PATCH 09/21] =?UTF-8?q?feat:=20Inbox=E3=81=AE=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=96=E3=82=AD=E3=83=A5=E3=83=BC=E3=82=92=E5=9E=8B=E5=AE=89?= =?UTF-8?q?=E5=85=A8=E3=82=B8=E3=83=A7=E3=83=96=E3=82=AD=E3=83=A5=E3=83=BC?= =?UTF-8?q?=E5=AE=9F=E8=A3=85=E3=81=AB=E5=88=87=E3=82=8A=E6=9B=BF=E3=81=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/tmp/InboxJobProcessor.kt | 11 +++++++- .../application/config/JobQueueRunner.kt | 27 ++++++++++--------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt index 99ad3fb9..e33da23b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt @@ -7,7 +7,9 @@ import dev.usbharu.hideout.activitypub.service.common.ActivityType import dev.usbharu.hideout.activitypub.service.objects.user.APUserService import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.external.job.InboxJob +import dev.usbharu.hideout.core.external.job.InboxJobParam import dev.usbharu.hideout.core.query.UserQueryService +import dev.usbharu.hideout.core.service.job.JobProcessor import dev.usbharu.hideout.util.RsaUtil import dev.usbharu.httpsignature.common.HttpHeaders import dev.usbharu.httpsignature.common.HttpRequest @@ -27,7 +29,7 @@ class InboxJobProcessor( private val signatureVerifier: HttpSignatureVerifier, private val userQueryService: UserQueryService, private val apUserService: APUserService -) { +) : JobProcessor { suspend fun process(props: JobProps) { val type = ActivityType.valueOf(props[InboxJob.type]) @@ -90,6 +92,13 @@ class InboxJobProcessor( } } + override suspend fun process(param: InboxJobParam) { + println(param) + System.err.println("aaaaaaaaaaaaaaaaaaaaaaaaaaa") + } + + override fun job(): InboxJob = InboxJob + companion object { private val logger = LoggerFactory.getLogger(InboxJobProcessor::class.java) } diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/JobQueueRunner.kt b/src/main/kotlin/dev/usbharu/hideout/application/config/JobQueueRunner.kt index bb22e6d6..cc1580ea 100644 --- a/src/main/kotlin/dev/usbharu/hideout/application/config/JobQueueRunner.kt +++ b/src/main/kotlin/dev/usbharu/hideout/application/config/JobQueueRunner.kt @@ -34,19 +34,20 @@ class JobQueueWorkerRunner( ) : ApplicationRunner { override fun run(args: ApplicationArguments?) { LOGGER.info("Init job queue worker.") - jobQueueWorkerService.init( - jobs.map { - it to { - execute { - LOGGER.debug("excute job ${it.name}") - apJobService.processActivity( - job = this, - hideoutJob = it - ) - } - } - } - ) +// jobQueueWorkerService.init>( +// jobs.map { +// it to { +// execute { +// LOGGER.debug("excute job ${it.name}") +// apJobService.processActivity( +// job = this, +// hideoutJob = it +// ) +// } +// } +// } +// ) + jobQueueWorkerService.init>(emptyList()) } companion object { From 9171e3a063f802efa4a61f59831acfce85f30e3a Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sun, 26 Nov 2023 15:36:43 +0900 Subject: [PATCH 10/21] =?UTF-8?q?feat:=20Inbox=E3=81=AE=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=96=E3=82=AD=E3=83=A5=E3=83=BC=E3=82=92=E5=9E=8B=E5=AE=89?= =?UTF-8?q?=E5=85=A8=E3=82=B8=E3=83=A7=E3=83=96=E3=82=AD=E3=83=A5=E3=83=BC?= =?UTF-8?q?=E5=AE=9F=E8=A3=85=E3=81=AB=E5=88=87=E3=82=8A=E6=9B=BF=E3=81=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/tmp/InboxJobProcessor.kt | 32 +++++++++++++++++-- .../hideout/core/external/job/HideoutJob.kt | 7 ++-- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt index e33da23b..3cc5d0fc 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt @@ -93,8 +93,36 @@ class InboxJobProcessor( } override suspend fun process(param: InboxJobParam) { - println(param) - System.err.println("aaaaaaaaaaaaaaaaaaaaaaaaaaa") + val jsonNode = objectMapper.readTree(param.json) + + logger.info("START Process inbox. type: {}", param.type) + logger.trace("type: {}\njson: \n{}", param.type, jsonNode.toPrettyString()) + + val map = objectMapper.readValue>>(param.headers) + + val httpRequest = objectMapper.readValue(param.httpRequest).copy(headers = HttpHeaders(map)) + + logger.trace("Request: {}\nheaders: {}", httpRequest, map) + + val signature = parseSignatureHeader(httpRequest.headers) + + logger.debug("Has signature? {}", signature != null) + + val verify = signature?.let { verifyHttpSignature(httpRequest, it) } ?: false + + logger.debug("Is verifying success? {}", verify) + + val activityPubProcessor = activityPubProcessorList.firstOrNull { it.isSupported(param.type) } + + if (activityPubProcessor == null) { + logger.warn("ActivityType {} is not support.", param.type) + throw IllegalStateException("ActivityPubProcessor not found.") + } + + val value = objectMapper.treeToValue(jsonNode, activityPubProcessor.type()) + activityPubProcessor.process(ActivityPubProcessContext(value, jsonNode, httpRequest, signature, verify)) + + logger.info("SUCCESS Process inbox. type: {}", param.type) } override fun job(): InboxJob = InboxJob diff --git a/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt b/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt index 72878f6e..7ca2a630 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt @@ -1,5 +1,6 @@ package dev.usbharu.hideout.core.external.job +import dev.usbharu.hideout.activitypub.service.common.ActivityType import kjob.core.Job import kjob.core.Prop import kjob.core.dsl.ScheduleContext @@ -129,7 +130,7 @@ object DeliverRemoveReactionJob : data class InboxJobParam( val json: String, - val type: String, + val type: ActivityType, val httpRequest: String, val headers: String ) @@ -143,14 +144,14 @@ object InboxJob : HideoutJob("InboxJob") { override fun convert(value: InboxJobParam): ScheduleContext.(InboxJob) -> Unit = { props[json] = value.json - props[type] = value.type + props[type] = value.type.name props[httpRequest] = value.httpRequest props[headers] = value.headers } override fun convert(props: JobProps): InboxJobParam = InboxJobParam( props[json], - props[type], + ActivityType.valueOf(props[type]), props[httpRequest], props[headers] ) From 14998f514d9163485e2f93151a339e018266c79d Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sun, 26 Nov 2023 15:47:40 +0900 Subject: [PATCH 11/21] =?UTF-8?q?refactor:=20tmp=E3=81=8B=E3=82=89?= =?UTF-8?q?=E6=AD=A3=E5=BC=8F=E3=81=AA=E3=83=91=E3=83=83=E3=82=B1=E3=83=BC?= =?UTF-8?q?=E3=82=B8=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../create}/CreateActivityProcessor.kt | 6 +++--- .../{tmp => common}/AbstractActivityPubProcessor.kt | 2 +- .../{tmp => common}/ActivityPubProcessContext.kt | 2 +- .../service/{tmp => common}/ActivityPubProcessor.kt | 3 +-- .../activitypub/service/common/ApJobServiceImpl.kt | 2 +- .../service/{tmp => inbox}/InboxJobProcessor.kt | 10 +++++++--- 6 files changed, 14 insertions(+), 11 deletions(-) rename src/main/kotlin/dev/usbharu/hideout/activitypub/service/{tmp/impl => activity/create}/CreateActivityProcessor.kt (79%) rename src/main/kotlin/dev/usbharu/hideout/activitypub/service/{tmp => common}/AbstractActivityPubProcessor.kt (96%) rename src/main/kotlin/dev/usbharu/hideout/activitypub/service/{tmp => common}/ActivityPubProcessContext.kt (88%) rename src/main/kotlin/dev/usbharu/hideout/activitypub/service/{tmp => common}/ActivityPubProcessor.kt (68%) rename src/main/kotlin/dev/usbharu/hideout/activitypub/service/{tmp => inbox}/InboxJobProcessor.kt (92%) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/impl/CreateActivityProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/CreateActivityProcessor.kt similarity index 79% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/impl/CreateActivityProcessor.kt rename to src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/CreateActivityProcessor.kt index 60918d01..5d057b3f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/impl/CreateActivityProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/CreateActivityProcessor.kt @@ -1,11 +1,11 @@ -package dev.usbharu.hideout.activitypub.service.tmp.impl +package dev.usbharu.hideout.activitypub.service.activity.create import dev.usbharu.hideout.activitypub.domain.model.Create import dev.usbharu.hideout.activitypub.domain.model.Note +import dev.usbharu.hideout.activitypub.service.common.AbstractActivityPubProcessor +import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessContext import dev.usbharu.hideout.activitypub.service.common.ActivityType import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService -import dev.usbharu.hideout.activitypub.service.tmp.AbstractActivityPubProcessor -import dev.usbharu.hideout.activitypub.service.tmp.ActivityPubProcessContext import dev.usbharu.hideout.application.external.Transaction import org.springframework.stereotype.Service diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/AbstractActivityPubProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/AbstractActivityPubProcessor.kt similarity index 96% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/AbstractActivityPubProcessor.kt rename to src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/AbstractActivityPubProcessor.kt index c5d927c9..8cddae81 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/AbstractActivityPubProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/AbstractActivityPubProcessor.kt @@ -1,4 +1,4 @@ -package dev.usbharu.hideout.activitypub.service.tmp +package dev.usbharu.hideout.activitypub.service.common import dev.usbharu.hideout.activitypub.domain.exception.ActivityPubProcessException import dev.usbharu.hideout.activitypub.domain.exception.FailedProcessException diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessContext.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityPubProcessContext.kt similarity index 88% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessContext.kt rename to src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityPubProcessContext.kt index 6f45fd20..60a17bb4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessContext.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityPubProcessContext.kt @@ -1,4 +1,4 @@ -package dev.usbharu.hideout.activitypub.service.tmp +package dev.usbharu.hideout.activitypub.service.common import com.fasterxml.jackson.databind.JsonNode import dev.usbharu.hideout.activitypub.domain.model.objects.Object diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityPubProcessor.kt similarity index 68% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessor.kt rename to src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityPubProcessor.kt index 350f1aea..4bc16f25 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/ActivityPubProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ActivityPubProcessor.kt @@ -1,7 +1,6 @@ -package dev.usbharu.hideout.activitypub.service.tmp +package dev.usbharu.hideout.activitypub.service.common import dev.usbharu.hideout.activitypub.domain.model.objects.Object -import dev.usbharu.hideout.activitypub.service.common.ActivityType interface ActivityPubProcessor { suspend fun process(activity: ActivityPubProcessContext) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt index 150e93a3..64505017 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt @@ -3,8 +3,8 @@ package dev.usbharu.hideout.activitypub.service.common import com.fasterxml.jackson.databind.ObjectMapper import dev.usbharu.hideout.activitypub.service.activity.follow.APReceiveFollowJobService import dev.usbharu.hideout.activitypub.service.activity.like.ApReactionJobService +import dev.usbharu.hideout.activitypub.service.inbox.InboxJobProcessor import dev.usbharu.hideout.activitypub.service.objects.note.ApNoteJobService -import dev.usbharu.hideout.activitypub.service.tmp.InboxJobProcessor import dev.usbharu.hideout.core.external.job.* import kjob.core.dsl.JobContextWithProps import kjob.core.job.JobProps diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/inbox/InboxJobProcessor.kt similarity index 92% rename from src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt rename to src/main/kotlin/dev/usbharu/hideout/activitypub/service/inbox/InboxJobProcessor.kt index 3cc5d0fc..71614aca 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/tmp/InboxJobProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/inbox/InboxJobProcessor.kt @@ -1,10 +1,13 @@ -package dev.usbharu.hideout.activitypub.service.tmp +package dev.usbharu.hideout.activitypub.service.inbox import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.readValue import dev.usbharu.hideout.activitypub.domain.model.objects.Object +import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessContext +import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessor import dev.usbharu.hideout.activitypub.service.common.ActivityType import dev.usbharu.hideout.activitypub.service.objects.user.APUserService +import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.external.job.InboxJob import dev.usbharu.hideout.core.external.job.InboxJobParam @@ -28,7 +31,8 @@ class InboxJobProcessor( private val signatureHeaderParser: SignatureHeaderParser, private val signatureVerifier: HttpSignatureVerifier, private val userQueryService: UserQueryService, - private val apUserService: APUserService + private val apUserService: APUserService, + private val transaction: Transaction ) : JobProcessor { suspend fun process(props: JobProps) { @@ -92,7 +96,7 @@ class InboxJobProcessor( } } - override suspend fun process(param: InboxJobParam) { + override suspend fun process(param: InboxJobParam) = transaction.transaction { val jsonNode = objectMapper.readTree(param.json) logger.info("START Process inbox. type: {}", param.type) From 8757d059bed408079250b8d385557351c2cbbdd7 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 27 Nov 2023 11:57:42 +0900 Subject: [PATCH 12/21] =?UTF-8?q?feat:=20follow=E3=81=AE=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=96=E3=83=97=E3=83=AD=E3=82=BB=E3=83=83=E3=82=B5=E3=83=BC?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../follow/APReceiveFollowJobProcessor.kt | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobProcessor.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobProcessor.kt new file mode 100644 index 00000000..91b88b79 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobProcessor.kt @@ -0,0 +1,62 @@ +package dev.usbharu.hideout.activitypub.service.activity.follow + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import dev.usbharu.hideout.activitypub.domain.model.Accept +import dev.usbharu.hideout.activitypub.domain.model.Follow +import dev.usbharu.hideout.activitypub.service.common.APRequestService +import dev.usbharu.hideout.activitypub.service.objects.user.APUserService +import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.external.job.ReceiveFollowJob +import dev.usbharu.hideout.core.external.job.ReceiveFollowJobParam +import dev.usbharu.hideout.core.query.UserQueryService +import dev.usbharu.hideout.core.service.job.JobProcessor +import dev.usbharu.hideout.core.service.user.UserService +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Service + +@Service +class APReceiveFollowJobProcessor( + private val transaction: Transaction, + private val userQueryService: UserQueryService, + private val apUserService: APUserService, + private val objectMapper: ObjectMapper, + private val apRequestService: APRequestService, + private val userService: UserService +) : + JobProcessor { + override suspend fun process(param: ReceiveFollowJobParam) = transaction.transaction { + val person = apUserService.fetchPerson(param.actor, param.targetActor) + val follow = objectMapper.readValue(param.follow) + + + logger.info("START Follow from: {} to {}", param.targetActor, param.actor) + + val signer = userQueryService.findByUrl(param.targetActor) + + val urlString = person.inbox ?: throw IllegalArgumentException("inbox is not found.") + + apRequestService.apPost( + url = urlString, + body = Accept( + name = "Follow", + `object` = follow, + actor = param.targetActor + ), + signer = signer + ) + + val targetEntity = userQueryService.findByUrl(param.targetActor) + val followActorEntity = + userQueryService.findByUrl(follow.actor ?: throw IllegalArgumentException("actor is null")) + + userService.followRequest(targetEntity.id, followActorEntity.id) + logger.info("SUCCESS Follow from: {} to: {}", param.targetActor, param.actor) + } + + override fun job(): ReceiveFollowJob = ReceiveFollowJob + + companion object { + private val logger = LoggerFactory.getLogger(APReceiveFollowJobProcessor::class.java) + } +} From ac4aa8a2316f36dd4a801aece09d9dd2b23b9c44 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 27 Nov 2023 13:43:37 +0900 Subject: [PATCH 13/21] =?UTF-8?q?feat:=20=E3=81=9D=E3=81=AE=E4=BB=96?= =?UTF-8?q?=E3=81=AEActivityPub=E3=83=97=E3=83=AD=E3=82=BB=E3=83=83?= =?UTF-8?q?=E3=82=B5=E3=83=BC=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activity/accept/APAcceptService.kt | 1 + .../activity/accept/ApAcceptProcessor.kt | 50 +++++++++++++++++ .../activity/delete/APDeleteProcessor.kt | 35 ++++++++++++ .../activity/follow/APFollowProcessor.kt | 35 ++++++++++++ .../follow/APReceiveFollowJobService.kt | 1 + .../follow/APReceiveFollowJobServiceImpl.kt | 1 + .../service/activity/like/APLikeProcessor.kt | 54 +++++++++++++++++++ .../service/activity/undo/APUndoProcessor.kt | 53 ++++++++++++++++++ .../common/AbstractActivityPubProcessor.kt | 2 +- 9 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessor.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APFollowProcessor.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeProcessor.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoProcessor.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptService.kt index 2e845715..b702a791 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptService.kt @@ -10,6 +10,7 @@ import dev.usbharu.hideout.core.service.user.UserService import org.slf4j.LoggerFactory import org.springframework.stereotype.Service +@Deprecated("use activitypub processor") interface APAcceptService { suspend fun receiveAccept(accept: Accept) } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessor.kt new file mode 100644 index 00000000..6060531f --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessor.kt @@ -0,0 +1,50 @@ +package dev.usbharu.hideout.activitypub.service.activity.accept + +import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException +import dev.usbharu.hideout.activitypub.domain.model.Accept +import dev.usbharu.hideout.activitypub.domain.model.Follow +import dev.usbharu.hideout.activitypub.service.common.AbstractActivityPubProcessor +import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessContext +import dev.usbharu.hideout.activitypub.service.common.ActivityType +import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.query.FollowerQueryService +import dev.usbharu.hideout.core.query.UserQueryService +import dev.usbharu.hideout.core.service.user.UserService + +class ApAcceptProcessor( + private val transaction: Transaction, + private val userQueryService: UserQueryService, + private val followerQueryService: FollowerQueryService, + private val userService: UserService +) : + AbstractActivityPubProcessor(transaction) { + + override suspend fun internalProcess(activity: ActivityPubProcessContext) { + val value = activity.activity.`object` ?: throw IllegalActivityPubObjectException("object is null") + + if (value.type.contains("Follow").not()) { + logger.warn("FAILED Activity type is not Follow.") + throw IllegalActivityPubObjectException("Invalid type ${value.type}") + } + + val follow = value as Follow + + val userUrl = follow.`object` ?: throw IllegalActivityPubObjectException("object is null") + val followerUrl = follow.actor ?: throw IllegalActivityPubObjectException("actor is null") + + val user = userQueryService.findByUrl(userUrl) + val follower = userQueryService.findByUrl(followerUrl) + + if (followerQueryService.alreadyFollow(user.id, follower.id)) { + logger.debug("END User already follow from ${follower.url} to ${user.url}.") + return + } + + userService.follow(user.id, follower.id) + logger.debug("SUCCESS Follow from ${follower.url} to ${user.url}.") + } + + override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Accept + + override fun type(): Class = Accept::class.java +} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt new file mode 100644 index 00000000..fee94bad --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt @@ -0,0 +1,35 @@ +package dev.usbharu.hideout.activitypub.service.activity.delete + +import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException +import dev.usbharu.hideout.activitypub.domain.model.Delete +import dev.usbharu.hideout.activitypub.service.common.AbstractActivityPubProcessor +import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessContext +import dev.usbharu.hideout.activitypub.service.common.ActivityType +import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.domain.model.post.PostRepository +import dev.usbharu.hideout.core.query.PostQueryService + +class APDeleteProcessor( + transaction: Transaction, + private val postQueryService: PostQueryService, + private val postRepository: PostRepository +) : + AbstractActivityPubProcessor(transaction) { + override suspend fun internalProcess(activity: ActivityPubProcessContext) { + val deleteId = activity.activity.`object`?.id ?: throw IllegalActivityPubObjectException("object.id is null") + + val post = try { + postQueryService.findByApId(deleteId) + } catch (e: FailedToGetResourcesException) { + logger.warn("FAILED delete id: {} is not found.", deleteId) + return + } + + postRepository.delete(post.id) + } + + override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Delete + + override fun type(): Class = Delete::class.java +} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APFollowProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APFollowProcessor.kt new file mode 100644 index 00000000..92ad3e28 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APFollowProcessor.kt @@ -0,0 +1,35 @@ +package dev.usbharu.hideout.activitypub.service.activity.follow + +import com.fasterxml.jackson.databind.ObjectMapper +import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException +import dev.usbharu.hideout.activitypub.domain.model.Follow +import dev.usbharu.hideout.activitypub.service.common.AbstractActivityPubProcessor +import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessContext +import dev.usbharu.hideout.activitypub.service.common.ActivityType +import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.external.job.ReceiveFollowJob +import dev.usbharu.hideout.core.external.job.ReceiveFollowJobParam +import dev.usbharu.hideout.core.service.job.JobQueueParentService + +class APFollowProcessor( + transaction: Transaction, + private val jobQueueParentService: JobQueueParentService, + private val objectMapper: ObjectMapper +) : + AbstractActivityPubProcessor(transaction) { + override suspend fun internalProcess(activity: ActivityPubProcessContext) { + logger.info("FOLLOW from: {} to {}", activity.activity.actor, activity.activity.`object`) + + // inboxをジョブキューに乗せているので既に不要だが、フォロー承認制アカウントを実装する際に必要なので残す + val jobProps = ReceiveFollowJobParam( + activity.activity.actor ?: throw IllegalActivityPubObjectException("actor is null"), + objectMapper.writeValueAsString(activity.activity), + activity.activity.`object` ?: throw IllegalActivityPubObjectException("object is null") + ) + jobQueueParentService.scheduleTypeSafe(ReceiveFollowJob, jobProps) + } + + override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Follow + + override fun type(): Class = Follow::class.java +} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobService.kt index 2b7a84d4..d3c106b9 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobService.kt @@ -3,6 +3,7 @@ package dev.usbharu.hideout.activitypub.service.activity.follow import dev.usbharu.hideout.core.external.job.ReceiveFollowJob import kjob.core.job.JobProps +@Deprecated("use activitypub processor") interface APReceiveFollowJobService { suspend fun receiveFollowJob(props: JobProps) } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobServiceImpl.kt index 02a466ab..86056b69 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobServiceImpl.kt @@ -16,6 +16,7 @@ import org.springframework.beans.factory.annotation.Qualifier import org.springframework.stereotype.Component @Component +@Deprecated("use activitypub processor") class APReceiveFollowJobServiceImpl( private val apUserService: APUserService, private val userQueryService: UserQueryService, diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeProcessor.kt new file mode 100644 index 00000000..470eaee7 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeProcessor.kt @@ -0,0 +1,54 @@ +package dev.usbharu.hideout.activitypub.service.activity.like + +import dev.usbharu.hideout.activitypub.domain.exception.FailedToGetActivityPubResourceException +import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException +import dev.usbharu.hideout.activitypub.domain.model.Like +import dev.usbharu.hideout.activitypub.service.common.AbstractActivityPubProcessor +import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessContext +import dev.usbharu.hideout.activitypub.service.common.ActivityType +import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService +import dev.usbharu.hideout.activitypub.service.objects.user.APUserService +import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.query.PostQueryService +import dev.usbharu.hideout.core.service.reaction.ReactionService + +class APLikeProcessor( + transaction: Transaction, + private val apUserService: APUserService, + private val apNoteService: APNoteService, + private val postQueryService: PostQueryService, + private val reactionService: ReactionService +) : + AbstractActivityPubProcessor(transaction) { + override suspend fun internalProcess(activity: ActivityPubProcessContext) { + val actor = activity.activity.actor ?: throw IllegalActivityPubObjectException("actor is null") + val content = activity.activity.content ?: throw IllegalActivityPubObjectException("content is null") + + val target = activity.activity.`object` ?: throw IllegalActivityPubObjectException("object is null") + + val personWithEntity = apUserService.fetchPersonWithEntity(actor) + + try { + apNoteService.fetchNoteAsync(target).await() + } catch (e: FailedToGetActivityPubResourceException) { + logger.debug("FAILED failed to get {}", target) + logger.trace("", e) + return + } + + val post = postQueryService.findByUrl(target) + + reactionService.receiveReaction( + content, + actor.substringAfter("://").substringBefore("/"), + personWithEntity.second.id, + post.id + ) + + logger.debug("SUCCESS Add Like($content) from ${personWithEntity.second.url} to ${post.url}") + } + + override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Like + + override fun type(): Class = Like::class.java +} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoProcessor.kt new file mode 100644 index 00000000..8c09b54f --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoProcessor.kt @@ -0,0 +1,53 @@ +package dev.usbharu.hideout.activitypub.service.activity.undo + +import dev.usbharu.hideout.activitypub.domain.model.Follow +import dev.usbharu.hideout.activitypub.domain.model.Undo +import dev.usbharu.hideout.activitypub.service.common.AbstractActivityPubProcessor +import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessContext +import dev.usbharu.hideout.activitypub.service.common.ActivityType +import dev.usbharu.hideout.activitypub.service.objects.user.APUserService +import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.query.UserQueryService +import dev.usbharu.hideout.core.service.user.UserService + +class APUndoProcessor( + transaction: Transaction, + private val apUserService: APUserService, + private val userQueryService: UserQueryService, + private val userService: UserService +) : + AbstractActivityPubProcessor(transaction) { + override suspend fun internalProcess(activity: ActivityPubProcessContext) { + val undo = activity.activity + if (undo.actor == null) { + return + } + + val type = + undo.`object`?.type.orEmpty() + .firstOrNull { it == "Block" || it == "Follow" || it == "Like" || it == "Announce" || it == "Accept" } + ?: return + + when (type) { + "Follow" -> { + val follow = undo.`object` as Follow + + if (follow.`object` == null) { + return + } + apUserService.fetchPerson(undo.actor!!, follow.`object`) + val follower = userQueryService.findByUrl(undo.actor!!) + val target = userQueryService.findByUrl(follow.`object`!!) + userService.unfollow(target.id, follower.id) + return + } + + else -> {} + } + TODO() + } + + override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Undo + + override fun type(): Class = Undo::class.java +} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/AbstractActivityPubProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/AbstractActivityPubProcessor.kt index 8cddae81..bfc7d24e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/AbstractActivityPubProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/AbstractActivityPubProcessor.kt @@ -11,7 +11,7 @@ abstract class AbstractActivityPubProcessor( private val transaction: Transaction, private val allowUnauthorized: Boolean = false ) : ActivityPubProcessor { - private val logger = LoggerFactory.getLogger(this::class.java) + protected val logger = LoggerFactory.getLogger(this::class.java) override suspend fun process(activity: ActivityPubProcessContext) { if (activity.isAuthorized.not() && allowUnauthorized.not()) { From 3243a0126ff2a4f8c9a6544d26dceb7d828b712b Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 27 Nov 2023 13:52:42 +0900 Subject: [PATCH 14/21] =?UTF-8?q?feat:=20=E4=B8=8D=E8=A6=81=E3=81=AB?= =?UTF-8?q?=E3=81=AA=E3=81=A3=E3=81=9FAPService=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activity/accept/APAcceptService.kt | 55 ---------------- .../activity/create/APCreateService.kt | 40 ------------ .../activity/delete/APReceiveDeleteService.kt | 7 --- .../delete/APReceiveDeleteServiceImpl.kt | 28 --------- .../service/activity/like/APLikeService.kt | 63 ------------------- .../service/activity/undo/APUndoService.kt | 53 ---------------- 6 files changed, 246 deletions(-) delete mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptService.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/APCreateService.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteService.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteServiceImpl.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeService.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptService.kt deleted file mode 100644 index b702a791..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptService.kt +++ /dev/null @@ -1,55 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.activity.accept - -import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException -import dev.usbharu.hideout.activitypub.domain.model.Accept -import dev.usbharu.hideout.activitypub.domain.model.Follow -import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.query.FollowerQueryService -import dev.usbharu.hideout.core.query.UserQueryService -import dev.usbharu.hideout.core.service.user.UserService -import org.slf4j.LoggerFactory -import org.springframework.stereotype.Service - -@Deprecated("use activitypub processor") -interface APAcceptService { - suspend fun receiveAccept(accept: Accept) -} - -@Service -class APAcceptServiceImpl( - private val userService: UserService, - private val userQueryService: UserQueryService, - private val followerQueryService: FollowerQueryService, - private val transaction: Transaction -) : APAcceptService { - override suspend fun receiveAccept(accept: Accept) { - return transaction.transaction { - LOGGER.debug("START Follow") - LOGGER.trace("{}", accept) - val value = accept.`object` ?: throw IllegalActivityPubObjectException("object is null") - if (value.type.contains("Follow").not()) { - LOGGER.warn("FAILED Activity type is not 'Follow'") - throw IllegalActivityPubObjectException("Invalid type ${value.type}") - } - - val follow = value as Follow - val userUrl = follow.`object` ?: throw IllegalActivityPubObjectException("object is null") - val followerUrl = follow.actor ?: throw IllegalActivityPubObjectException("actor is null") - - val user = userQueryService.findByUrl(userUrl) - val follower = userQueryService.findByUrl(followerUrl) - - if (followerQueryService.alreadyFollow(user.id, follower.id)) { - LOGGER.debug("END User already follow from ${follower.url} to ${user.url}") - return@transaction - } - userService.follow(user.id, follower.id) - LOGGER.debug("SUCCESS Follow from ${follower.url} to ${user.url}.") - - } - } - - companion object { - private val LOGGER = LoggerFactory.getLogger(APAcceptServiceImpl::class.java) - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/APCreateService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/APCreateService.kt deleted file mode 100644 index afcf4881..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/APCreateService.kt +++ /dev/null @@ -1,40 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.activity.create - -import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException -import dev.usbharu.hideout.activitypub.domain.model.Create -import dev.usbharu.hideout.activitypub.domain.model.Note -import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService -import dev.usbharu.hideout.application.external.Transaction -import org.slf4j.LoggerFactory -import org.springframework.stereotype.Service - -interface APCreateService { - suspend fun receiveCreate(create: Create) -} - -@Service -class APCreateServiceImpl( - private val apNoteService: APNoteService, - private val transaction: Transaction -) : APCreateService { - override suspend fun receiveCreate(create: Create) { - LOGGER.debug("START Create new remote note.") - LOGGER.trace("{}", create) - - val value = create.`object` ?: throw IllegalActivityPubObjectException("object is null") - if (value.type.contains("Note").not()) { - LOGGER.warn("FAILED Object type is not 'Note'") - throw IllegalActivityPubObjectException("object is not Note") - } - - return transaction.transaction { - val note = value as Note - apNoteService.fetchNote(note) - LOGGER.debug("SUCCESS Create new remote note. ${note.id} by ${note.attributedTo}") - } - } - - companion object { - private val LOGGER = LoggerFactory.getLogger(APCreateServiceImpl::class.java) - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteService.kt deleted file mode 100644 index 68505f22..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteService.kt +++ /dev/null @@ -1,7 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.activity.delete - -import dev.usbharu.hideout.activitypub.domain.model.Delete - -interface APReceiveDeleteService { - suspend fun receiveDelete(delete: Delete) -} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteServiceImpl.kt deleted file mode 100644 index e75fa90c..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteServiceImpl.kt +++ /dev/null @@ -1,28 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.activity.delete - -import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException -import dev.usbharu.hideout.activitypub.domain.model.Delete -import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException -import dev.usbharu.hideout.core.domain.model.post.PostRepository -import dev.usbharu.hideout.core.query.PostQueryService -import org.springframework.stereotype.Service - -@Service -class APReceiveDeleteServiceImpl( - private val postQueryService: PostQueryService, - private val postRepository: PostRepository, - private val transaction: Transaction -) : APReceiveDeleteService { - override suspend fun receiveDelete(delete: Delete) = transaction.transaction { - val deleteId = delete.`object`?.id ?: throw IllegalActivityPubObjectException("object.id is null") - - val post = try { - postQueryService.findByApId(deleteId) - } catch (_: FailedToGetResourcesException) { - return@transaction - } - postRepository.delete(post.id) - return@transaction - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeService.kt deleted file mode 100644 index 5b59550e..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeService.kt +++ /dev/null @@ -1,63 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.activity.like - -import dev.usbharu.hideout.activitypub.domain.exception.FailedToGetActivityPubResourceException -import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException -import dev.usbharu.hideout.activitypub.domain.model.Like -import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService -import dev.usbharu.hideout.activitypub.service.objects.user.APUserService -import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.query.PostQueryService -import dev.usbharu.hideout.core.service.reaction.ReactionService -import org.slf4j.LoggerFactory -import org.springframework.stereotype.Service - -interface APLikeService { - suspend fun receiveLike(like: Like) -} - -@Service -class APLikeServiceImpl( - private val reactionService: ReactionService, - private val apUserService: APUserService, - private val apNoteService: APNoteService, - private val postQueryService: PostQueryService, - private val transaction: Transaction -) : APLikeService { - override suspend fun receiveLike(like: Like) { - LOGGER.debug("START Add Like") - LOGGER.trace("{}", like) - - val actor = like.actor ?: throw IllegalActivityPubObjectException("actor is null") - val content = like.content ?: throw IllegalActivityPubObjectException("content is null") - like.`object` ?: throw IllegalActivityPubObjectException("object is null") - transaction.transaction { - LOGGER.trace("FETCH Liked Person $actor") - val person = apUserService.fetchPersonWithEntity(actor) - LOGGER.trace("{}", person.second) - - LOGGER.trace("FETCH Liked Note ${like.`object`}") - try { - apNoteService.fetchNoteAsync(like.`object` ?: return@transaction).await() - } catch (e: FailedToGetActivityPubResourceException) { - LOGGER.debug("FAILED Failed to Get ${like.`object`}") - LOGGER.trace("", e) - return@transaction - } - val post = postQueryService.findByUrl(like.`object` ?: return@transaction) - LOGGER.trace("{}", post) - - reactionService.receiveReaction( - content, - actor.substringAfter("://").substringBefore("/"), - person.second.id, - post.id - ) - LOGGER.debug("SUCCESS Add Like($content) from ${person.second.url} to ${post.url}") - } - return - } - - companion object { - private val LOGGER = LoggerFactory.getLogger(APLikeServiceImpl::class.java) - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoService.kt deleted file mode 100644 index e0348b6c..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoService.kt +++ /dev/null @@ -1,53 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.activity.undo - -import dev.usbharu.hideout.activitypub.domain.model.Follow -import dev.usbharu.hideout.activitypub.domain.model.Undo -import dev.usbharu.hideout.activitypub.service.objects.user.APUserService -import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.query.UserQueryService -import dev.usbharu.hideout.core.service.user.UserService -import org.springframework.stereotype.Service - -interface APUndoService { - suspend fun receiveUndo(undo: Undo) -} - -@Service -@Suppress("UnsafeCallOnNullableType") -class APUndoServiceImpl( - private val userService: UserService, - private val apUserService: APUserService, - private val userQueryService: UserQueryService, - private val transaction: Transaction -) : APUndoService { - override suspend fun receiveUndo(undo: Undo) { - if (undo.actor == null) { - return - } - - val type = - undo.`object`?.type.orEmpty() - .firstOrNull { it == "Block" || it == "Follow" || it == "Like" || it == "Announce" || it == "Accept" } - ?: return - - when (type) { - "Follow" -> { - val follow = undo.`object` as Follow - - if (follow.`object` == null) { - return - } - transaction.transaction { - apUserService.fetchPerson(undo.actor!!, follow.`object`) - val follower = userQueryService.findByUrl(undo.actor!!) - val target = userQueryService.findByUrl(follow.`object`!!) - userService.unfollow(target.id, follower.id) - } - return - } - - else -> {} - } - TODO() - } -} From 1b721c5a0c660227425a7028b0956fcd3d1069a0 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 27 Nov 2023 14:09:44 +0900 Subject: [PATCH 15/21] =?UTF-8?q?feat:=20=E3=81=9D=E3=81=AE=E4=BB=96?= =?UTF-8?q?=E3=81=AEJobProcessor=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activity/like/ApReactionJobProcessor.kt | 35 +++++++++++++++ .../like/ApRemoveReactionJobProcessor.kt | 43 +++++++++++++++++++ .../objects/note/ApNoteJobProcessor.kt | 40 +++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApReactionJobProcessor.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApRemoveReactionJobProcessor.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobProcessor.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApReactionJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApReactionJobProcessor.kt new file mode 100644 index 00000000..af3f2f09 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApReactionJobProcessor.kt @@ -0,0 +1,35 @@ +package dev.usbharu.hideout.activitypub.service.activity.like + +import dev.usbharu.hideout.activitypub.domain.model.Like +import dev.usbharu.hideout.activitypub.service.common.APRequestService +import dev.usbharu.hideout.application.config.ApplicationConfig +import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.external.job.DeliverReactionJob +import dev.usbharu.hideout.core.external.job.DeliverReactionJobParam +import dev.usbharu.hideout.core.query.UserQueryService +import dev.usbharu.hideout.core.service.job.JobProcessor + +class ApReactionJobProcessor( + private val userQueryService: UserQueryService, + private val apRequestService: APRequestService, + private val applicationConfig: ApplicationConfig, + private val transaction: Transaction +) : JobProcessor { + override suspend fun process(param: DeliverReactionJobParam): Unit = transaction.transaction { + val signer = userQueryService.findByUrl(param.actor) + + apRequestService.apPost( + param.inbox, + Like( + name = "Like", + actor = param.actor, + `object` = param.postUrl, + id = "${applicationConfig.url}/liek/note/${param.id}", + content = param.reaction + ), + signer + ) + } + + override fun job(): DeliverReactionJob = DeliverReactionJob +} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApRemoveReactionJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApRemoveReactionJobProcessor.kt new file mode 100644 index 00000000..dadbe66e --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApRemoveReactionJobProcessor.kt @@ -0,0 +1,43 @@ +package dev.usbharu.hideout.activitypub.service.activity.like + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import dev.usbharu.hideout.activitypub.domain.model.Like +import dev.usbharu.hideout.activitypub.domain.model.Undo +import dev.usbharu.hideout.activitypub.service.common.APRequestService +import dev.usbharu.hideout.application.config.ApplicationConfig +import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.external.job.DeliverRemoveReactionJob +import dev.usbharu.hideout.core.external.job.DeliverRemoveReactionJobParam +import dev.usbharu.hideout.core.query.UserQueryService +import dev.usbharu.hideout.core.service.job.JobProcessor +import java.time.Instant + +class ApRemoveReactionJobProcessor( + private val userQueryService: UserQueryService, + private val transaction: Transaction, + private val objectMapper: ObjectMapper, + private val apRequestService: APRequestService, + private val applicationConfig: ApplicationConfig +) : JobProcessor { + override suspend fun process(param: DeliverRemoveReactionJobParam): Unit = transaction.transaction { + + val like = objectMapper.readValue(param.like) + + val signer = userQueryService.findByUrl(param.actor) + + apRequestService.apPost( + param.inbox, + Undo( + name = "Undo Reaction", + actor = param.actor, + `object` = like, + id = "${applicationConfig.url}/undo/like/${param.id}", + published = Instant.now() + ), + signer + ) + } + + override fun job(): DeliverRemoveReactionJob = DeliverRemoveReactionJob +} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobProcessor.kt new file mode 100644 index 00000000..df54350d --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobProcessor.kt @@ -0,0 +1,40 @@ +package dev.usbharu.hideout.activitypub.service.objects.note + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import dev.usbharu.hideout.activitypub.domain.model.Create +import dev.usbharu.hideout.activitypub.service.common.APRequestService +import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.external.job.DeliverPostJob +import dev.usbharu.hideout.core.external.job.DeliverPostJobParam +import dev.usbharu.hideout.core.query.UserQueryService +import dev.usbharu.hideout.core.service.job.JobProcessor +import org.slf4j.LoggerFactory + +class ApNoteJobProcessor( + private val transaction: Transaction, + private val objectMapper: ObjectMapper, + private val userQueryService: UserQueryService, + private val apRequestService: APRequestService +) : JobProcessor { + override suspend fun process(param: DeliverPostJobParam) { + val create = objectMapper.readValue(param.create) + transaction.transaction { + val signer = userQueryService.findByUrl(param.actor) + + logger.debug("CreateNoteJob: actor: {} create: {} inbox: {}", param.actor, create, param.inbox) + + apRequestService.apPost( + param.inbox, + create, + signer + ) + } + } + + override fun job(): DeliverPostJob = DeliverPostJob + + companion object { + private val logger = LoggerFactory.getLogger(ApNoteJobProcessor::class.java) + } +} From 640dff53cf6881c1d7fe1617319a0438b23f713c Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 27 Nov 2023 14:13:08 +0900 Subject: [PATCH 16/21] =?UTF-8?q?refactor:=20=E4=B8=8D=E8=A6=81=E3=81=AB?= =?UTF-8?q?=E3=81=AA=E3=81=A3=E3=81=9FAPService=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../follow/APReceiveFollowJobService.kt | 9 --- .../follow/APReceiveFollowJobServiceImpl.kt | 62 ----------------- .../activity/like/ApReactionJobService.kt | 10 --- .../activity/like/ApReactionJobServiceImpl.kt | 66 ------------------- .../service/common/ApJobServiceImpl.kt | 58 ---------------- .../service/objects/note/ApNoteJobService.kt | 8 --- .../objects/note/ApNoteJobServiceImpl.kt | 41 ------------ 7 files changed, 254 deletions(-) delete mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobService.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobServiceImpl.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApReactionJobService.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApReactionJobServiceImpl.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobService.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobService.kt deleted file mode 100644 index d3c106b9..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobService.kt +++ /dev/null @@ -1,9 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.activity.follow - -import dev.usbharu.hideout.core.external.job.ReceiveFollowJob -import kjob.core.job.JobProps - -@Deprecated("use activitypub processor") -interface APReceiveFollowJobService { - suspend fun receiveFollowJob(props: JobProps) -} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobServiceImpl.kt deleted file mode 100644 index 86056b69..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobServiceImpl.kt +++ /dev/null @@ -1,62 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.activity.follow - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import dev.usbharu.hideout.activitypub.domain.model.Accept -import dev.usbharu.hideout.activitypub.domain.model.Follow -import dev.usbharu.hideout.activitypub.service.common.APRequestService -import dev.usbharu.hideout.activitypub.service.objects.user.APUserService -import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.external.job.ReceiveFollowJob -import dev.usbharu.hideout.core.query.UserQueryService -import dev.usbharu.hideout.core.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 -@Deprecated("use activitypub processor") -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/activitypub/service/activity/like/ApReactionJobService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApReactionJobService.kt deleted file mode 100644 index ca43443f..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApReactionJobService.kt +++ /dev/null @@ -1,10 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.activity.like - -import dev.usbharu.hideout.core.external.job.DeliverReactionJob -import dev.usbharu.hideout.core.external.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/activitypub/service/activity/like/ApReactionJobServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApReactionJobServiceImpl.kt deleted file mode 100644 index 5a8e088c..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApReactionJobServiceImpl.kt +++ /dev/null @@ -1,66 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.activity.like - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import dev.usbharu.hideout.activitypub.domain.model.Like -import dev.usbharu.hideout.activitypub.domain.model.Undo -import dev.usbharu.hideout.activitypub.service.common.APRequestService -import dev.usbharu.hideout.application.config.ApplicationConfig -import dev.usbharu.hideout.core.external.job.DeliverReactionJob -import dev.usbharu.hideout.core.external.job.DeliverRemoveReactionJob -import dev.usbharu.hideout.core.query.UserQueryService -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 id = props[DeliverRemoveReactionJob.id] - - val signer = userQueryService.findByUrl(actor) - - apRequestService.apPost( - inbox, - Undo( - name = "Undo Reaction", - actor = actor, - `object` = like, - id = "${applicationConfig.url}/undo/note/$id", - published = Instant.now() - ), - signer - ) - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt deleted file mode 100644 index 64505017..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt +++ /dev/null @@ -1,58 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.common - -import com.fasterxml.jackson.databind.ObjectMapper -import dev.usbharu.hideout.activitypub.service.activity.follow.APReceiveFollowJobService -import dev.usbharu.hideout.activitypub.service.activity.like.ApReactionJobService -import dev.usbharu.hideout.activitypub.service.inbox.InboxJobProcessor -import dev.usbharu.hideout.activitypub.service.objects.note.ApNoteJobService -import dev.usbharu.hideout.core.external.job.* -import kjob.core.dsl.JobContextWithProps -import kjob.core.job.JobProps -import org.slf4j.LoggerFactory -import org.springframework.beans.factory.annotation.Qualifier -import org.springframework.stereotype.Service - -@Service -class ApJobServiceImpl( - private val apReceiveFollowJobService: APReceiveFollowJobService, - private val apNoteJobService: ApNoteJobService, - private val apReactionJobService: ApReactionJobService, - @Qualifier("activitypub") private val objectMapper: ObjectMapper, - private val inboxJobProcessor: InboxJobProcessor -) : 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 InboxJob -> { - inboxJobProcessor.process(job.props as JobProps) - } - - 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) - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobService.kt deleted file mode 100644 index ad7ea01e..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobService.kt +++ /dev/null @@ -1,8 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.objects.note - -import dev.usbharu.hideout.core.external.job.DeliverPostJob -import kjob.core.job.JobProps - -interface ApNoteJobService { - suspend fun createNoteJob(props: JobProps) -} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobServiceImpl.kt deleted file mode 100644 index 1e3dc801..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/ApNoteJobServiceImpl.kt +++ /dev/null @@ -1,41 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.objects.note - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import dev.usbharu.hideout.activitypub.domain.model.Create -import dev.usbharu.hideout.activitypub.service.common.APRequestService -import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.external.job.DeliverPostJob -import dev.usbharu.hideout.core.query.UserQueryService -import kjob.core.job.JobProps -import org.slf4j.LoggerFactory -import org.springframework.beans.factory.annotation.Qualifier -import org.springframework.stereotype.Component - -@Component -class ApNoteJobServiceImpl( - private val userQueryService: UserQueryService, - private val apRequestService: APRequestService, - @Qualifier("activitypub") private val objectMapper: ObjectMapper, - private val transaction: Transaction -) : ApNoteJobService { - override suspend fun createNoteJob(props: JobProps) { - val actor = props[DeliverPostJob.actor] - val create = objectMapper.readValue(props[DeliverPostJob.create]) - transaction.transaction { - val signer = userQueryService.findByUrl(actor) - - val inbox = props[DeliverPostJob.inbox] - logger.debug("createNoteJob: actor={}, create={}, inbox={}", actor, create, inbox) - apRequestService.apPost( - inbox, - create, - signer - ) - } - } - - companion object { - private val logger = LoggerFactory.getLogger(ApNoteJobServiceImpl::class.java) - } -} From a3adba6813ac4cd19d52d1e87e529e73458389e5 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 27 Nov 2023 14:23:51 +0900 Subject: [PATCH 17/21] =?UTF-8?q?test:=20=E4=B8=8D=E8=A6=81=E3=81=AA?= =?UTF-8?q?=E3=83=86=E3=82=B9=E3=83=88=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/inbox/InboxControllerImplTest.kt | 32 ++-- .../accept/APAcceptServiceImplTest.kt | 109 ----------- .../create/APCreateServiceImplTest.kt | 63 ------- .../follow/APReceiveFollowServiceImplTest.kt | 176 ------------------ .../activity/like/APLikeServiceImplTest.kt | 111 ----------- .../like/ApReactionJobServiceImplTest.kt | 128 ------------- .../activity/undo/APUndoServiceImplTest.kt | 47 ----- .../service/common/APServiceImplTest.kt | 114 +++--------- 8 files changed, 40 insertions(+), 740 deletions(-) delete mode 100644 src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptServiceImplTest.kt delete mode 100644 src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/APCreateServiceImplTest.kt delete mode 100644 src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowServiceImplTest.kt delete mode 100644 src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeServiceImplTest.kt delete mode 100644 src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApReactionJobServiceImplTest.kt delete mode 100644 src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoServiceImplTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImplTest.kt index 1f2ee0a0..4fe4a3b2 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImplTest.kt @@ -4,7 +4,6 @@ import dev.usbharu.hideout.activitypub.domain.exception.JsonParseException import dev.usbharu.hideout.activitypub.service.common.APService import dev.usbharu.hideout.activitypub.service.common.ActivityType import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException -import io.ktor.http.* import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -12,10 +11,7 @@ import org.junit.jupiter.api.extension.ExtendWith import org.mockito.InjectMocks import org.mockito.Mock import org.mockito.junit.jupiter.MockitoExtension -import org.mockito.kotlin.doReturn -import org.mockito.kotlin.doThrow -import org.mockito.kotlin.eq -import org.mockito.kotlin.whenever +import org.mockito.kotlin.* import org.springframework.http.MediaType import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.get @@ -44,11 +40,15 @@ class InboxControllerImplTest { val json = """{"type":"Follow"}""" whenever(apService.parseActivity(eq(json))).doReturn(ActivityType.Follow) - whenever(apService.processActivity(eq(json), eq(ActivityType.Follow))).doReturn( - ActivityPubStringResponse( - HttpStatusCode.Accepted, "" + whenever( + apService.processActivity( + eq(json), + eq(ActivityType.Follow), + any(), + any() + ) - ) + ).doReturn(Unit) mockMvc .post("/inbox") { @@ -86,7 +86,9 @@ class InboxControllerImplTest { whenever( apService.processActivity( eq(json), - eq(ActivityType.Follow) + eq(ActivityType.Follow), + any(), + any() ) ).doThrow(FailedToGetResourcesException::class) @@ -113,10 +115,8 @@ class InboxControllerImplTest { val json = """{"type":"Follow"}""" whenever(apService.parseActivity(eq(json))).doReturn(ActivityType.Follow) - whenever(apService.processActivity(eq(json), eq(ActivityType.Follow))).doReturn( - ActivityPubStringResponse( - HttpStatusCode.Accepted, "" - ) + whenever(apService.processActivity(eq(json), eq(ActivityType.Follow), any(), any())).doReturn( + Unit ) mockMvc @@ -155,7 +155,9 @@ class InboxControllerImplTest { whenever( apService.processActivity( eq(json), - eq(ActivityType.Follow) + eq(ActivityType.Follow), + any(), + any() ) ).doThrow(FailedToGetResourcesException::class) diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptServiceImplTest.kt deleted file mode 100644 index 8f5ab942..00000000 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptServiceImplTest.kt +++ /dev/null @@ -1,109 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.activity.accept - -import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException -import dev.usbharu.hideout.activitypub.domain.model.Accept -import dev.usbharu.hideout.activitypub.domain.model.Follow -import dev.usbharu.hideout.activitypub.domain.model.Like -import dev.usbharu.hideout.core.query.FollowerQueryService -import dev.usbharu.hideout.core.query.UserQueryService -import dev.usbharu.hideout.core.service.user.UserService -import io.ktor.http.* -import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertThrows -import org.mockito.kotlin.* -import utils.TestTransaction -import utils.UserBuilder - -class APAcceptServiceImplTest { - - @Test - fun `receiveAccept 正常なAcceptを処理できる`() = runTest { - val actor = "https://example.com" - val follower = "https://follower.example.com" - val targetUser = UserBuilder.localUserOf() - val followerUser = UserBuilder.localUserOf() - val userQueryService = mock { - onBlocking { findByUrl(eq(actor)) } doReturn targetUser - onBlocking { findByUrl(eq(follower)) } doReturn followerUser - } - val followerQueryService = mock { - onBlocking { alreadyFollow(eq(targetUser.id), eq(followerUser.id)) } doReturn false - } - val userService = mock() - val apAcceptServiceImpl = - APAcceptServiceImpl(userService, userQueryService, followerQueryService, TestTransaction) - - val accept = Accept( - name = "Accept", - `object` = Follow( - name = "", - `object` = actor, - actor = follower - ), - actor = actor - ) - - - val actual = apAcceptServiceImpl.receiveAccept(accept) - assertEquals(ActivityPubStringResponse(HttpStatusCode.OK, "accepted"), actual) - verify(userService, times(1)).follow(eq(targetUser.id), eq(followerUser.id)) - } - - @Test - fun `receiveAccept 既にフォローしている場合は無視する`() = runTest { - - val actor = "https://example.com" - val follower = "https://follower.example.com" - val targetUser = UserBuilder.localUserOf() - val followerUser = UserBuilder.localUserOf() - val userQueryService = mock { - onBlocking { findByUrl(eq(actor)) } doReturn targetUser - onBlocking { findByUrl(eq(follower)) } doReturn followerUser - } - val followerQueryService = mock { - onBlocking { alreadyFollow(eq(targetUser.id), eq(followerUser.id)) } doReturn true - } - val userService = mock() - val apAcceptServiceImpl = - APAcceptServiceImpl(userService, userQueryService, followerQueryService, TestTransaction) - - val accept = Accept( - name = "Accept", - `object` = Follow( - name = "", - `object` = actor, - actor = follower - ), - actor = actor - ) - - - val actual = apAcceptServiceImpl.receiveAccept(accept) - assertEquals(ActivityPubStringResponse(HttpStatusCode.OK, "accepted"), actual) - verify(userService, times(0)).follow(eq(targetUser.id), eq(followerUser.id)) - } - - @Test - fun `revieveAccept AcceptのobjectのtypeがFollow以外の場合IllegalActivityPubObjectExceptionがthrowされる`() = - runTest { - val accept = Accept( - name = "Accept", - `object` = Like( - name = "Like", - actor = "actor", - id = "https://example.com", - `object` = "https://example.com", - content = "aaaa" - ), - actor = "https://example.com" - ) - - val apAcceptServiceImpl = APAcceptServiceImpl(mock(), mock(), mock(), TestTransaction) - - assertThrows { - apAcceptServiceImpl.receiveAccept(accept) - } - } -} diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/APCreateServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/APCreateServiceImplTest.kt deleted file mode 100644 index 5eaff691..00000000 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/APCreateServiceImplTest.kt +++ /dev/null @@ -1,63 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.activity.create - -import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException -import dev.usbharu.hideout.activitypub.domain.model.Create -import dev.usbharu.hideout.activitypub.domain.model.Like -import dev.usbharu.hideout.activitypub.domain.model.Note -import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService -import io.ktor.http.* -import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertThrows -import org.mockito.kotlin.* -import utils.TestTransaction - -class APCreateServiceImplTest { - - @Test - fun `receiveCreate 正常なCreateを処理できる`() = runTest { - val create = Create( - name = "Create", - `object` = Note( - name = "Note", - id = "https://example.com/note", - attributedTo = "https://example.com/actor", - content = "Hello World", - published = "Date: Wed, 21 Oct 2015 07:28:00 GMT" - ), - actor = "https://example.com/actor", - id = "https://example.com/create", - ) - - val apNoteService = mock() - val apCreateServiceImpl = APCreateServiceImpl(apNoteService, TestTransaction) - - val actual = ActivityPubStringResponse(HttpStatusCode.OK, "Created") - - val receiveCreate = apCreateServiceImpl.receiveCreate(create) - verify(apNoteService, times(1)).fetchNote(any(), anyOrNull()) - assertEquals(actual, receiveCreate) - } - - @Test - fun `reveiveCreate CreateのobjectのtypeがNote以外の場合IllegalActivityPubObjectExceptionがthrowされる`() = runTest { - val create = Create( - name = "Create", - `object` = Like( - name = "Like", - id = "https://example.com/note", - actor = "https://example.com/actor", - `object` = "https://example.com/create", - content = "aaa" - ), - actor = "https://example.com/actor", - id = "https://example.com/create", - ) - - val apCreateServiceImpl = APCreateServiceImpl(mock(), TestTransaction) - assertThrows { - apCreateServiceImpl.receiveCreate(create) - } - } -} diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowServiceImplTest.kt deleted file mode 100644 index d80183dd..00000000 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowServiceImplTest.kt +++ /dev/null @@ -1,176 +0,0 @@ -@file:OptIn(ExperimentalCoroutinesApi::class) -@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") - -package dev.usbharu.hideout.activitypub.service.activity.follow - -import dev.usbharu.hideout.activitypub.domain.model.Follow -import dev.usbharu.hideout.activitypub.domain.model.Image -import dev.usbharu.hideout.activitypub.domain.model.Key -import dev.usbharu.hideout.activitypub.domain.model.Person -import dev.usbharu.hideout.activitypub.service.objects.user.APUserService -import dev.usbharu.hideout.application.config.ApplicationConfig -import dev.usbharu.hideout.application.config.CharacterLimit -import dev.usbharu.hideout.core.domain.model.post.Post -import dev.usbharu.hideout.core.domain.model.user.User -import dev.usbharu.hideout.core.external.job.ReceiveFollowJob -import dev.usbharu.hideout.core.query.UserQueryService -import dev.usbharu.hideout.core.service.job.JobQueueParentService -import dev.usbharu.hideout.core.service.user.UserService -import kjob.core.dsl.ScheduleContext -import kjob.core.job.JobProps -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.runTest -import kotlinx.serialization.json.Json -import org.junit.jupiter.api.Assertions.assertEquals -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 - -class APReceiveFollowServiceImplTest { - - val userBuilder = User.UserBuilder(CharacterLimit(), ApplicationConfig(URL("https://example.com"))) - val postBuilder = Post.PostBuilder(CharacterLimit()) - - @Test - fun `receiveFollow フォロー受付処理`() = runTest { - val jobQueueParentService = mock { - onBlocking { schedule(eq(ReceiveFollowJob), any()) } doReturn Unit - } - val activityPubFollowService = - APReceiveFollowServiceImpl( - jobQueueParentService, - objectMapper - ) - activityPubFollowService.receiveFollow( - Follow( - emptyList(), - "Follow", - "https://example.com", - "https://follower.example.com" - ) - ) - verify(jobQueueParentService, times(1)).schedule(eq(ReceiveFollowJob), any()) - argumentCaptor.(ReceiveFollowJob) -> Unit> { - verify(jobQueueParentService, times(1)).schedule(eq(ReceiveFollowJob), capture()) - val scheduleContext = ScheduleContext(Json) - firstValue.invoke(scheduleContext, ReceiveFollowJob) - val actor = scheduleContext.props.props[ReceiveFollowJob.actor.name] - val targetActor = scheduleContext.props.props[ReceiveFollowJob.targetActor.name] - val follow = scheduleContext.props.props[ReceiveFollowJob.follow.name] as String - assertEquals("https://follower.example.com", actor) - assertEquals("https://example.com", targetActor) - //language=JSON - assertEquals( - Json.parseToJsonElement( - """{ - "type": "Follow", - "name": "Follow", - "actor": "https://follower.example.com", - "object": "https://example.com" - -}""" - ), - Json.parseToJsonElement(follow) - ) - } - } - - @Test - fun `receiveFollowJob フォロー受付処理のJob`() = runTest { - val person = Person( - type = emptyList(), - name = "follower", - id = "https://follower.example.com", - preferredUsername = "followerUser", - summary = "This user is follower user.", - inbox = "https://follower.example.com/inbox", - outbox = "https://follower.example.com/outbox", - url = "https://follower.example.com", - icon = Image( - type = emptyList(), - name = "https://follower.example.com/image", - mediaType = "image/png", - url = "https://follower.example.com/image" - ), - publicKey = Key( - type = emptyList(), - name = "Public Key", - id = "https://follower.example.com#main-key", - owner = "https://follower.example.com", - publicKeyPem = "BEGIN PUBLIC KEY...END PUBLIC KEY", - ), - followers = "", - following = "" - - ) - val apUserService = mock { - onBlocking { fetchPerson(anyString(), any()) } doReturn person - } - val userQueryService = mock { - onBlocking { findByUrl(eq("https://example.com")) } doReturn - userBuilder.of( - id = 1L, - name = "test", - domain = "example.com", - screenName = "testUser", - description = "This user is test user.", - inbox = "https://example.com/inbox", - outbox = "https://example.com/outbox", - url = "https://example.com", - publicKey = "", - password = "a", - privateKey = "a", - createdAt = Instant.now(), - keyId = "a" - ) - onBlocking { findByUrl(eq("https://follower.example.com")) } doReturn - userBuilder.of( - id = 2L, - name = "follower", - domain = "follower.example.com", - screenName = "followerUser", - description = "This user is test follower user.", - inbox = "https://follower.example.com/inbox", - outbox = "https://follower.example.com/outbox", - url = "https://follower.example.com", - publicKey = "", - createdAt = Instant.now(), - keyId = "a" - ) - } - - val userService = mock { - onBlocking { followRequest(any(), any()) } doReturn false - } - val activityPubFollowService = - APReceiveFollowJobServiceImpl( - apUserService, - userQueryService, - mock(), - userService, - objectMapper, - TestTransaction - ) - activityPubFollowService.receiveFollowJob( - JobProps( - data = mapOf( - ReceiveFollowJob.actor.name to "https://follower.example.com", - ReceiveFollowJob.targetActor.name to "https://example.com", - //language=JSON - ReceiveFollowJob.follow.name to """{ - "type": "Follow", - "name": "Follow", - "object": "https://example.com", - "actor": "https://follower.example.com", - "@context": null -}""" - ), - json = Json - ) - ) - } -} diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeServiceImplTest.kt deleted file mode 100644 index 0cb421f5..00000000 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeServiceImplTest.kt +++ /dev/null @@ -1,111 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.activity.like - -import dev.usbharu.hideout.activitypub.domain.exception.FailedToGetActivityPubResourceException -import dev.usbharu.hideout.activitypub.domain.model.Like -import dev.usbharu.hideout.activitypub.domain.model.Note -import dev.usbharu.hideout.activitypub.domain.model.Person -import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService -import dev.usbharu.hideout.activitypub.service.objects.user.APUserService -import dev.usbharu.hideout.core.query.PostQueryService -import dev.usbharu.hideout.core.service.reaction.ReactionService -import io.ktor.http.* -import kotlinx.coroutines.async -import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test -import org.mockito.kotlin.* -import utils.PostBuilder -import utils.TestTransaction -import utils.UserBuilder - - -class APLikeServiceImplTest { - @Test - fun `receiveLike 正常なLikeを処理できる`() = runTest { - val actor = "https://example.com/actor" - val note = "https://example.com/note" - val like = Like( - name = "Like", actor = actor, id = "htps://example.com", `object` = note, content = "aaa" - ) - - val user = UserBuilder.localUserOf() - val apUserService = mock { - onBlocking { fetchPersonWithEntity(eq(actor), anyOrNull()) } doReturn (Person( - name = "TestUser", - id = "https://example.com", - preferredUsername = "Test user", - summary = "test user", - inbox = "https://example.com/inbox", - outbox = "https://example.com/outbox", - url = "https://example.com/", - icon = null, - publicKey = null, - followers = null, - following = null - ) to user) - } - val apNoteService = mock { - on { fetchNoteAsync(eq(note), anyOrNull()) } doReturn async { - Note( - name = "Note", - id = "https://example.com/note", - attributedTo = "https://example.com/actor", - content = "Hello World", - published = "Date: Wed, 21 Oct 2015 07:28:00 GMT", - ) - } - } - val post = PostBuilder.of() - val postQueryService = mock { - onBlocking { findByUrl(eq(note)) } doReturn post - } - val reactionService = mock() - val apLikeServiceImpl = APLikeServiceImpl( - reactionService, apUserService, apNoteService, postQueryService, TestTransaction - ) - - val actual = apLikeServiceImpl.receiveLike(like) - - verify(reactionService, times(1)).receiveReaction(eq("aaa"), eq("example.com"), eq(user.id), eq(post.id)) - assertEquals(ActivityPubStringResponse(HttpStatusCode.OK, ""), actual) - } - - @Test - fun `recieveLike Likeのobjectのurlが取得できないとき何もしない`() = runTest { - val actor = "https://example.com/actor" - val note = "https://example.com/note" - val like = Like( - name = "Like", actor = actor, id = "htps://example.com", `object` = note, content = "aaa" - ) - - val user = UserBuilder.localUserOf() - val apUserService = mock { - onBlocking { fetchPersonWithEntity(eq(actor), anyOrNull()) } doReturn (Person( - name = "TestUser", - id = "https://example.com", - preferredUsername = "Test user", - summary = "test user", - inbox = "https://example.com/inbox", - outbox = "https://example.com/outbox", - url = "https://example.com/", - icon = null, - publicKey = null, - followers = null, - following = null - ) to user) - } - val apNoteService = mock { - on { fetchNoteAsync(eq(note), anyOrNull()) } doThrow FailedToGetActivityPubResourceException() - } - - val reactionService = mock() - val apLikeServiceImpl = APLikeServiceImpl( - reactionService, apUserService, apNoteService, mock(), TestTransaction - ) - - val actual = apLikeServiceImpl.receiveLike(like) - - verify(reactionService, times(0)).receiveReaction(anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull()) - assertEquals(ActivityPubStringResponse(HttpStatusCode.OK, ""), actual) - } -} diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApReactionJobServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApReactionJobServiceImplTest.kt deleted file mode 100644 index 22763ca8..00000000 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApReactionJobServiceImplTest.kt +++ /dev/null @@ -1,128 +0,0 @@ -@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") - -package dev.usbharu.hideout.activitypub.service.activity.like - -import dev.usbharu.hideout.activitypub.domain.model.Like -import dev.usbharu.hideout.activitypub.domain.model.Undo -import dev.usbharu.hideout.activitypub.service.common.APRequestService -import dev.usbharu.hideout.application.config.ApplicationConfig -import dev.usbharu.hideout.core.external.job.DeliverReactionJob -import dev.usbharu.hideout.core.external.job.DeliverRemoveReactionJob -import dev.usbharu.hideout.core.query.UserQueryService -import kjob.core.job.JobProps -import kotlinx.coroutines.test.runTest -import kotlinx.serialization.json.Json -import org.junit.jupiter.api.Test -import org.mockito.Mockito.mockStatic -import org.mockito.kotlin.* -import utils.JsonObjectMapper.objectMapper -import utils.UserBuilder -import java.net.URL -import java.time.Instant - -class ApReactionJobServiceImplTest { - @Test - fun `reactionJob Likeが配送される`() = runTest { - - val localUser = UserBuilder.localUserOf() - val remoteUser = UserBuilder.remoteUserOf() - - val userQueryService = mock { - onBlocking { findByUrl(localUser.url) } doReturn localUser - } - val apRequestService = mock() - val apReactionJobServiceImpl = ApReactionJobServiceImpl( - userQueryService = userQueryService, - apRequestService = apRequestService, - applicationConfig = ApplicationConfig(URL("https://example.com")), - objectMapper = objectMapper - ) - - - val postUrl = "${remoteUser.url}/posts/1234" - - apReactionJobServiceImpl.reactionJob( - JobProps( - data = mapOf( - DeliverReactionJob.inbox.name to remoteUser.inbox, - DeliverReactionJob.actor.name to localUser.url, - DeliverReactionJob.postUrl.name to postUrl, - DeliverReactionJob.id.name to "1234", - DeliverReactionJob.reaction.name to "❤", - - ), - json = Json - ) - ) - - val body = Like( - name = "Like", - actor = localUser.url, - `object` = postUrl, - id = "https://example.com/like/note/1234", - content = "❤" - ) - - verify(apRequestService, times(1)).apPost(eq(remoteUser.inbox), eq(body), eq(localUser)) - - } - - @Test - fun `removeReactionJob LikeのUndoが配送される`() = runTest { - - val localUser = UserBuilder.localUserOf() - val remoteUser = UserBuilder.remoteUserOf() - - val userQueryService = mock { - onBlocking { findByUrl(localUser.url) } doReturn localUser - } - val apRequestService = mock() - val apReactionJobServiceImpl = ApReactionJobServiceImpl( - userQueryService = userQueryService, - apRequestService = apRequestService, - applicationConfig = ApplicationConfig(URL("https://example.com")), - objectMapper = objectMapper - ) - - - val postUrl = "${remoteUser.url}/posts/1234" - val like = Like( - name = "Like", - actor = remoteUser.url, - `object` = postUrl, - id = "https://example.com/like/note/1234", - content = "❤" - ) - - val now = Instant.now() - - val body = mockStatic(Instant::class.java).use { - - it.`when`(Instant::now).thenReturn(now) - - apReactionJobServiceImpl.removeReactionJob( - JobProps( - data = mapOf( - DeliverRemoveReactionJob.inbox.name to remoteUser.inbox, - DeliverRemoveReactionJob.actor.name to localUser.url, - DeliverRemoveReactionJob.id.name to "1234", - DeliverRemoveReactionJob.like.name to objectMapper.writeValueAsString(like), - - ), - json = Json - ) - ) - Undo( - name = "Undo Reaction", - actor = localUser.url, - `object` = like, - id = "https://example.com/undo/note/1234", - published = now - ) - } - - - - verify(apRequestService, times(1)).apPost(eq(remoteUser.inbox), eq(body), eq(localUser)) - } -} diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoServiceImplTest.kt deleted file mode 100644 index e465944e..00000000 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoServiceImplTest.kt +++ /dev/null @@ -1,47 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.activity.undo - -import dev.usbharu.hideout.activitypub.domain.model.Follow -import dev.usbharu.hideout.activitypub.domain.model.Undo -import dev.usbharu.hideout.core.query.UserQueryService -import io.ktor.http.* -import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test -import org.mockito.kotlin.doReturn -import org.mockito.kotlin.eq -import org.mockito.kotlin.mock -import utils.TestTransaction -import utils.UserBuilder -import java.time.Instant - -class APUndoServiceImplTest { - @Test - fun `receiveUndo FollowのUndoを処理できる`() = runTest { - - val userQueryService = mock { - onBlocking { findByUrl(eq("https://follower.example.com/actor")) } doReturn UserBuilder.remoteUserOf() - onBlocking { findByUrl(eq("https://example.com/actor")) } doReturn UserBuilder.localUserOf() - } - val apUndoServiceImpl = APUndoServiceImpl( - userService = mock(), - apUserService = mock(), - userQueryService = userQueryService, - transaction = TestTransaction - ) - - val undo = Undo( - name = "Undo", - actor = "https://follower.example.com/actor", - id = "https://follower.example.com/undo/follow", - `object` = Follow( - name = "Follow", - `object` = "https://example.com/actor", - actor = "https://follower.example.com/actor" - ), - published = Instant.now() - ) - val activityPubResponse = apUndoServiceImpl.receiveUndo(undo) - assertEquals(ActivityPubStringResponse(HttpStatusCode.OK, "Accept"), activityPubResponse) - } - -} diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APServiceImplTest.kt index 1b6591f8..b4dc586f 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/common/APServiceImplTest.kt @@ -11,13 +11,7 @@ class APServiceImplTest { @Test fun `parseActivity 正常なActivityをパースできる`() { val apServiceImpl = APServiceImpl( - apReceiveFollowService = mock(), - apUndoService = mock(), - apAcceptService = mock(), - apCreateService = mock(), - apLikeService = mock(), - apReceiveDeleteService = mock(), - objectMapper = objectMapper + objectMapper = objectMapper, jobQueueParentService = mock() ) //language=JSON @@ -29,13 +23,7 @@ class APServiceImplTest { @Test fun `parseActivity Typeが配列のActivityをパースできる`() { val apServiceImpl = APServiceImpl( - apReceiveFollowService = mock(), - apUndoService = mock(), - apAcceptService = mock(), - apCreateService = mock(), - apLikeService = mock(), - apReceiveDeleteService = mock(), - objectMapper = objectMapper + objectMapper = objectMapper, jobQueueParentService = mock() ) //language=JSON @@ -47,13 +35,7 @@ class APServiceImplTest { @Test fun `parseActivity Typeが配列で関係ない物が入っていてもパースできる`() { val apServiceImpl = APServiceImpl( - apReceiveFollowService = mock(), - apUndoService = mock(), - apAcceptService = mock(), - apCreateService = mock(), - apLikeService = mock(), - apReceiveDeleteService = mock(), - objectMapper = objectMapper + objectMapper = objectMapper, jobQueueParentService = mock() ) //language=JSON @@ -65,13 +47,8 @@ class APServiceImplTest { @Test fun `parseActivity jsonとして解釈できない場合JsonParseExceptionがthrowされる`() { val apServiceImpl = APServiceImpl( - apReceiveFollowService = mock(), - apUndoService = mock(), - apAcceptService = mock(), - apCreateService = mock(), - apLikeService = mock(), - apReceiveDeleteService = mock(), - objectMapper = objectMapper + + objectMapper = objectMapper, jobQueueParentService = mock() ) //language=JSON @@ -83,13 +60,8 @@ class APServiceImplTest { @Test fun `parseActivity 空の場合JsonParseExceptionがthrowされる`() { val apServiceImpl = APServiceImpl( - apReceiveFollowService = mock(), - apUndoService = mock(), - apAcceptService = mock(), - apCreateService = mock(), - apLikeService = mock(), - apReceiveDeleteService = mock(), - objectMapper = objectMapper + + objectMapper = objectMapper, jobQueueParentService = mock() ) //language=JSON @@ -101,13 +73,8 @@ class APServiceImplTest { @Test fun `parseActivity jsonにtypeプロパティがない場合JsonParseExceptionがthrowされる`() { val apServiceImpl = APServiceImpl( - apReceiveFollowService = mock(), - apUndoService = mock(), - apAcceptService = mock(), - apCreateService = mock(), - apLikeService = mock(), - apReceiveDeleteService = mock(), - objectMapper = objectMapper + + objectMapper = objectMapper, jobQueueParentService = mock() ) //language=JSON @@ -119,13 +86,8 @@ class APServiceImplTest { @Test fun `parseActivity typeが配列でないときtypeが未定義の場合IllegalArgumentExceptionがthrowされる`() { val apServiceImpl = APServiceImpl( - apReceiveFollowService = mock(), - apUndoService = mock(), - apAcceptService = mock(), - apCreateService = mock(), - apLikeService = mock(), - apReceiveDeleteService = mock(), - objectMapper = objectMapper + + objectMapper = objectMapper, jobQueueParentService = mock() ) //language=JSON @@ -137,13 +99,8 @@ class APServiceImplTest { @Test fun `parseActivity typeが配列のとき定義済みのtypeを見つけられなかった場合IllegalArgumentExceptionがthrowされる`() { val apServiceImpl = APServiceImpl( - apReceiveFollowService = mock(), - apUndoService = mock(), - apAcceptService = mock(), - apCreateService = mock(), - apLikeService = mock(), - apReceiveDeleteService = mock(), - objectMapper = objectMapper + + objectMapper = objectMapper, jobQueueParentService = mock() ) //language=JSON @@ -155,13 +112,8 @@ class APServiceImplTest { @Test fun `parseActivity typeが空の場合IllegalArgumentExceptionがthrowされる`() { val apServiceImpl = APServiceImpl( - apReceiveFollowService = mock(), - apUndoService = mock(), - apAcceptService = mock(), - apCreateService = mock(), - apLikeService = mock(), - apReceiveDeleteService = mock(), - objectMapper = objectMapper + + objectMapper = objectMapper, jobQueueParentService = mock() ) //language=JSON @@ -173,13 +125,8 @@ class APServiceImplTest { @Test fun `parseActivity typeに指定されている文字の判定がcase-insensitiveで行われる`() { val apServiceImpl = APServiceImpl( - apReceiveFollowService = mock(), - apUndoService = mock(), - apAcceptService = mock(), - apCreateService = mock(), - apLikeService = mock(), - apReceiveDeleteService = mock(), - objectMapper = objectMapper + + objectMapper = objectMapper, jobQueueParentService = mock() ) //language=JSON @@ -191,13 +138,8 @@ class APServiceImplTest { @Test fun `parseActivity typeが配列のとき指定されている文字の判定がcase-insensitiveで行われる`() { val apServiceImpl = APServiceImpl( - apReceiveFollowService = mock(), - apUndoService = mock(), - apAcceptService = mock(), - apCreateService = mock(), - apLikeService = mock(), - apReceiveDeleteService = mock(), - objectMapper = objectMapper + + objectMapper = objectMapper, jobQueueParentService = mock() ) //language=JSON @@ -209,13 +151,8 @@ class APServiceImplTest { @Test fun `parseActivity activityがarrayのときJsonParseExceptionがthrowされる`() { val apServiceImpl = APServiceImpl( - apReceiveFollowService = mock(), - apUndoService = mock(), - apAcceptService = mock(), - apCreateService = mock(), - apLikeService = mock(), - apReceiveDeleteService = mock(), - objectMapper = objectMapper + + objectMapper = objectMapper, jobQueueParentService = mock() ) //language=JSON @@ -227,13 +164,8 @@ class APServiceImplTest { @Test fun `parseActivity activityがvalueのときJsonParseExceptionがthrowされる`() { val apServiceImpl = APServiceImpl( - apReceiveFollowService = mock(), - apUndoService = mock(), - apAcceptService = mock(), - apCreateService = mock(), - apLikeService = mock(), - apReceiveDeleteService = mock(), - objectMapper = objectMapper + + objectMapper = objectMapper, jobQueueParentService = mock() ) //language=JSON From e40e2c0d969e87a693bfd62da2a4f22778b34514 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 27 Nov 2023 15:03:26 +0900 Subject: [PATCH 18/21] =?UTF-8?q?refactor:=20=E4=B8=8D=E8=A6=81=E3=81=AA?= =?UTF-8?q?=E4=BE=9D=E5=AD=98=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activitypub/service/common/ApJobService.kt | 8 -------- .../hideout/application/config/JobQueueRunner.kt | 16 ---------------- 2 files changed, 24 deletions(-) delete mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobService.kt deleted file mode 100644 index 3b50b777..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobService.kt +++ /dev/null @@ -1,8 +0,0 @@ -package dev.usbharu.hideout.activitypub.service.common - -import dev.usbharu.hideout.core.external.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/application/config/JobQueueRunner.kt b/src/main/kotlin/dev/usbharu/hideout/application/config/JobQueueRunner.kt index cc1580ea..1667b7ec 100644 --- a/src/main/kotlin/dev/usbharu/hideout/application/config/JobQueueRunner.kt +++ b/src/main/kotlin/dev/usbharu/hideout/application/config/JobQueueRunner.kt @@ -1,6 +1,5 @@ package dev.usbharu.hideout.application.config -import dev.usbharu.hideout.activitypub.service.common.ApJobService import dev.usbharu.hideout.core.external.job.HideoutJob import dev.usbharu.hideout.core.service.job.JobQueueParentService import dev.usbharu.hideout.core.service.job.JobQueueWorkerService @@ -29,24 +28,9 @@ class JobQueueRunner( @Component class JobQueueWorkerRunner( private val jobQueueWorkerService: JobQueueWorkerService, - private val jobs: List>, - private val apJobService: ApJobService ) : ApplicationRunner { override fun run(args: ApplicationArguments?) { LOGGER.info("Init job queue worker.") -// jobQueueWorkerService.init>( -// jobs.map { -// it to { -// execute { -// LOGGER.debug("excute job ${it.name}") -// apJobService.processActivity( -// job = this, -// hideoutJob = it -// ) -// } -// } -// } -// ) jobQueueWorkerService.init>(emptyList()) } From c0dffe7c9842c26cfd38773f24adef5ef7d9a1e4 Mon Sep 17 00:00:00 2001 From: usbharu Date: Mon, 27 Nov 2023 15:10:22 +0900 Subject: [PATCH 19/21] Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../service/activity/follow/APReceiveFollowJobProcessor.kt | 1 - .../service/activity/like/ApRemoveReactionJobProcessor.kt | 1 - .../service/common/AbstractActivityPubProcessor.kt | 1 - .../hideout/activitypub/service/inbox/InboxJobProcessor.kt | 1 - .../dev/usbharu/hideout/core/external/job/HideoutJob.kt | 5 +++-- .../infrastructure/kjobexposed/KJobJobQueueWorkerService.kt | 5 ++++- .../kjobmongodb/KJobMongoJobQueueWorkerService.kt | 3 ++- 7 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobProcessor.kt index 91b88b79..a6aae23b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowJobProcessor.kt @@ -29,7 +29,6 @@ class APReceiveFollowJobProcessor( val person = apUserService.fetchPerson(param.actor, param.targetActor) val follow = objectMapper.readValue(param.follow) - logger.info("START Follow from: {} to {}", param.targetActor, param.actor) val signer = userQueryService.findByUrl(param.targetActor) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApRemoveReactionJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApRemoveReactionJobProcessor.kt index dadbe66e..307f0c16 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApRemoveReactionJobProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/ApRemoveReactionJobProcessor.kt @@ -21,7 +21,6 @@ class ApRemoveReactionJobProcessor( private val applicationConfig: ApplicationConfig ) : JobProcessor { override suspend fun process(param: DeliverRemoveReactionJobParam): Unit = transaction.transaction { - val like = objectMapper.readValue(param.like) val signer = userQueryService.findByUrl(param.actor) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/AbstractActivityPubProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/AbstractActivityPubProcessor.kt index bfc7d24e..329941b2 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/AbstractActivityPubProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/AbstractActivityPubProcessor.kt @@ -30,5 +30,4 @@ abstract class AbstractActivityPubProcessor( } abstract suspend fun internalProcess(activity: ActivityPubProcessContext) - } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/inbox/InboxJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/inbox/InboxJobProcessor.kt index 71614aca..51a49af9 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/inbox/InboxJobProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/inbox/InboxJobProcessor.kt @@ -35,7 +35,6 @@ class InboxJobProcessor( private val transaction: Transaction ) : JobProcessor { suspend fun process(props: JobProps) { - val type = ActivityType.valueOf(props[InboxJob.type]) val jsonString = objectMapper.readTree(props[InboxJob.json]) val httpRequestString = props[InboxJob.httpRequest] diff --git a/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt b/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt index 7ca2a630..8cd3647f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt @@ -29,7 +29,6 @@ object ReceiveFollowJob : HideoutJob("R props[follow] = value.follow props[actor] = value.actor props[targetActor] = value.targetActor - } override fun convert(props: JobProps): ReceiveFollowJobParam = ReceiveFollowJobParam( @@ -78,7 +77,9 @@ object DeliverReactionJob : HideoutJob = string("actor") val inbox: Prop = string("inbox") val id: Prop = string("id") - override fun convert(value: DeliverReactionJobParam): ScheduleContext.(DeliverReactionJob) -> Unit = + override fun convert( + value: DeliverReactionJobParam + ): ScheduleContext.(DeliverReactionJob) -> Unit = { props[reaction] = value.reaction props[postUrl] = value.postUrl diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueWorkerService.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueWorkerService.kt index 872a3249..a03272c4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueWorkerService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobexposed/KJobJobQueueWorkerService.kt @@ -24,7 +24,10 @@ class KJobJobQueueWorkerService(private val jobQueueProcessorList: List> init(defines: List>.(R) -> KJobFunctions>>>) { + override fun > init( + defines: + List>.(R) -> KJobFunctions>>> + ) { defines.forEach { job -> kjob.register(job.first, job.second) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KJobMongoJobQueueWorkerService.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KJobMongoJobQueueWorkerService.kt index 25fbdefe..5017fd0d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KJobMongoJobQueueWorkerService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KJobMongoJobQueueWorkerService.kt @@ -23,7 +23,8 @@ class KJobMongoJobQueueWorkerService(private val mongoClient: MongoClient) : Job }.start() } - override fun > init(defines: List>.(R) -> KJobFunctions>>>) { + override fun > init(defines: + List>.(R) -> KJobFunctions>>>) { defines.forEach { job -> kjob.register(job.first, job.second) } From e5d1a8d4a66cb744e1d809792ee5e8779cf60735 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 27 Nov 2023 15:52:49 +0900 Subject: [PATCH 20/21] style: fix lint --- .../interfaces/api/inbox/InboxControllerImpl.kt | 9 +++++---- .../hideout/core/domain/model/instance/Nodeinfo2_0.kt | 2 ++ .../kjobmongodb/KJobMongoJobQueueWorkerService.kt | 6 ++++-- .../dev/usbharu/hideout/core/service/job/JobProcessor.kt | 2 +- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImpl.kt index fc8acf7f..1ad9062c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImpl.kt @@ -13,14 +13,12 @@ import org.springframework.web.context.request.RequestContextHolder import org.springframework.web.context.request.ServletRequestAttributes import java.net.URL - @RestController class InboxControllerImpl(private val apService: APService) : InboxController { @Suppress("TooGenericExceptionCaught") override suspend fun inbox( @RequestBody string: String ): ResponseEntity { - val request = (requireNotNull(RequestContextHolder.getRequestAttributes()) as ServletRequestAttributes).request val parseActivity = try { @@ -48,11 +46,14 @@ class InboxControllerImpl(private val apService: APService) : InboxController { println(headers) apService.processActivity( - string, parseActivity, HttpRequest( + string, + parseActivity, + HttpRequest( URL(url + request.queryString.orEmpty()), HttpHeaders(headers), method - ), headers + ), + headers ) } catch (e: Exception) { LOGGER.warn("FAILED Process Activity $parseActivity", e) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/Nodeinfo2_0.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/Nodeinfo2_0.kt index fcd99c73..53479eee 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/Nodeinfo2_0.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/Nodeinfo2_0.kt @@ -1,3 +1,5 @@ +@file:Suppress("Filename") + package dev.usbharu.hideout.core.domain.model.instance @Suppress("ClassNaming") diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KJobMongoJobQueueWorkerService.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KJobMongoJobQueueWorkerService.kt index 5017fd0d..bb48b08b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KJobMongoJobQueueWorkerService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/kjobmongodb/KJobMongoJobQueueWorkerService.kt @@ -23,8 +23,10 @@ class KJobMongoJobQueueWorkerService(private val mongoClient: MongoClient) : Job }.start() } - override fun > init(defines: - List>.(R) -> KJobFunctions>>>) { + override fun > init( + defines: + List>.(R) -> KJobFunctions>>> + ) { defines.forEach { job -> kjob.register(job.first, job.second) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessor.kt index f6adc74b..7d38449f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/job/JobProcessor.kt @@ -2,7 +2,7 @@ package dev.usbharu.hideout.core.service.job import dev.usbharu.hideout.core.external.job.HideoutJob -interface JobProcessor> { +interface JobProcessor> { suspend fun process(param: @UnsafeVariance T) fun job(): R } From db2046b6e1d2211d71515beedf0bc4bd8ff85bfd Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 27 Nov 2023 16:04:06 +0900 Subject: [PATCH 21/21] style: fix lint --- .../hideout/activitypub/service/objects/user/APUserService.kt | 1 + .../springframework/httpsignature/HttpSignatureFilter.kt | 2 +- .../oauth2/ExposedOAuth2AuthorizationService.kt | 4 +++- .../service/media/converter/movie/MovieMediaProcessService.kt | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt index 9e8cb4b8..422b4874 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt @@ -77,6 +77,7 @@ class APUserServiceImpl( override suspend fun fetchPerson(url: String, targetActor: String?): Person = fetchPersonWithEntity(url, targetActor).first + @Suppress("LongMethod") override suspend fun fetchPersonWithEntity(url: String, targetActor: String?): Pair { return try { val userEntity = userQueryService.findByUrl(url) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureFilter.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureFilter.kt index 6a68e267..e814e568 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureFilter.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureFilter.kt @@ -37,7 +37,7 @@ class HttpSignatureFilter( transaction.transaction { try { userQueryService.findByKeyId(signature.keyId) - } catch (e: FailedToGetResourcesException) { + } catch (_: FailedToGetResourcesException) { apUserService.fetchPerson(signature.keyId) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/ExposedOAuth2AuthorizationService.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/ExposedOAuth2AuthorizationService.kt index 458f805c..b18d5ca0 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/ExposedOAuth2AuthorizationService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/ExposedOAuth2AuthorizationService.kt @@ -272,7 +272,9 @@ class ExposedOAuth2AuthorizationService( oidcIdTokenValue, oidcTokenIssuedAt, oidcTokenExpiresAt, - oidcTokenMetadata.getValue(OAuth2Authorization.Token.CLAIMS_METADATA_NAME) as MutableMap? + @Suppress("CastToNullableType") + oidcTokenMetadata.getValue(OAuth2Authorization.Token.CLAIMS_METADATA_NAME) + as MutableMap? ) builder.token(oidcIdToken) { it.putAll(oidcTokenMetadata) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/movie/MovieMediaProcessService.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/movie/MovieMediaProcessService.kt index 9b39e854..711cf29b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/movie/MovieMediaProcessService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/media/converter/movie/MovieMediaProcessService.kt @@ -34,6 +34,7 @@ class MovieMediaProcessService : MediaProcessService { TODO("Not yet implemented") } + @Suppress("LongMethod", "NestedBlockDepth", "CognitiveComplexMethod") override suspend fun process( mimeType: MimeType, fileName: String,