From f98178b37cf8de611d0c472c95630e0f3db528f9 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sun, 17 Dec 2023 19:08:18 +0900 Subject: [PATCH 01/12] =?UTF-8?q?refactor:=20actor=E3=81=AEDB=E3=81=8B?= =?UTF-8?q?=E3=82=89=E3=81=AE=E5=8F=96=E5=BE=97=E3=81=AB=E9=96=A2=E3=81=99?= =?UTF-8?q?=E3=82=8B=E5=A4=A7=E8=A6=8F=E6=A8=A1=E3=81=AA=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/mastodon/account/AccountApiTest.kt | 8 +- ...WithHttpSignatureSecurityContextFactory.kt | 8 +- .../accept/APDeliverAcceptJobProcessor.kt | 8 +- .../activity/accept/ApAcceptProcessor.kt | 11 +-- .../block/BlockActivityPubProcessor.kt | 12 ++- .../create/ApSendCreateServiceImpl.kt | 9 ++- .../activity/delete/APDeleteProcessor.kt | 15 ++-- .../delete/APDeliverDeleteJobProcessor.kt | 8 +- .../activity/delete/APSendDeleteService.kt | 10 ++- .../follow/APReceiveFollowJobProcessor.kt | 12 +-- .../activity/like/APReactionService.kt | 9 ++- .../activity/like/ApReactionJobProcessor.kt | 8 +- .../like/ApRemoveReactionJobProcessor.kt | 8 +- .../reject/APDeliverRejectJobProcessor.kt | 8 +- .../activity/reject/ApRejectProcessor.kt | 13 ++-- .../undo/APDeliverUndoJobProcessor.kt | 8 +- .../service/activity/undo/APUndoProcessor.kt | 24 +++--- .../service/inbox/InboxJobProcessor.kt | 17 ++--- .../objects/note/ApNoteJobProcessor.kt | 8 +- .../service/objects/user/APUserService.kt | 75 ++++++++++--------- .../service/webfinger/WebFingerApiService.kt | 13 +++- .../application/config/SecurityConfig.kt | 15 ++-- .../exposed/ExposedTransaction.kt | 3 +- .../core/domain/exception/HideoutException.kt | 21 ++++++ .../exception/resource/NotFoundException.kt | 16 ++++ .../resource/UserNotFoundException.kt | 37 +++++++++ .../local/LocalUserNotFoundException.kt | 33 ++++++++ .../domain/model/actor/ActorRepository.kt | 18 +++++ .../exposedquery/ActorQueryServiceImpl.kt | 60 --------------- .../exposedquery/FollowerQueryServiceImpl.kt | 8 +- .../exposedrepository/ActorRepositoryImpl.kt | 41 +++++++++- .../HttpSignatureUserDetailsService.kt | 13 +--- .../oauth2/UserDetailsServiceImpl.kt | 17 ++--- .../hideout/core/query/ActorQueryService.kt | 16 ---- .../relationship/RelationshipServiceImpl.kt | 32 ++++---- .../core/service/timeline/TimelineService.kt | 9 ++- .../core/service/user/UserAuthServiceImpl.kt | 8 +- .../core/service/user/UserServiceImpl.kt | 11 ++- .../service/status/StatusesApiService.kt | 13 +--- src/main/resources/application.yml | 18 ++--- src/main/resources/logback.xml | 15 ++++ .../accept/APDeliverAcceptJobProcessorTest.kt | 1 - .../activity/accept/ApAcceptProcessorTest.kt | 1 - .../create/ApSendCreateServiceImplTest.kt | 1 - .../objects/note/APNoteServiceImplTest.kt | 1 - .../RelationshipServiceImplTest.kt | 1 - .../service/timeline/TimelineServiceTest.kt | 1 - .../core/service/user/ActorServiceTest.kt | 2 - 48 files changed, 403 insertions(+), 301 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/domain/exception/HideoutException.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/NotFoundException.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/UserNotFoundException.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/local/LocalUserNotFoundException.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ActorQueryServiceImpl.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/query/ActorQueryService.kt diff --git a/src/intTest/kotlin/mastodon/account/AccountApiTest.kt b/src/intTest/kotlin/mastodon/account/AccountApiTest.kt index cf67b35d..f2f9ffc7 100644 --- a/src/intTest/kotlin/mastodon/account/AccountApiTest.kt +++ b/src/intTest/kotlin/mastodon/account/AccountApiTest.kt @@ -1,7 +1,7 @@ package mastodon.account import dev.usbharu.hideout.SpringApplication -import dev.usbharu.hideout.core.infrastructure.exposedquery.ActorQueryServiceImpl +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.infrastructure.exposedquery.FollowerQueryServiceImpl import kotlinx.coroutines.test.runTest import org.assertj.core.api.Assertions.assertThat @@ -39,7 +39,7 @@ class AccountApiTest { private lateinit var followerQueryServiceImpl: FollowerQueryServiceImpl @Autowired - private lateinit var userQueryServiceImpl: ActorQueryServiceImpl + private lateinit var actorRepository: ActorRepository @Autowired @@ -100,7 +100,7 @@ class AccountApiTest { .asyncDispatch() .andExpect { status { isFound() } } - userQueryServiceImpl.findByNameAndDomain("api-test-user-1", "example.com") + actorRepository.findByNameAndDomain("api-test-user-1", "example.com") } @Test @@ -116,7 +116,7 @@ class AccountApiTest { .asyncDispatch() .andExpect { status { isFound() } } - userQueryServiceImpl.findByNameAndDomain("api-test-user-2", "example.com") + actorRepository.findByNameAndDomain("api-test-user-2", "example.com") } @Test diff --git a/src/intTest/kotlin/util/WithHttpSignatureSecurityContextFactory.kt b/src/intTest/kotlin/util/WithHttpSignatureSecurityContextFactory.kt index faabf58a..fc9772f0 100644 --- a/src/intTest/kotlin/util/WithHttpSignatureSecurityContextFactory.kt +++ b/src/intTest/kotlin/util/WithHttpSignatureSecurityContextFactory.kt @@ -1,8 +1,9 @@ package util import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.infrastructure.springframework.httpsignature.HttpSignatureUser -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.httpsignature.common.HttpHeaders import dev.usbharu.httpsignature.common.HttpMethod import dev.usbharu.httpsignature.common.HttpRequest @@ -14,7 +15,7 @@ import org.springframework.security.web.authentication.preauth.PreAuthenticatedA import java.net.URL class WithHttpSignatureSecurityContextFactory( - private val actorQueryService: ActorQueryService, + private val actorRepository: ActorRepository, private val transaction: Transaction ) : WithSecurityContextFactory { @@ -28,7 +29,8 @@ class WithHttpSignatureSecurityContextFactory( ) ) val httpSignatureUser = transaction.transaction { - val findByKeyId = actorQueryService.findByKeyId(annotation.keyId) + val findByKeyId = + actorRepository.findByKeyId(annotation.keyId) ?: throw UserNotFoundException.withKeyId(annotation.keyId) HttpSignatureUser( findByKeyId.name, findByKeyId.domain, diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessor.kt index 3a48b5df..0936d8b7 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessor.kt @@ -2,22 +2,22 @@ package dev.usbharu.hideout.activitypub.service.activity.accept import dev.usbharu.hideout.activitypub.service.common.APRequestService import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.external.job.DeliverAcceptJob import dev.usbharu.hideout.core.external.job.DeliverAcceptJobParam -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.service.job.JobProcessor import org.springframework.stereotype.Service @Service class APDeliverAcceptJobProcessor( private val apRequestService: APRequestService, - private val actorQueryService: ActorQueryService, private val deliverAcceptJob: DeliverAcceptJob, - private val transaction: Transaction + private val transaction: Transaction, + private val actorRepository: ActorRepository ) : JobProcessor { override suspend fun process(param: DeliverAcceptJobParam): Unit = transaction.transaction { - apRequestService.apPost(param.inbox, param.accept, actorQueryService.findById(param.signer)) + apRequestService.apPost(param.inbox, param.accept, actorRepository.findById(param.signer)) } override fun job(): DeliverAcceptJob = deliverAcceptJob 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 index 1a48f22d..cae83622 100644 --- 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 @@ -7,15 +7,16 @@ import dev.usbharu.hideout.activitypub.service.common.AbstractActivityPubProcess 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.ActorQueryService +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.service.relationship.RelationshipService import org.springframework.stereotype.Service @Service class ApAcceptProcessor( transaction: Transaction, - private val actorQueryService: ActorQueryService, - private val relationshipService: RelationshipService + private val relationshipService: RelationshipService, + private val actorRepository: ActorRepository ) : AbstractActivityPubProcessor(transaction) { @@ -32,8 +33,8 @@ class ApAcceptProcessor( val userUrl = follow.apObject val followerUrl = follow.actor - val user = actorQueryService.findByUrl(userUrl) - val follower = actorQueryService.findByUrl(followerUrl) + val user = actorRepository.findByUrl(userUrl) ?: throw UserNotFoundException.withUrl(userUrl) + val follower = actorRepository.findByUrl(followerUrl) ?: throw UserNotFoundException.withUrl(followerUrl) relationshipService.acceptFollowRequest(user.id, follower.id) logger.debug("SUCCESS Follow from ${user.url} to ${follower.url}.") diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/block/BlockActivityPubProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/block/BlockActivityPubProcessor.kt index e31f4e6c..7262edd4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/block/BlockActivityPubProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/block/BlockActivityPubProcessor.kt @@ -5,7 +5,8 @@ import dev.usbharu.hideout.activitypub.service.common.AbstractActivityPubProcess 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.ActorQueryService +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.service.relationship.RelationshipService import org.springframework.stereotype.Service @@ -14,14 +15,17 @@ import org.springframework.stereotype.Service */ @Service class BlockActivityPubProcessor( - private val actorQueryService: ActorQueryService, private val relationshipService: RelationshipService, + private val actorRepository: ActorRepository, transaction: Transaction ) : AbstractActivityPubProcessor(transaction) { override suspend fun internalProcess(activity: ActivityPubProcessContext) { - val user = actorQueryService.findByUrl(activity.activity.actor) - val target = actorQueryService.findByUrl(activity.activity.apObject) + val user = actorRepository.findByUrl(activity.activity.actor) + ?: throw UserNotFoundException.withUrl(activity.activity.actor) + val target = actorRepository.findByUrl(activity.activity.apObject) ?: throw UserNotFoundException.withUrl( + activity.activity.apObject + ) relationshipService.block(user.id, target.id) } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImpl.kt index 0ba9413e..7f6ea823 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImpl.kt @@ -4,9 +4,10 @@ import com.fasterxml.jackson.databind.ObjectMapper import dev.usbharu.hideout.activitypub.domain.model.Create import dev.usbharu.hideout.activitypub.query.NoteQueryService import dev.usbharu.hideout.application.config.ApplicationConfig +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.external.job.DeliverPostJob -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.query.FollowerQueryService import dev.usbharu.hideout.core.service.job.JobQueueParentService import org.slf4j.LoggerFactory @@ -17,9 +18,9 @@ class ApSendCreateServiceImpl( private val followerQueryService: FollowerQueryService, private val objectMapper: ObjectMapper, private val jobQueueParentService: JobQueueParentService, - private val actorQueryService: ActorQueryService, private val noteQueryService: NoteQueryService, - private val applicationConfig: ApplicationConfig + private val applicationConfig: ApplicationConfig, + private val actorRepository: ActorRepository ) : ApSendCreateService { override suspend fun createNote(post: Post) { logger.info("CREATE Create Local Note ${post.url}") @@ -29,7 +30,7 @@ class ApSendCreateServiceImpl( logger.debug("DELIVER Deliver Note Create ${followers.size} accounts.") - val userEntity = actorQueryService.findById(post.actorId) + val userEntity = actorRepository.findById(post.actorId) ?: throw UserNotFoundException.withId(post.actorId) val note = noteQueryService.findById(post.id).first val create = Create( name = "Create Note", 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 index 508c3d45..f56f6018 100644 --- 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 @@ -9,7 +9,7 @@ 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.query.ActorQueryService +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.service.post.PostService import dev.usbharu.hideout.core.service.user.UserService @@ -19,9 +19,9 @@ import org.springframework.stereotype.Service class APDeleteProcessor( transaction: Transaction, private val postQueryService: PostQueryService, - private val actorQueryService: ActorQueryService, private val userService: UserService, - private val postService: PostService + private val postService: PostService, + private val actorRepository: ActorRepository ) : AbstractActivityPubProcessor(transaction) { override suspend fun internalProcess(activity: ActivityPubProcessContext) { @@ -34,12 +34,9 @@ class APDeleteProcessor( throw IllegalActivityPubObjectException("object hasn't id or object") } - try { - val actor = actorQueryService.findByUrl(deleteId) - userService.deleteRemoteActor(actor.id) - } catch (e: Exception) { - logger.warn("FAILED delete id: {} is not found.", deleteId, e) - } + val actor = actorRepository.findByUrl(deleteId) + actor?.let { userService.deleteRemoteActor(it.id) } + try { val post = postQueryService.findByApId(deleteId) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeliverDeleteJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeliverDeleteJobProcessor.kt index 5c72c304..9924594f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeliverDeleteJobProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeliverDeleteJobProcessor.kt @@ -2,21 +2,21 @@ package dev.usbharu.hideout.activitypub.service.activity.delete import dev.usbharu.hideout.activitypub.service.common.APRequestService import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.external.job.DeliverDeleteJob import dev.usbharu.hideout.core.external.job.DeliverDeleteJobParam -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.service.job.JobProcessor import org.springframework.stereotype.Service @Service class APDeliverDeleteJobProcessor( private val apRequestService: APRequestService, - private val actorQueryService: ActorQueryService, private val transaction: Transaction, - private val deliverDeleteJob: DeliverDeleteJob + private val deliverDeleteJob: DeliverDeleteJob, + private val actorRepository: ActorRepository ) : JobProcessor { override suspend fun process(param: DeliverDeleteJobParam): Unit = transaction.transaction { - apRequestService.apPost(param.inbox, param.delete, actorQueryService.findById(param.signer)) + apRequestService.apPost(param.inbox, param.delete, actorRepository.findById(param.signer)) } override fun job(): DeliverDeleteJob = deliverDeleteJob diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt index 2d1dde2a..626418d8 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt @@ -4,11 +4,12 @@ import dev.usbharu.hideout.activitypub.domain.model.Delete import dev.usbharu.hideout.activitypub.domain.model.Tombstone import dev.usbharu.hideout.activitypub.domain.model.objects.ObjectValue import dev.usbharu.hideout.application.config.ApplicationConfig +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import dev.usbharu.hideout.core.domain.model.actor.Actor +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.external.job.DeliverDeleteJob import dev.usbharu.hideout.core.external.job.DeliverDeleteJobParam -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.query.FollowerQueryService import dev.usbharu.hideout.core.service.job.JobQueueParentService import org.springframework.stereotype.Service @@ -24,11 +25,12 @@ class APSendDeleteServiceImpl( private val jobQueueParentService: JobQueueParentService, private val delverDeleteJob: DeliverDeleteJob, private val followerQueryService: FollowerQueryService, - private val actorQueryService: ActorQueryService, - private val applicationConfig: ApplicationConfig + private val applicationConfig: ApplicationConfig, + private val actorRepository: ActorRepository ) : APSendDeleteService { override suspend fun sendDeleteNote(deletedPost: Post) { - val actor = actorQueryService.findById(deletedPost.actorId) + val actor = + actorRepository.findById(deletedPost.actorId) ?: throw UserNotFoundException.withId(deletedPost.actorId) val followersById = followerQueryService.findFollowersById(deletedPost.actorId) val delete = Delete( 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 292f0ee2..50641d62 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 @@ -5,9 +5,10 @@ import com.fasterxml.jackson.module.kotlin.readValue import dev.usbharu.hideout.activitypub.domain.model.Follow import dev.usbharu.hideout.activitypub.service.objects.user.APUserService import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.external.job.ReceiveFollowJob import dev.usbharu.hideout.core.external.job.ReceiveFollowJobParam -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.service.job.JobProcessor import dev.usbharu.hideout.core.service.relationship.RelationshipService import org.slf4j.LoggerFactory @@ -16,10 +17,10 @@ import org.springframework.stereotype.Service @Service class APReceiveFollowJobProcessor( private val transaction: Transaction, - private val actorQueryService: ActorQueryService, private val apUserService: APUserService, private val objectMapper: ObjectMapper, - private val relationshipService: RelationshipService + private val relationshipService: RelationshipService, + private val actorRepository: ActorRepository ) : JobProcessor { override suspend fun process(param: ReceiveFollowJobParam) = transaction.transaction { @@ -28,9 +29,10 @@ class APReceiveFollowJobProcessor( logger.info("START Follow from: {} to {}", param.targetActor, param.actor) - val targetEntity = actorQueryService.findByUrl(param.targetActor) + val targetEntity = + actorRepository.findByUrl(param.targetActor) ?: throw UserNotFoundException.withUrl(param.targetActor) val followActorEntity = - actorQueryService.findByUrl(follow.actor) + actorRepository.findByUrl(follow.actor) ?: throw UserNotFoundException.withUrl(follow.actor) relationshipService.followRequest(followActorEntity.id, targetEntity.id) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt index 1995cf83..94f67a4f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt @@ -1,10 +1,11 @@ package dev.usbharu.hideout.activitypub.service.activity.like import com.fasterxml.jackson.databind.ObjectMapper +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.reaction.Reaction import dev.usbharu.hideout.core.external.job.DeliverReactionJob import dev.usbharu.hideout.core.external.job.DeliverRemoveReactionJob -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.query.FollowerQueryService import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.service.job.JobQueueParentService @@ -19,14 +20,14 @@ interface APReactionService { @Service class APReactionServiceImpl( private val jobQueueParentService: JobQueueParentService, - private val actorQueryService: ActorQueryService, private val followerQueryService: FollowerQueryService, private val postQueryService: PostQueryService, + private val actorRepository: ActorRepository, @Qualifier("activitypub") private val objectMapper: ObjectMapper ) : APReactionService { override suspend fun reaction(like: Reaction) { val followers = followerQueryService.findFollowersById(like.actorId) - val user = actorQueryService.findById(like.actorId) + val user = actorRepository.findById(like.actorId) ?: throw UserNotFoundException.withId(like.actorId) val post = postQueryService.findById(like.postId) followers.forEach { follower -> @@ -42,7 +43,7 @@ class APReactionServiceImpl( override suspend fun removeReaction(like: Reaction) { val followers = followerQueryService.findFollowersById(like.actorId) - val user = actorQueryService.findById(like.actorId) + val user = actorRepository.findById(like.actorId) ?: throw UserNotFoundException.withId(like.actorId) val post = postQueryService.findById(like.postId) followers.forEach { follower -> 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 index e7857e8e..ee4f8605 100644 --- 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 @@ -4,21 +4,21 @@ 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.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.external.job.DeliverReactionJob import dev.usbharu.hideout.core.external.job.DeliverReactionJobParam -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.service.job.JobProcessor import org.springframework.stereotype.Service @Service class ApReactionJobProcessor( - private val actorQueryService: ActorQueryService, private val apRequestService: APRequestService, private val applicationConfig: ApplicationConfig, - private val transaction: Transaction + private val transaction: Transaction, + private val actorRepository: ActorRepository ) : JobProcessor { override suspend fun process(param: DeliverReactionJobParam): Unit = transaction.transaction { - val signer = actorQueryService.findByUrl(param.actor) + val signer = actorRepository.findByUrl(param.actor) apRequestService.apPost( param.inbox, 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 5dd3e6e7..0d48c53a 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 @@ -7,25 +7,25 @@ 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.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.external.job.DeliverRemoveReactionJob import dev.usbharu.hideout.core.external.job.DeliverRemoveReactionJobParam -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.service.job.JobProcessor import org.springframework.stereotype.Service import java.time.Instant @Service class ApRemoveReactionJobProcessor( - private val actorQueryService: ActorQueryService, private val transaction: Transaction, private val objectMapper: ObjectMapper, private val apRequestService: APRequestService, - private val applicationConfig: ApplicationConfig + private val applicationConfig: ApplicationConfig, + private val actorRepository: ActorRepository ) : JobProcessor { override suspend fun process(param: DeliverRemoveReactionJobParam): Unit = transaction.transaction { val like = objectMapper.readValue(param.like) - val signer = actorQueryService.findByUrl(param.actor) + val signer = actorRepository.findByUrl(param.actor) apRequestService.apPost( param.inbox, diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/APDeliverRejectJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/APDeliverRejectJobProcessor.kt index 0ef702d5..a7706473 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/APDeliverRejectJobProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/APDeliverRejectJobProcessor.kt @@ -2,22 +2,22 @@ package dev.usbharu.hideout.activitypub.service.activity.reject import dev.usbharu.hideout.activitypub.service.common.APRequestService import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.external.job.DeliverRejectJob import dev.usbharu.hideout.core.external.job.DeliverRejectJobParam -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.service.job.JobProcessor import org.springframework.stereotype.Component @Component class APDeliverRejectJobProcessor( private val apRequestService: APRequestService, - private val actorQueryService: ActorQueryService, private val deliverRejectJob: DeliverRejectJob, - private val transaction: Transaction + private val transaction: Transaction, + private val actorRepository: ActorRepository ) : JobProcessor { override suspend fun process(param: DeliverRejectJobParam): Unit = transaction.transaction { - apRequestService.apPost(param.inbox, param.reject, actorQueryService.findById(param.signer)) + apRequestService.apPost(param.inbox, param.reject, actorRepository.findById(param.signer)) } override fun job(): DeliverRejectJob = deliverRejectJob diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApRejectProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApRejectProcessor.kt index 29bbd1f9..d1c53f0e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApRejectProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApRejectProcessor.kt @@ -6,15 +6,16 @@ import dev.usbharu.hideout.activitypub.service.common.AbstractActivityPubProcess 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.ActorQueryService +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.service.relationship.RelationshipService import org.springframework.stereotype.Service @Service class ApRejectProcessor( private val relationshipService: RelationshipService, - private val actorQueryService: ActorQueryService, - transaction: Transaction + transaction: Transaction, + private val actorRepository: ActorRepository ) : AbstractActivityPubProcessor(transaction) { override suspend fun internalProcess(activity: ActivityPubProcessContext) { @@ -26,13 +27,15 @@ class ApRejectProcessor( } when (activityType) { "Follow" -> { - val user = actorQueryService.findByUrl(activity.activity.actor) + val user = actorRepository.findByUrl(activity.activity.actor) ?: throw UserNotFoundException.withUrl( + activity.activity.actor + ) activity.activity.apObject as Follow val actor = activity.activity.apObject.actor - val target = actorQueryService.findByUrl(actor) + val target = actorRepository.findByUrl(actor) ?: throw UserNotFoundException.withUrl(actor) logger.debug("REJECT Follow user {} target {}", user.url, target.url) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APDeliverUndoJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APDeliverUndoJobProcessor.kt index 70e31921..ebc3257c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APDeliverUndoJobProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APDeliverUndoJobProcessor.kt @@ -2,9 +2,9 @@ package dev.usbharu.hideout.activitypub.service.activity.undo import dev.usbharu.hideout.activitypub.service.common.APRequestService import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.external.job.DeliverUndoJob import dev.usbharu.hideout.core.external.job.DeliverUndoJobParam -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.service.job.JobProcessor import org.springframework.stereotype.Service @@ -12,11 +12,11 @@ import org.springframework.stereotype.Service class APDeliverUndoJobProcessor( private val deliverUndoJob: DeliverUndoJob, private val apRequestService: APRequestService, - private val actorQueryService: ActorQueryService, - private val transaction: Transaction + private val transaction: Transaction, + private val actorRepository: ActorRepository ) : JobProcessor { override suspend fun process(param: DeliverUndoJobParam): Unit = transaction.transaction { - apRequestService.apPost(param.inbox, param.undo, actorQueryService.findById(param.signer)) + apRequestService.apPost(param.inbox, param.undo, actorRepository.findById(param.signer)) } override fun job(): DeliverUndoJob = deliverUndoJob 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 index 77388337..afd9a721 100644 --- 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 @@ -7,7 +7,9 @@ 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.ActorQueryService +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException +import dev.usbharu.hideout.core.domain.exception.resource.local.LocalUserNotFoundException +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.service.reaction.ReactionService import dev.usbharu.hideout.core.service.relationship.RelationshipService @@ -17,10 +19,10 @@ import org.springframework.stereotype.Service class APUndoProcessor( transaction: Transaction, private val apUserService: APUserService, - private val actorQueryService: ActorQueryService, private val relationshipService: RelationshipService, private val postQueryService: PostQueryService, - private val reactionService: ReactionService + private val reactionService: ReactionService, + private val actorRepository: ActorRepository ) : AbstractActivityPubProcessor(transaction) { override suspend fun internalProcess(activity: ActivityPubProcessContext) { @@ -35,9 +37,9 @@ class APUndoProcessor( "Follow" -> { val follow = undo.apObject as Follow - apUserService.fetchPerson(undo.actor, follow.apObject) - val follower = actorQueryService.findByUrl(undo.actor) - val target = actorQueryService.findByUrl(follow.apObject) + val follower = apUserService.fetchPersonWithEntity(undo.actor, follow.apObject).second + val target = + actorRepository.findByUrl(follow.apObject) ?: throw UserNotFoundException.withUrl(follow.apObject) relationshipService.unfollow(follower.id, target.id) return @@ -47,7 +49,8 @@ class APUndoProcessor( val block = undo.apObject as Block val blocker = apUserService.fetchPersonWithEntity(undo.actor, block.apObject).second - val target = actorQueryService.findByUrl(block.apObject) + val target = + actorRepository.findByUrl(block.apObject) ?: throw UserNotFoundException.withUrl(block.apObject) relationshipService.unblock(blocker.id, target.id) return @@ -66,7 +69,8 @@ class APUndoProcessor( } val accepter = apUserService.fetchPersonWithEntity(undo.actor, acceptObject).second - val target = actorQueryService.findByUrl(acceptObject) + val target = + actorRepository.findByUrl(acceptObject) ?: throw UserNotFoundException.withUrl(acceptObject) relationshipService.rejectFollowRequest(accepter.id, target.id) return @@ -77,7 +81,9 @@ class APUndoProcessor( val post = postQueryService.findByUrl(like.apObject) - val actor = actorQueryService.findByUrl(like.actor) + val signer = + actorRepository.findById(post.actorId) ?: throw LocalUserNotFoundException.withId(post.actorId) + val actor = apUserService.fetchPersonWithEntity(like.actor, signer.url).second reactionService.receiveRemoveReaction(actor.id, post.id) return 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 bfaf72f1..660f5958 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 @@ -7,10 +7,8 @@ import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessContext import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessor 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 -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.service.job.JobProcessor import dev.usbharu.hideout.util.RsaUtil import dev.usbharu.httpsignature.common.HttpHeaders @@ -29,7 +27,6 @@ class InboxJobProcessor( private val objectMapper: ObjectMapper, private val signatureHeaderParser: SignatureHeaderParser, private val signatureVerifier: HttpSignatureVerifier, - private val actorQueryService: ActorQueryService, private val apUserService: APUserService, private val transaction: Transaction ) : JobProcessor { @@ -37,7 +34,8 @@ class InboxJobProcessor( private suspend fun verifyHttpSignature( httpRequest: HttpRequest, signature: Signature, - transaction: Transaction + transaction: Transaction, + actor: String ): Boolean { val requiredHeaders = when (httpRequest.method) { HttpMethod.GET -> getRequiredHeaders @@ -49,11 +47,7 @@ class InboxJobProcessor( } val user = transaction.transaction { - try { - actorQueryService.findByKeyId(signature.keyId) - } catch (_: FailedToGetResourcesException) { - apUserService.fetchPersonWithEntity(signature.keyId).second - } + apUserService.fetchPersonWithEntity(actor).second } @Suppress("TooGenericExceptionCaught") @@ -97,7 +91,10 @@ class InboxJobProcessor( logger.debug("Has signature? {}", signature != null) - val verify = signature?.let { verifyHttpSignature(httpRequest, it, transaction) } ?: false + + //todo 不正なactorを取得してしまわないようにする + val verify = + signature?.let { verifyHttpSignature(httpRequest, it, transaction, jsonNode["actor"].textValue()) } ?: false logger.debug("Is verifying success? {}", verify) 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 index a9dbab74..921eaddf 100644 --- 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 @@ -5,9 +5,9 @@ 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.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.external.job.DeliverPostJob import dev.usbharu.hideout.core.external.job.DeliverPostJobParam -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.service.job.JobProcessor import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -16,13 +16,13 @@ import org.springframework.stereotype.Service class ApNoteJobProcessor( private val transaction: Transaction, private val objectMapper: ObjectMapper, - private val actorQueryService: ActorQueryService, - private val apRequestService: APRequestService + private val apRequestService: APRequestService, + private val actorRepository: ActorRepository ) : JobProcessor { override suspend fun process(param: DeliverPostJobParam) { val create = objectMapper.readValue(param.create) transaction.transaction { - val signer = actorQueryService.findByUrl(param.actor) + val signer = actorRepository.findByUrl(param.actor) logger.debug("CreateNoteJob: actor: {} create: {} inbox: {}", param.actor, create, param.inbox) 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 009c6821..886ecb42 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 @@ -1,6 +1,5 @@ package dev.usbharu.hideout.activitypub.service.objects.user -import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException import dev.usbharu.hideout.activitypub.domain.model.Image import dev.usbharu.hideout.activitypub.domain.model.Key import dev.usbharu.hideout.activitypub.domain.model.Person @@ -8,9 +7,9 @@ import dev.usbharu.hideout.activitypub.service.common.APResourceResolveService import dev.usbharu.hideout.activitypub.service.common.resolve import dev.usbharu.hideout.application.config.ApplicationConfig import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import dev.usbharu.hideout.core.domain.model.actor.Actor -import dev.usbharu.hideout.core.query.ActorQueryService +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.service.user.RemoteUserCreateDto import dev.usbharu.hideout.core.service.user.UserService import org.springframework.stereotype.Service @@ -34,16 +33,17 @@ interface APUserService { @Service class APUserServiceImpl( private val userService: UserService, - private val actorQueryService: ActorQueryService, private val transaction: Transaction, private val applicationConfig: ApplicationConfig, - private val apResourceResolveService: APResourceResolveService + private val apResourceResolveService: APResourceResolveService, + private val actorRepository: ActorRepository ) : APUserService { override suspend fun getPersonByName(name: String): Person { val userEntity = transaction.transaction { - actorQueryService.findByNameAndDomain(name, applicationConfig.url.host) + actorRepository.findByNameAndDomain(name, applicationConfig.url.host) + ?: throw UserNotFoundException.withNameAndDomain(name, applicationConfig.url.host) } // TODO: JOINで書き直し val userUrl = "${applicationConfig.url}/users/$name" @@ -78,38 +78,41 @@ class APUserServiceImpl( @Transactional override suspend fun fetchPersonWithEntity(url: String, targetActor: String?): Pair { - return try { - val userEntity = actorQueryService.findByUrl(url) - val id = userEntity.url - return entityToPerson(userEntity, id) to userEntity - } catch (ignore: FailedToGetResourcesException) { - val person = apResourceResolveService.resolve(url, null as Long?) + val userEntity = actorRepository.findByUrl(url) - val id = person.id - try { - val userEntity = actorQueryService.findByUrl(id) - return entityToPerson(userEntity, id) to userEntity - } catch (_: FailedToGetResourcesException) { - } - person to userService.createRemoteUser( - RemoteUserCreateDto( - name = person.preferredUsername - ?: throw IllegalActivityPubObjectException("preferredUsername is null"), - domain = id.substringAfter("://").substringBefore("/"), - screenName = person.name ?: person.preferredUsername, - description = person.summary.orEmpty(), - inbox = person.inbox, - outbox = person.outbox, - url = id, - publicKey = person.publicKey.publicKeyPem, - keyId = person.publicKey.id, - following = person.following, - followers = person.followers, - sharedInbox = person.endpoints["sharedInbox"], - locked = person.manuallyApprovesFollowers - ) - ) + if (userEntity != null) { + return entityToPerson(userEntity, userEntity.url) to userEntity } + + + val person = apResourceResolveService.resolve(url, null as Long?) + + val id = person.id + + val actor = actorRepository.findByUrlWithLock(id) + + if (actor != null) { + return person to actor + } + + return person to userService.createRemoteUser( + RemoteUserCreateDto( + name = person.preferredUsername, + domain = id.substringAfter("://").substringBefore("/"), + screenName = person.name ?: person.preferredUsername, + description = person.summary.orEmpty(), + inbox = person.inbox, + outbox = person.outbox, + url = id, + publicKey = person.publicKey.publicKeyPem, + keyId = person.publicKey.id, + following = person.following, + followers = person.followers, + sharedInbox = person.endpoints["sharedInbox"], + locked = person.manuallyApprovesFollowers + ) + ) + } private fun entityToPerson( diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/webfinger/WebFingerApiService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/webfinger/WebFingerApiService.kt index 1cdd8230..25b774a0 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/webfinger/WebFingerApiService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/webfinger/WebFingerApiService.kt @@ -1,8 +1,9 @@ package dev.usbharu.hideout.activitypub.service.webfinger import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import dev.usbharu.hideout.core.domain.model.actor.Actor -import dev.usbharu.hideout.core.query.ActorQueryService +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import org.springframework.stereotype.Service @Service @@ -11,11 +12,17 @@ interface WebFingerApiService { } @Service -class WebFingerApiServiceImpl(private val transaction: Transaction, private val actorQueryService: ActorQueryService) : +class WebFingerApiServiceImpl( + private val transaction: Transaction, + private val actorRepository: ActorRepository +) : WebFingerApiService { override suspend fun findByNameAndDomain(name: String, domain: String): Actor { return transaction.transaction { - actorQueryService.findByNameAndDomain(name, domain) + actorRepository.findByNameAndDomain(name, domain) ?: throw UserNotFoundException.withNameAndDomain( + name, + domain + ) } } } diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt b/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt index 144379c9..966be809 100644 --- a/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt @@ -7,19 +7,18 @@ import com.nimbusds.jose.jwk.source.ImmutableJWKSet import com.nimbusds.jose.jwk.source.JWKSource import com.nimbusds.jose.proc.SecurityContext import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.infrastructure.springframework.httpsignature.HttpSignatureFilter import dev.usbharu.hideout.core.infrastructure.springframework.httpsignature.HttpSignatureUserDetailsService import dev.usbharu.hideout.core.infrastructure.springframework.httpsignature.HttpSignatureVerifierComposite import dev.usbharu.hideout.core.infrastructure.springframework.oauth2.UserDetailsImpl import dev.usbharu.hideout.core.infrastructure.springframework.oauth2.UserDetailsServiceImpl -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.util.RsaUtil import dev.usbharu.hideout.util.hasAnyScope import dev.usbharu.httpsignature.sign.RsaSha256HttpSignatureSigner import dev.usbharu.httpsignature.verify.DefaultSignatureHeaderParser import dev.usbharu.httpsignature.verify.RsaSha256HttpSignatureVerifier import jakarta.annotation.PostConstruct -import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer import org.springframework.boot.context.properties.ConfigurationProperties @@ -68,9 +67,6 @@ import java.util.* @Suppress("FunctionMaxLength", "TooManyFunctions") class SecurityConfig { - @Autowired - private lateinit var actorQueryService: ActorQueryService - @Bean fun authenticationManager(authenticationConfiguration: AuthenticationConfiguration): AuthenticationManager? = authenticationConfiguration.authenticationManager @@ -130,12 +126,14 @@ class SecurityConfig { @Bean @Order(1) - fun httpSignatureAuthenticationProvider(transaction: Transaction): PreAuthenticatedAuthenticationProvider { + fun httpSignatureAuthenticationProvider( + transaction: Transaction, + actorRepository: ActorRepository + ): PreAuthenticatedAuthenticationProvider { val provider = PreAuthenticatedAuthenticationProvider() val signatureHeaderParser = DefaultSignatureHeaderParser() provider.setPreAuthenticatedUserDetailsService( HttpSignatureUserDetailsService( - actorQueryService, HttpSignatureVerifierComposite( mapOf( "rsa-sha256" to RsaSha256HttpSignatureVerifier( @@ -145,7 +143,8 @@ class SecurityConfig { signatureHeaderParser ), transaction, - signatureHeaderParser + signatureHeaderParser, + actorRepository ) ) provider.setUserDetailsChecker(AccountStatusUserDetailsChecker()) diff --git a/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedTransaction.kt b/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedTransaction.kt index 74be00ff..097c551a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedTransaction.kt +++ b/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedTransaction.kt @@ -6,12 +6,11 @@ import org.jetbrains.exposed.sql.StdOutSqlLogger import org.jetbrains.exposed.sql.addLogger import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction import org.springframework.stereotype.Service -import java.sql.Connection @Service class ExposedTransaction : Transaction { override suspend fun transaction(block: suspend () -> T): T { - return newSuspendedTransaction(MDCContext(), transactionIsolation = Connection.TRANSACTION_SERIALIZABLE) { + return newSuspendedTransaction(MDCContext()) { addLogger(StdOutSqlLogger) block() } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/HideoutException.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/HideoutException.kt new file mode 100644 index 00000000..0307e24d --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/HideoutException.kt @@ -0,0 +1,21 @@ +package dev.usbharu.hideout.core.domain.exception + +import java.io.Serial + +open class HideoutException : 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 = 8506638570017469956L + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/NotFoundException.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/NotFoundException.kt new file mode 100644 index 00000000..1a1e0d0d --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/NotFoundException.kt @@ -0,0 +1,16 @@ +package dev.usbharu.hideout.core.domain.exception.resource + +import dev.usbharu.hideout.core.domain.exception.HideoutException + +open class NotFoundException : HideoutException { + 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/core/domain/exception/resource/UserNotFoundException.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/UserNotFoundException.kt new file mode 100644 index 00000000..0560be92 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/UserNotFoundException.kt @@ -0,0 +1,37 @@ +package dev.usbharu.hideout.core.domain.exception.resource + +import java.io.Serial + +open class UserNotFoundException : NotFoundException { + 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 = 3219433672235626200L + + + fun withName(string: String, throwable: Throwable? = null): UserNotFoundException = + UserNotFoundException("name: $string was not found.", throwable) + + fun withId(id: Long, throwable: Throwable? = null): UserNotFoundException = + UserNotFoundException("id: $id was not found.", throwable) + + fun withUrl(url: String, throwable: Throwable? = null): UserNotFoundException = + UserNotFoundException("url: $url was not found.", throwable) + + fun withNameAndDomain(name: String, domain: String, throwable: Throwable? = null): UserNotFoundException = + UserNotFoundException("name: $name domain: $domain (@$name@$domain) was not found.", throwable) + + fun withKeyId(keyId: String, throwable: Throwable? = null) = + UserNotFoundException("keyId: $keyId was not found.", throwable) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/local/LocalUserNotFoundException.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/local/LocalUserNotFoundException.kt new file mode 100644 index 00000000..b2cdb0ae --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/local/LocalUserNotFoundException.kt @@ -0,0 +1,33 @@ +package dev.usbharu.hideout.core.domain.exception.resource.local + +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException +import java.io.Serial + +class LocalUserNotFoundException : UserNotFoundException { + 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 = -4742548128672528145L + + fun withName(string: String, throwable: Throwable? = null): LocalUserNotFoundException = + LocalUserNotFoundException("name: $string was not found.", throwable) + + fun withId(id: Long, throwable: Throwable? = null): LocalUserNotFoundException = + LocalUserNotFoundException("id: $id was not found.", throwable) + + fun withUrl(url: String, throwable: Throwable? = null): LocalUserNotFoundException = + LocalUserNotFoundException("url: $url was not found.", throwable) + } + +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorRepository.kt index 39887a5e..ae39290a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorRepository.kt @@ -8,6 +8,24 @@ interface ActorRepository { suspend fun findById(id: Long): Actor? + suspend fun findByIdWithLock(id: Long): Actor? + + suspend fun findAll(limit: Int, offset: Long): List + + suspend fun findByName(name: String): List + + suspend fun findByNameAndDomain(name: String, domain: String): Actor? + + suspend fun findByNameAndDomainWithLock(name: String, domain: String): Actor? + + suspend fun findByUrl(url: String): Actor? + + suspend fun findByUrlWithLock(url: String): Actor? + + suspend fun findByIds(ids: List): List + + suspend fun findByKeyId(keyId: String): Actor? + suspend fun delete(id: Long) suspend fun nextId(): Long diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ActorQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ActorQueryServiceImpl.kt deleted file mode 100644 index 6dab78c2..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ActorQueryServiceImpl.kt +++ /dev/null @@ -1,60 +0,0 @@ -package dev.usbharu.hideout.core.infrastructure.exposedquery - -import dev.usbharu.hideout.application.infrastructure.exposed.QueryMapper -import dev.usbharu.hideout.application.infrastructure.exposed.ResultRowMapper -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException -import dev.usbharu.hideout.core.domain.model.actor.Actor -import dev.usbharu.hideout.core.infrastructure.exposedrepository.Actors -import dev.usbharu.hideout.core.query.ActorQueryService -import dev.usbharu.hideout.util.singleOr -import org.jetbrains.exposed.sql.and -import org.jetbrains.exposed.sql.select -import org.jetbrains.exposed.sql.selectAll -import org.slf4j.LoggerFactory -import org.springframework.stereotype.Repository - -@Repository -class ActorQueryServiceImpl( - private val actorResultRowMapper: ResultRowMapper, - private val actorQueryMapper: QueryMapper -) : ActorQueryService { - - private val logger = LoggerFactory.getLogger(ActorQueryServiceImpl::class.java) - - override suspend fun findAll(limit: Int, offset: Long): List = - Actors.selectAll().limit(limit, offset).let(actorQueryMapper::map) - - override suspend fun findById(id: Long): Actor = Actors.select { Actors.id eq id } - .singleOr { FailedToGetResourcesException("id: $id is duplicate or does not exist.", it) } - .let(actorResultRowMapper::map) - - override suspend fun findByName(name: String): List = - Actors.select { Actors.name eq name }.let(actorQueryMapper::map) - - override suspend fun findByNameAndDomain(name: String, domain: String): Actor = - Actors - .select { Actors.name eq name and (Actors.domain eq domain) } - .singleOr { - FailedToGetResourcesException("name: $name,domain: $domain is duplicate or does not exist.", it) - } - .let(actorResultRowMapper::map) - - override suspend fun findByUrl(url: String): Actor { - logger.trace("findByUrl url: $url") - return Actors.select { Actors.url eq url } - .singleOr { FailedToGetResourcesException("url: $url is duplicate or does not exist.", it) } - .let(actorResultRowMapper::map) - } - - override suspend fun findByIds(ids: List): List = - Actors.select { Actors.id inList ids }.let(actorQueryMapper::map) - - override suspend fun existByNameAndDomain(name: String, domain: String): Boolean = - Actors.select { Actors.name eq name and (Actors.domain eq domain) }.empty().not() - - override suspend fun findByKeyId(keyId: String): Actor { - return Actors.select { Actors.keyId eq keyId } - .singleOr { FailedToGetResourcesException("keyId: $keyId is duplicate or does not exist.", it) } - .let(actorResultRowMapper::map) - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/FollowerQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/FollowerQueryServiceImpl.kt index f7161b2e..9c841f15 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/FollowerQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/FollowerQueryServiceImpl.kt @@ -1,8 +1,8 @@ package dev.usbharu.hideout.core.infrastructure.exposedquery import dev.usbharu.hideout.core.domain.model.actor.Actor +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.query.FollowerQueryService import dev.usbharu.hideout.core.query.RelationshipQueryService import org.springframework.stereotype.Repository @@ -10,11 +10,11 @@ import org.springframework.stereotype.Repository @Repository class FollowerQueryServiceImpl( private val relationshipQueryService: RelationshipQueryService, - private val actorQueryService: ActorQueryService, - private val relationshipRepository: RelationshipRepository + private val relationshipRepository: RelationshipRepository, + private val actorRepository: ActorRepository ) : FollowerQueryService { override suspend fun findFollowersById(id: Long): List { - return actorQueryService.findByIds( + return actorRepository.findByIds( relationshipQueryService.findByTargetIdAndFollowing(id, true).map { it.actorId } ) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ActorRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ActorRepositoryImpl.kt index 96ce6409..fa0f395d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ActorRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ActorRepositoryImpl.kt @@ -1,5 +1,6 @@ package dev.usbharu.hideout.core.infrastructure.exposedrepository +import dev.usbharu.hideout.application.infrastructure.exposed.QueryMapper import dev.usbharu.hideout.application.infrastructure.exposed.ResultRowMapper import dev.usbharu.hideout.application.service.id.IdGenerateService import dev.usbharu.hideout.core.domain.model.actor.Actor @@ -12,12 +13,13 @@ import org.springframework.stereotype.Repository @Repository class ActorRepositoryImpl( private val idGenerateService: IdGenerateService, - private val actorResultRowMapper: ResultRowMapper + private val actorResultRowMapper: ResultRowMapper, + private val actorQueryMapper: QueryMapper ) : ActorRepository { override suspend fun save(actor: Actor): Actor { - val singleOrNull = Actors.select { Actors.id eq actor.id }.empty() + val singleOrNull = Actors.select { Actors.id eq actor.id }.forUpdate().empty() if (singleOrNull) { Actors.insert { it[id] = actor.id @@ -70,6 +72,41 @@ class ActorRepositoryImpl( override suspend fun findById(id: Long): Actor? = Actors.select { Actors.id eq id }.singleOrNull()?.let(actorResultRowMapper::map) + override suspend fun findByIdWithLock(id: Long): Actor? = + Actors.select { Actors.id eq id }.forUpdate().singleOrNull()?.let(actorResultRowMapper::map) + + override suspend fun findAll(limit: Int, offset: Long): List = + Actors.selectAll().limit(limit, offset).let(actorQueryMapper::map) + + override suspend fun findByName(name: String): List = + Actors.select { Actors.name eq name }.let(actorQueryMapper::map) + + override suspend fun findByNameAndDomain(name: String, domain: String): Actor? = Actors + .select { Actors.name eq name and (Actors.domain eq domain) } + .singleOrNull() + ?.let(actorResultRowMapper::map) + + override suspend fun findByNameAndDomainWithLock(name: String, domain: String): Actor? = Actors + .select { Actors.name eq name and (Actors.domain eq domain) } + .forUpdate() + .singleOrNull() + ?.let(actorResultRowMapper::map) + + override suspend fun findByUrl(url: String): Actor? = Actors.select { Actors.url eq url } + .singleOrNull() + ?.let(actorResultRowMapper::map) + + override suspend fun findByUrlWithLock(url: String): Actor? = Actors.select { Actors.url eq url }.forUpdate() + .singleOrNull() + ?.let(actorResultRowMapper::map) + + override suspend fun findByIds(ids: List): List = + Actors.select { Actors.id inList ids }.let(actorQueryMapper::map) + + override suspend fun findByKeyId(keyId: String): Actor? = Actors.select { Actors.keyId eq keyId } + .singleOrNull() + ?.let(actorResultRowMapper::map) + override suspend fun delete(id: Long) { Actors.deleteWhere { Actors.id.eq(id) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureUserDetailsService.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureUserDetailsService.kt index 8c891da3..17552026 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureUserDetailsService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureUserDetailsService.kt @@ -1,9 +1,8 @@ package dev.usbharu.hideout.core.infrastructure.springframework.httpsignature import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.exception.HttpSignatureVerifyException -import dev.usbharu.hideout.core.query.ActorQueryService +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.util.RsaUtil import dev.usbharu.httpsignature.common.HttpMethod import dev.usbharu.httpsignature.common.HttpRequest @@ -20,10 +19,10 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken class HttpSignatureUserDetailsService( - private val actorQueryService: ActorQueryService, private val httpSignatureVerifier: HttpSignatureVerifier, private val transaction: Transaction, - private val httpSignatureHeaderParser: SignatureHeaderParser + private val httpSignatureHeaderParser: SignatureHeaderParser, + private val actorRepository: ActorRepository ) : AuthenticationUserDetailsService { override fun loadUserDetails(token: PreAuthenticatedAuthenticationToken): UserDetails = runBlocking { @@ -34,11 +33,7 @@ class HttpSignatureUserDetailsService( val keyId = token.principal as String val findByKeyId = transaction.transaction { - try { - actorQueryService.findByKeyId(keyId) - } catch (e: FailedToGetResourcesException) { - throw UsernameNotFoundException("User not found", e) - } + actorRepository.findByKeyId(keyId) ?: throw UsernameNotFoundException("keyId: $keyId not found.") } val signature = httpSignatureHeaderParser.parse(credentials.headers) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/UserDetailsServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/UserDetailsServiceImpl.kt index 2e979cea..6da7e79a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/UserDetailsServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/UserDetailsServiceImpl.kt @@ -2,9 +2,9 @@ package dev.usbharu.hideout.core.infrastructure.springframework.oauth2 import dev.usbharu.hideout.application.config.ApplicationConfig import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository -import dev.usbharu.hideout.core.query.ActorQueryService import kotlinx.coroutines.runBlocking import org.springframework.security.core.userdetails.UserDetails import org.springframework.security.core.userdetails.UserDetailsService @@ -13,10 +13,10 @@ import org.springframework.stereotype.Service @Service class UserDetailsServiceImpl( - private val actorQueryService: ActorQueryService, private val applicationConfig: ApplicationConfig, private val userDetailRepository: UserDetailRepository, - private val transaction: Transaction + private val transaction: Transaction, + private val actorRepository: ActorRepository ) : UserDetailsService { override fun loadUserByUsername(username: String?): UserDetails = runBlocking { @@ -24,11 +24,10 @@ class UserDetailsServiceImpl( throw UsernameNotFoundException("$username not found") } transaction.transaction { - val findById = try { - actorQueryService.findByNameAndDomain(username, applicationConfig.url.host) - } catch (e: FailedToGetResourcesException) { - throw UsernameNotFoundException("$username not found", e) - } + val findById = + actorRepository.findByNameAndDomain(username, applicationConfig.url.host) + ?: throw UserNotFoundException.withNameAndDomain(username, applicationConfig.url.host) + val userDetails = userDetailRepository.findByActorId(findById.id) ?: throw UsernameNotFoundException("${findById.id} not found.") UserDetailsImpl( diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/ActorQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/ActorQueryService.kt deleted file mode 100644 index 05b79e25..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/query/ActorQueryService.kt +++ /dev/null @@ -1,16 +0,0 @@ -package dev.usbharu.hideout.core.query - -import dev.usbharu.hideout.core.domain.model.actor.Actor -import org.springframework.stereotype.Repository - -@Repository -interface ActorQueryService { - suspend fun findAll(limit: Int, offset: Long): List - suspend fun findById(id: Long): Actor - suspend fun findByName(name: String): List - suspend fun findByNameAndDomain(name: String, domain: String): Actor - suspend fun findByUrl(url: String): Actor - suspend fun findByIds(ids: List): List - suspend fun existByNameAndDomain(name: String, domain: String): Boolean - suspend fun findByKeyId(keyId: String): Actor -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImpl.kt index 69082c3e..cd83150e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImpl.kt @@ -6,12 +6,11 @@ import dev.usbharu.hideout.activitypub.service.activity.follow.APSendFollowServi import dev.usbharu.hideout.activitypub.service.activity.reject.ApSendRejectService import dev.usbharu.hideout.activitypub.service.activity.undo.APSendUndoService import dev.usbharu.hideout.application.config.ApplicationConfig -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.relationship.Relationship import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.service.follow.SendFollowDto import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -19,7 +18,6 @@ import org.springframework.stereotype.Service @Service class RelationshipServiceImpl( private val applicationConfig: ApplicationConfig, - private val actorQueryService: ActorQueryService, private val relationshipRepository: RelationshipRepository, private val apSendFollowService: APSendFollowService, private val apSendBlockService: APSendBlockService, @@ -78,10 +76,10 @@ class RelationshipServiceImpl( val remoteUser = isRemoteUser(targetId) if (remoteUser != null) { - val user = actorQueryService.findById(actorId) + val user = actorRepository.findById(actorId) ?: throw UserNotFoundException.withId(actorId) apSendFollowService.sendFollow(SendFollowDto(user, remoteUser)) } else { - val target = actorQueryService.findById(targetId) + val target = actorRepository.findById(targetId) ?: throw UserNotFoundException.withId(targetId) if (target.locked.not()) { acceptFollowRequest(targetId, actorId) } @@ -93,8 +91,8 @@ class RelationshipServiceImpl( override suspend fun block(actorId: Long, targetId: Long) { val relationship = relationshipRepository.findByUserIdAndTargetUserId(actorId, targetId) - val user = actorQueryService.findById(actorId) - val targetActor = actorQueryService.findById(targetId) + val user = actorRepository.findById(actorId) ?: throw UserNotFoundException.withId(actorId) + val targetActor = actorRepository.findById(targetId) ?: throw UserNotFoundException.withId(targetId) if (relationship?.following == true) { actorRepository.save(user.decrementFollowing()) actorRepository.save(targetActor.decrementFollowers()) @@ -174,13 +172,13 @@ class RelationshipServiceImpl( val copy = relationship.copy(followRequest = false, following = true, blocking = false) - val user = actorQueryService.findById(actorId) + val user = actorRepository.findById(actorId) ?: throw UserNotFoundException.withId(actorId) actorRepository.save(user.incrementFollowers()) relationshipRepository.save(copy) - val remoteActor = actorQueryService.findById(targetId) + val remoteActor = actorRepository.findById(targetId) ?: throw UserNotFoundException.withId(targetId) actorRepository.save(remoteActor.incrementFollowing()) @@ -209,7 +207,7 @@ class RelationshipServiceImpl( val remoteUser = isRemoteUser(targetId) if (remoteUser != null) { - val user = actorQueryService.findById(actorId) + val user = actorRepository.findById(actorId) ?: throw UserNotFoundException.withId(actorId) apSendRejectService.sendRejectFollow(user, remoteUser) } } @@ -238,8 +236,8 @@ class RelationshipServiceImpl( return } - val user = actorQueryService.findById(actorId) - val targetActor = actorQueryService.findById(targetId) + val user = actorRepository.findById(actorId) ?: throw UserNotFoundException.withId(actorId) + val targetActor = actorRepository.findById(targetId) ?: throw UserNotFoundException.withId(targetId) if (relationship.following) { actorRepository.save(user.decrementFollowing()) @@ -280,7 +278,7 @@ class RelationshipServiceImpl( val remoteUser = isRemoteUser(targetId) if (remoteUser != null) { - val user = actorQueryService.findById(actorId) + val user = actorRepository.findById(actorId) ?: throw UserNotFoundException.withId(actorId) apSendUndoService.sendUndoBlock(user, remoteUser) } } @@ -315,12 +313,8 @@ class RelationshipServiceImpl( private suspend fun isRemoteUser(userId: Long): Actor? { logger.trace("isRemoteUser({})", userId) - val user = try { - actorQueryService.findById(userId) - } catch (e: FailedToGetResourcesException) { - logger.warn("User not found.", e) - throw IllegalStateException("User not found.", e) - } + val user = + actorRepository.findById(userId) ?: throw UserNotFoundException.withId(userId) logger.trace("user info {}", user) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineService.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineService.kt index e53e327d..a6d8b185 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineService.kt @@ -1,10 +1,11 @@ package dev.usbharu.hideout.core.service.timeline +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.Visibility import dev.usbharu.hideout.core.domain.model.timeline.Timeline import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.query.FollowerQueryService import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -12,14 +13,14 @@ import org.springframework.stereotype.Service @Service class TimelineService( private val followerQueryService: FollowerQueryService, - private val actorQueryService: ActorQueryService, - private val timelineRepository: TimelineRepository + private val timelineRepository: TimelineRepository, + private val actorRepository: ActorRepository ) { suspend fun publishTimeline(post: Post, isLocal: Boolean) { val findFollowersById = followerQueryService.findFollowersById(post.actorId).toMutableList() if (isLocal) { // 自分自身も含める必要がある - val user = actorQueryService.findById(post.actorId) + val user = actorRepository.findById(post.actorId) ?: throw UserNotFoundException.withId(post.actorId) findFollowersById.add(user) } val timelines = findFollowersById.map { diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserAuthServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserAuthServiceImpl.kt index 5ec5d4be..dd8f8669 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserAuthServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserAuthServiceImpl.kt @@ -1,6 +1,7 @@ package dev.usbharu.hideout.core.service.user -import dev.usbharu.hideout.core.query.ActorQueryService +import dev.usbharu.hideout.application.config.ApplicationConfig +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder import org.springframework.stereotype.Service import java.security.* @@ -8,13 +9,14 @@ import java.util.* @Service class UserAuthServiceImpl( - val actorQueryService: ActorQueryService + private val actorRepository: ActorRepository, + private val applicationConfig: ApplicationConfig ) : UserAuthService { override fun hash(password: String): String = BCryptPasswordEncoder().encode(password) override suspend fun usernameAlreadyUse(username: String): Boolean { - actorQueryService.findByName(username) + actorRepository.findByNameAndDomain(username, applicationConfig.url.host) ?: return false return true } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt index 36259740..d8b97c32 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt @@ -3,6 +3,7 @@ package dev.usbharu.hideout.core.service.user import dev.usbharu.hideout.activitypub.service.activity.delete.APSendDeleteService import dev.usbharu.hideout.application.config.ApplicationConfig import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.deletedActor.DeletedActor @@ -11,7 +12,6 @@ import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.query.DeletedActorQueryService import dev.usbharu.hideout.core.service.instance.InstanceService import dev.usbharu.hideout.core.service.post.PostService @@ -26,7 +26,6 @@ import java.time.Instant class UserServiceImpl( private val actorRepository: ActorRepository, private val userAuthService: UserAuthService, - private val actorQueryService: ActorQueryService, private val actorBuilder: Actor.UserBuilder, private val applicationConfig: ApplicationConfig, private val instanceService: InstanceService, @@ -42,7 +41,7 @@ class UserServiceImpl( UserService { override suspend fun usernameAlreadyUse(username: String): Boolean { - val findByNameAndDomain = actorQueryService.findByNameAndDomain(username, applicationConfig.url.host) + val findByNameAndDomain = actorRepository.findByNameAndDomain(username, applicationConfig.url.host) return findByNameAndDomain != null } @@ -116,7 +115,7 @@ class UserServiceImpl( save } catch (_: ExposedSQLException) { logger.warn("FAILED User already exists. name: {} url: {}", user.name, user.url) - actorQueryService.findByUrl(user.url) + actorRepository.findByUrl(user.url)!! } } @@ -142,7 +141,7 @@ class UserServiceImpl( } override suspend fun deleteRemoteActor(actorId: Long) { - val actor = actorQueryService.findById(actorId) + val actor = actorRepository.findByIdWithLock(actorId) ?: throw UserNotFoundException.withId(actorId) val deletedActor = DeletedActor( actor.id, actor.name, @@ -161,7 +160,7 @@ class UserServiceImpl( } override suspend fun deleteLocalUser(userId: Long) { - val actor = actorQueryService.findById(userId) + val actor = actorRepository.findByIdWithLock(userId) ?: throw UserNotFoundException.withId(userId) apSendDeleteService.sendDeleteActor(actor) val deletedActor = DeletedActor( actor.id, diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt index eac73698..53c4326b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt @@ -1,10 +1,9 @@ package dev.usbharu.hideout.mastodon.service.status import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.media.MediaRepository import dev.usbharu.hideout.core.domain.model.media.toMediaAttachments -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.service.post.PostCreateDto import dev.usbharu.hideout.core.service.post.PostService @@ -30,9 +29,9 @@ class StatsesApiServiceImpl( private val postService: PostService, private val accountService: AccountService, private val postQueryService: PostQueryService, - private val actorQueryService: ActorQueryService, private val mediaRepository: MediaRepository, - private val transaction: Transaction + private val transaction: Transaction, + private val actorRepository: ActorRepository ) : StatusesApiService { override suspend fun postStatus( @@ -54,11 +53,7 @@ class StatsesApiServiceImpl( val account = accountService.findById(userId) val replyUser = if (post.replyId != null) { - try { - actorQueryService.findById(postQueryService.findById(post.replyId).actorId).id - } catch (ignore: FailedToGetResourcesException) { - null - } + actorRepository.findById(postQueryService.findById(post.replyId).actorId)?.id } else { null } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index daff34db..2208876e 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,6 @@ hideout: url: "https://test-hideout.usbharu.dev" - use-mongodb: false + use-mongodb: true security: jwt: generate: true @@ -22,14 +22,14 @@ spring: url: "jdbc:postgresql:hideout2" username: "postgres" password: "" - # data: - # mongodb: - # auto-index-creation: true - # host: localhost - # port: 27017 - # database: hideout - # username: hideoutuser - # password: hideoutpass + data: + mongodb: + auto-index-creation: true + host: localhost + port: 27017 + database: hideout + # username: hideoutuser + # password: hideoutpass servlet: multipart: max-file-size: 40MB diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 26a50765..41b1f895 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -1,4 +1,18 @@ + + logFile.log + + UTF-8 + %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{x-request-id}] %logger{36} - %msg%n + + + + logFile.%d{yyyy-MM-dd_HH}.log + + + 30 + + %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{x-request-id}] [%X{x-job-id}] %logger{36} - @@ -8,6 +22,7 @@ + diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessorTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessorTest.kt index f26cd135..d89fbe6d 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessorTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessorTest.kt @@ -5,7 +5,6 @@ import dev.usbharu.hideout.activitypub.domain.model.Follow import dev.usbharu.hideout.activitypub.service.common.APRequestService import dev.usbharu.hideout.core.external.job.DeliverAcceptJob import dev.usbharu.hideout.core.external.job.DeliverAcceptJobParam -import dev.usbharu.hideout.core.query.ActorQueryService import kotlinx.coroutines.test.runTest import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessorTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessorTest.kt index 793a65b6..d9b8f24e 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessorTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessorTest.kt @@ -7,7 +7,6 @@ import dev.usbharu.hideout.activitypub.domain.model.Like import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessContext import dev.usbharu.hideout.activitypub.service.common.ActivityType import dev.usbharu.hideout.application.config.ActivityPubConfig -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.service.relationship.RelationshipService import dev.usbharu.httpsignature.common.HttpHeaders import dev.usbharu.httpsignature.common.HttpMethod diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImplTest.kt index c2f4f87e..0f5ec6f8 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImplTest.kt @@ -7,7 +7,6 @@ import dev.usbharu.hideout.activitypub.service.objects.note.APNoteServiceImpl import dev.usbharu.hideout.application.config.ActivityPubConfig import dev.usbharu.hideout.application.config.ApplicationConfig import dev.usbharu.hideout.core.external.job.DeliverPostJob -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.query.FollowerQueryService import dev.usbharu.hideout.core.service.job.JobQueueParentService import kotlinx.coroutines.test.runTest diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteServiceImplTest.kt index 0a709b38..59978164 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteServiceImplTest.kt @@ -16,7 +16,6 @@ import dev.usbharu.hideout.application.service.id.TwitterSnowflakeIdGenerateServ import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.PostRepository -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.service.post.PostService import io.ktor.client.* diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImplTest.kt index 4f6fa718..b21bd0a5 100644 --- a/src/test/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImplTest.kt @@ -9,7 +9,6 @@ import dev.usbharu.hideout.application.config.ApplicationConfig import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.relationship.Relationship import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.service.follow.SendFollowDto import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Test diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineServiceTest.kt b/src/test/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineServiceTest.kt index 29b195ae..22583888 100644 --- a/src/test/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineServiceTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineServiceTest.kt @@ -5,7 +5,6 @@ import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.post.Visibility import dev.usbharu.hideout.core.domain.model.timeline.Timeline import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository -import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.query.FollowerQueryService import kotlinx.coroutines.test.runTest import org.assertj.core.api.Assertions.assertThat diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt b/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt index d41e7e32..fa1f438d 100644 --- a/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt @@ -38,7 +38,6 @@ class ActorServiceTest { UserServiceImpl( actorRepository = actorRepository, userAuthService = userAuthService, - actorQueryService = mock(), actorBuilder = actorBuilder, applicationConfig = testApplicationConfig, instanceService = mock(), @@ -85,7 +84,6 @@ class ActorServiceTest { UserServiceImpl( actorRepository = actorRepository, userAuthService = mock(), - actorQueryService = mock(), actorBuilder = actorBuilder, applicationConfig = testApplicationConfig, instanceService = mock(), From aa2741d614b790b10fa7dcc671066e4f2177640d Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 19 Dec 2023 17:00:15 +0900 Subject: [PATCH 02/12] =?UTF-8?q?feat:=20=E9=87=8D=E8=A4=87=E6=8E=92?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + .../exposedquery/NoteQueryServiceImpl.kt | 2 +- .../service/activity/like/APLikeProcessor.kt | 2 +- .../activitypub/service/common/APService.kt | 1 - .../common/AbstractActivityPubProcessor.kt | 4 +- .../service/objects/note/APNoteService.kt | 29 +++--- .../service/objects/user/APUserService.kt | 7 +- .../exposed/ExposedTransaction.kt | 23 +++-- .../exception/SQLExceptionTranslator.kt | 7 ++ ...taAccessExceptionSQLExceptionTranslator.kt | 19 ++++ .../exception/resource/DuplicateException.kt | 21 +++++ .../exception/resource/NotFoundException.kt | 4 +- .../resource/PostNotFoundException.kt | 23 +++++ .../resource/ResourceAccessException.kt | 16 ++++ .../core/domain/model/post/PostRepository.kt | 11 ++- .../exposedquery/MediaQueryServiceImpl.kt | 2 +- .../exposedrepository/AbstractRepository.kt | 64 ++++++++++++++ .../exposedrepository/ActorRepositoryImpl.kt | 88 +++++++++++-------- .../exposedrepository/MediaRepositoryImpl.kt | 2 +- .../exposedrepository/PostRepositoryImpl.kt | 46 +++++++--- .../KJobMongoJobQueueWorkerService.kt | 22 ++++- .../MongoTimelineRepositoryWrapper.kt | 15 +++- .../core/service/post/PostServiceImpl.kt | 22 ++--- .../service/resource/InMemoryCacheManager.kt | 3 +- .../core/service/user/UserServiceImpl.kt | 7 +- src/main/resources/logback.xml | 2 +- 26 files changed, 334 insertions(+), 110 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/domain/exception/SQLExceptionTranslator.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/domain/exception/SpringDataAccessExceptionSQLExceptionTranslator.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/DuplicateException.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/PostNotFoundException.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/ResourceAccessException.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/AbstractRepository.kt diff --git a/.gitignore b/.gitignore index 84c07d25..6654d55e 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,5 @@ out/ /tomcat-e2e/ /e2eTest.log /files/ + +*.log diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt index 19b217d5..9685d383 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt @@ -49,7 +49,7 @@ class NoteQueryServiceImpl(private val postRepository: PostRepository, private v val replyId = this[Posts.replyId] val replyTo = if (replyId != null) { try { - postRepository.findById(replyId).url + postRepository.findById(replyId)?.url ?: throw FailedToGetResourcesException() } catch (e: FailedToGetResourcesException) { logger.warn("Failed to get replyId: $replyId", e) null 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 index 665c7c94..ffa775e4 100644 --- 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 @@ -30,7 +30,7 @@ class APLikeProcessor( val personWithEntity = apUserService.fetchPersonWithEntity(actor) try { - apNoteService.fetchNoteAsync(target).await() + apNoteService.fetchNote(target) } catch (e: FailedToGetActivityPubResourceException) { logger.debug("FAILED failed to get {}", target) logger.trace("", e) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt index 4f5c2902..fdf89ba8 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt @@ -229,7 +229,6 @@ class APServiceImpl( props[it.json] = json props[it.type] = type.name val writeValueAsString = objectMapper.writeValueAsString(httpRequest) - println(writeValueAsString) props[it.httpRequest] = writeValueAsString props[it.headers] = objectMapper.writeValueAsString(map) } 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 1bb106e3..e26e909d 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 @@ -18,7 +18,7 @@ abstract class AbstractActivityPubProcessor( if (activity.isAuthorized.not() && allowUnauthorized.not()) { throw HttpSignatureUnauthorizedException() } - logger.info("START ActivityPub process") + logger.info("START ActivityPub process. {}", this.type()) try { transaction.transaction { internalProcess(activity) @@ -27,7 +27,7 @@ abstract class AbstractActivityPubProcessor( logger.warn("FAILED ActivityPub process", e) throw FailedProcessException("Failed process", e) } - logger.info("SUCCESS ActivityPub process") + logger.info("SUCCESS ActivityPub process. {}", this.type()) } abstract suspend fun internalProcess(activity: ActivityPubProcessContext) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt index 32a542d4..48537741 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt @@ -15,28 +15,11 @@ import dev.usbharu.hideout.core.service.media.MediaService import dev.usbharu.hideout.core.service.media.RemoteMedia import dev.usbharu.hideout.core.service.post.PostService import io.ktor.client.plugins.* -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Deferred -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.slf4j.MDCContext -import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction import org.slf4j.LoggerFactory -import org.springframework.cache.annotation.Cacheable import org.springframework.stereotype.Service import java.time.Instant interface APNoteService { - - @Cacheable("fetchNote") - fun fetchNoteAsync(url: String, targetActor: String? = null): Deferred { - return CoroutineScope(Dispatchers.IO + MDCContext()).async { - newSuspendedTransaction(MDCContext()) { - fetchNote(url, targetActor) - } - } - } - suspend fun fetchNote(url: String, targetActor: String? = null): Note suspend fun fetchNote(note: Note, targetActor: String? = null): Note } @@ -77,7 +60,7 @@ class APNoteServiceImpl( ) throw FailedToGetActivityPubResourceException("Could not retrieve $url.", e) } - val savedNote = saveNote(note, targetActor, url) + val savedNote = saveIfMissing(note, targetActor, url) logger.debug("SUCCESS Fetch Note url: {}", url) return savedNote } @@ -89,11 +72,15 @@ class APNoteServiceImpl( ): Note { requireNotNull(note.id) { "id is null" } + + return try { noteQueryService.findByApid(note.id).first - } catch (_: FailedToGetResourcesException) { + } catch (e: FailedToGetResourcesException) { saveNote(note, targetActor, url) } + + } private suspend fun saveNote(note: Note, targetActor: String?, url: String): Note { @@ -102,6 +89,10 @@ class APNoteServiceImpl( targetActor ) + if (postRepository.existByApIdWithLock(note.id)) { + return note + } + logger.debug("VISIBILITY url: {} to: {} cc: {}", note.id, note.to, note.cc) val visibility = 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 886ecb42..f366ac2f 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 @@ -12,8 +12,8 @@ import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.service.user.RemoteUserCreateDto import dev.usbharu.hideout.core.service.user.UserService +import org.slf4j.LoggerFactory import org.springframework.stereotype.Service -import org.springframework.transaction.annotation.Transactional interface APUserService { suspend fun getPersonByName(name: String): Person @@ -76,7 +76,6 @@ class APUserServiceImpl( override suspend fun fetchPerson(url: String, targetActor: String?): Person = fetchPersonWithEntity(url, targetActor).first - @Transactional override suspend fun fetchPersonWithEntity(url: String, targetActor: String?): Pair { val userEntity = actorRepository.findByUrl(url) @@ -142,4 +141,8 @@ class APUserServiceImpl( following = actorEntity.following, manuallyApprovesFollowers = actorEntity.locked ) + + companion object { + private val logger = LoggerFactory.getLogger(APUserServiceImpl::class.java) + } } diff --git a/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedTransaction.kt b/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedTransaction.kt index 097c551a..05fe6305 100644 --- a/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedTransaction.kt +++ b/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedTransaction.kt @@ -1,24 +1,37 @@ package dev.usbharu.hideout.application.infrastructure.exposed import dev.usbharu.hideout.application.external.Transaction +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.slf4j.MDCContext -import org.jetbrains.exposed.sql.StdOutSqlLogger +import org.jetbrains.exposed.sql.Slf4jSqlDebugLogger import org.jetbrains.exposed.sql.addLogger import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction +import org.jetbrains.exposed.sql.transactions.transaction import org.springframework.stereotype.Service +import java.sql.Connection @Service class ExposedTransaction : Transaction { override suspend fun transaction(block: suspend () -> T): T { - return newSuspendedTransaction(MDCContext()) { - addLogger(StdOutSqlLogger) - block() +// return newSuspendedTransaction(MDCContext(), transactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED) { +// warnLongQueriesDuration = 1000 +// addLogger(Slf4jSqlDebugLogger) +// block() +// } + + return transaction(transactionIsolation = Connection.TRANSACTION_READ_COMMITTED) { + debug = true + warnLongQueriesDuration = 1000 + addLogger(Slf4jSqlDebugLogger) + runBlocking(MDCContext()) { + block() + } } } override suspend fun transaction(transactionLevel: Int, block: suspend () -> T): T { return newSuspendedTransaction(MDCContext(), transactionIsolation = transactionLevel) { - addLogger(StdOutSqlLogger) + addLogger(Slf4jSqlDebugLogger) block() } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/SQLExceptionTranslator.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/SQLExceptionTranslator.kt new file mode 100644 index 00000000..842c4ea8 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/SQLExceptionTranslator.kt @@ -0,0 +1,7 @@ +package dev.usbharu.hideout.core.domain.exception + +import dev.usbharu.hideout.core.domain.exception.resource.ResourceAccessException + +interface SQLExceptionTranslator { + fun translate(message: String, sql: String? = null, exception: Exception): ResourceAccessException +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/SpringDataAccessExceptionSQLExceptionTranslator.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/SpringDataAccessExceptionSQLExceptionTranslator.kt new file mode 100644 index 00000000..6917f583 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/SpringDataAccessExceptionSQLExceptionTranslator.kt @@ -0,0 +1,19 @@ +package dev.usbharu.hideout.core.domain.exception + +import dev.usbharu.hideout.core.domain.exception.resource.DuplicateException +import dev.usbharu.hideout.core.domain.exception.resource.ResourceAccessException +import org.springframework.dao.DataAccessException +import org.springframework.dao.DuplicateKeyException + +class SpringDataAccessExceptionSQLExceptionTranslator : SQLExceptionTranslator { + override fun translate(message: String, sql: String?, exception: Exception): ResourceAccessException { + if (exception !is DataAccessException) { + throw IllegalArgumentException("exception must be DataAccessException.") + } + + return when (exception) { + is DuplicateKeyException -> DuplicateException(message, exception.rootCause) + else -> ResourceAccessException(message, exception.rootCause) + } + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/DuplicateException.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/DuplicateException.kt new file mode 100644 index 00000000..adb26d2d --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/DuplicateException.kt @@ -0,0 +1,21 @@ +package dev.usbharu.hideout.core.domain.exception.resource + +import java.io.Serial + +class DuplicateException : ResourceAccessException { + 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 = 7092046653037974417L + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/NotFoundException.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/NotFoundException.kt index 1a1e0d0d..bc2e6938 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/NotFoundException.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/NotFoundException.kt @@ -1,8 +1,6 @@ package dev.usbharu.hideout.core.domain.exception.resource -import dev.usbharu.hideout.core.domain.exception.HideoutException - -open class NotFoundException : HideoutException { +open class NotFoundException : ResourceAccessException { constructor() : super() constructor(message: String?) : super(message) constructor(message: String?, cause: Throwable?) : super(message, cause) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/PostNotFoundException.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/PostNotFoundException.kt new file mode 100644 index 00000000..f66c41d8 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/PostNotFoundException.kt @@ -0,0 +1,23 @@ +package dev.usbharu.hideout.core.domain.exception.resource + +import java.io.Serial + +class PostNotFoundException : NotFoundException { + 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 = 1315818410686905717L + + fun withApId(apId: String): PostNotFoundException = PostNotFoundException("apId: $apId was not found.") + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/ResourceAccessException.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/ResourceAccessException.kt new file mode 100644 index 00000000..b61fd4f4 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/ResourceAccessException.kt @@ -0,0 +1,16 @@ +package dev.usbharu.hideout.core.domain.exception.resource + +import dev.usbharu.hideout.core.domain.exception.HideoutException + +open class ResourceAccessException : HideoutException { + 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/core/domain/model/post/PostRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/PostRepository.kt index f2feb6f0..60384aee 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/PostRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/PostRepository.kt @@ -6,7 +6,14 @@ import org.springframework.stereotype.Repository @Repository interface PostRepository { suspend fun generateId(): Long - suspend fun save(post: Post): Boolean + suspend fun save(post: Post): Post suspend fun delete(id: Long) - suspend fun findById(id: Long): Post + suspend fun findById(id: Long): Post? + suspend fun findByUrl(url: String): Post? + suspend fun findByUrl2(url: String): Post? { + throw Exception() + } + + suspend fun findByApId(apId: String): Post? + suspend fun existByApIdWithLock(apId: String): Boolean } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt index 7b5a5d8e..df87d4c9 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt @@ -24,7 +24,7 @@ class MediaQueryServiceImpl : MediaQueryService { } override suspend fun findByRemoteUrl(remoteUrl: String): MediaEntity { - return Media.select { Media.remoteUrl eq remoteUrl } + return Media.select { Media.remoteUrl eq remoteUrl }.forUpdate() .singleOr { FailedToGetResourcesException("remoteUrl: $remoteUrl is duplicate or not exist.", it) } .toMedia() } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/AbstractRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/AbstractRepository.kt new file mode 100644 index 00000000..14da46c8 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/AbstractRepository.kt @@ -0,0 +1,64 @@ +package dev.usbharu.hideout.core.infrastructure.exposedrepository + +import dev.usbharu.hideout.core.domain.exception.SpringDataAccessExceptionSQLExceptionTranslator +import org.slf4j.Logger +import org.springframework.beans.factory.annotation.Value +import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator +import java.sql.SQLException + +abstract class AbstractRepository { + protected abstract val logger: Logger + private val sqlErrorCodeSQLExceptionTranslator = SQLErrorCodeSQLExceptionTranslator() + private val springDataAccessExceptionSQLExceptionTranslator = SpringDataAccessExceptionSQLExceptionTranslator() + + @Value("\${hideout.debug.trace-query-exception:false}") + private var traceQueryException: Boolean = false + + @Value("\${hideout.debug.trace-query-call:false}") + private var traceQueryCall: Boolean = false + + protected suspend fun query(block: () -> T): T = try { + + if (traceQueryCall) { + logger.trace( + """ +***** QUERY CALL STACK TRACE ***** + +${Throwable().stackTrace.joinToString("\n")} + +***** QUERY CALL STACK TRACE ***** +""" + ) + + } + + block.invoke() + + } catch (e: SQLException) { + if (traceQueryException) { + logger.trace("FAILED EXECUTE SQL", e) + } + if (e.cause !is SQLException) { + throw e + } + + val dataAccessException = + sqlErrorCodeSQLExceptionTranslator.translate("Failed to persist entity", null, e.cause as SQLException) + ?: throw e + + if (traceQueryException) { + logger.trace("EXCEPTION TRANSLATED TO", dataAccessException) + } + + val translate = springDataAccessExceptionSQLExceptionTranslator.translate( + "Failed to persist entity", + null, + dataAccessException + ) + + if (traceQueryException) { + logger.trace("EXCEPTION TRANSLATED TO", translate) + } + throw translate + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ActorRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ActorRepositoryImpl.kt index fa0f395d..fcb8a736 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ActorRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ActorRepositoryImpl.kt @@ -8,6 +8,8 @@ import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.javatime.timestamp +import org.slf4j.Logger +import org.slf4j.LoggerFactory import org.springframework.stereotype.Repository @Repository @@ -15,12 +17,15 @@ class ActorRepositoryImpl( private val idGenerateService: IdGenerateService, private val actorResultRowMapper: ResultRowMapper, private val actorQueryMapper: QueryMapper -) : - ActorRepository { +) : ActorRepository, AbstractRepository() { + + + override suspend fun save(actor: Actor): Actor = query { + - override suspend fun save(actor: Actor): Actor { val singleOrNull = Actors.select { Actors.id eq actor.id }.forUpdate().empty() if (singleOrNull) { + Actors.insert { it[id] = actor.id it[name] = actor.name @@ -66,52 +71,63 @@ class ActorRepositoryImpl( it[lastPostAt] = actor.lastPostDate } } - return actor + return@query actor } - override suspend fun findById(id: Long): Actor? = - Actors.select { Actors.id eq id }.singleOrNull()?.let(actorResultRowMapper::map) + override suspend fun findById(id: Long): Actor? = query { + return@query Actors.select { Actors.id eq id }.singleOrNull()?.let(actorResultRowMapper::map) + } - override suspend fun findByIdWithLock(id: Long): Actor? = - Actors.select { Actors.id eq id }.forUpdate().singleOrNull()?.let(actorResultRowMapper::map) + override suspend fun findByIdWithLock(id: Long): Actor? = query { + return@query Actors.select { Actors.id eq id }.forUpdate().singleOrNull()?.let(actorResultRowMapper::map) + } - override suspend fun findAll(limit: Int, offset: Long): List = - Actors.selectAll().limit(limit, offset).let(actorQueryMapper::map) + override suspend fun findAll(limit: Int, offset: Long): List = query { + return@query Actors.selectAll().limit(limit, offset).let(actorQueryMapper::map) + } - override suspend fun findByName(name: String): List = - Actors.select { Actors.name eq name }.let(actorQueryMapper::map) + override suspend fun findByName(name: String): List = query { + return@query Actors.select { Actors.name eq name }.let(actorQueryMapper::map) + } - override suspend fun findByNameAndDomain(name: String, domain: String): Actor? = Actors - .select { Actors.name eq name and (Actors.domain eq domain) } - .singleOrNull() - ?.let(actorResultRowMapper::map) + override suspend fun findByNameAndDomain(name: String, domain: String): Actor? = query { + return@query Actors.select { Actors.name eq name and (Actors.domain eq domain) }.singleOrNull() + ?.let(actorResultRowMapper::map) + } - override suspend fun findByNameAndDomainWithLock(name: String, domain: String): Actor? = Actors - .select { Actors.name eq name and (Actors.domain eq domain) } - .forUpdate() - .singleOrNull() - ?.let(actorResultRowMapper::map) + override suspend fun findByNameAndDomainWithLock(name: String, domain: String): Actor? = query { + return@query Actors.select { Actors.name eq name and (Actors.domain eq domain) }.forUpdate().singleOrNull() + ?.let(actorResultRowMapper::map) + } - override suspend fun findByUrl(url: String): Actor? = Actors.select { Actors.url eq url } - .singleOrNull() - ?.let(actorResultRowMapper::map) + override suspend fun findByUrl(url: String): Actor? = query { + return@query Actors.select { Actors.url eq url }.singleOrNull()?.let(actorResultRowMapper::map) + } - override suspend fun findByUrlWithLock(url: String): Actor? = Actors.select { Actors.url eq url }.forUpdate() - .singleOrNull() - ?.let(actorResultRowMapper::map) + override suspend fun findByUrlWithLock(url: String): Actor? = query { + return@query Actors.select { Actors.url eq url }.forUpdate().singleOrNull()?.let(actorResultRowMapper::map) + } - override suspend fun findByIds(ids: List): List = - Actors.select { Actors.id inList ids }.let(actorQueryMapper::map) + override suspend fun findByIds(ids: List): List = query { + return@query Actors.select { Actors.id inList ids }.let(actorQueryMapper::map) + } - override suspend fun findByKeyId(keyId: String): Actor? = Actors.select { Actors.keyId eq keyId } - .singleOrNull() - ?.let(actorResultRowMapper::map) + override suspend fun findByKeyId(keyId: String): Actor? = query { + return@query Actors.select { Actors.keyId eq keyId }.singleOrNull()?.let(actorResultRowMapper::map) + } - override suspend fun delete(id: Long) { + override suspend fun delete(id: Long): Unit = query { Actors.deleteWhere { Actors.id.eq(id) } } override suspend fun nextId(): Long = idGenerateService.generateId() + + companion object { + private val logger = LoggerFactory.getLogger(ActorRepositoryImpl::class.java) + } + + override val logger: Logger + get() = Companion.logger } object Actors : Table("actors") { @@ -120,16 +136,14 @@ object Actors : Table("actors") { val domain: Column = varchar("domain", length = 1000) val screenName: Column = varchar("screen_name", length = 300) val description: Column = varchar( - "description", - length = 10000 + "description", length = 10000 ) val inbox: Column = varchar("inbox", length = 1000).uniqueIndex() val outbox: Column = varchar("outbox", length = 1000).uniqueIndex() val url: Column = varchar("url", length = 1000).uniqueIndex() val publicKey: Column = varchar("public_key", length = 10000) val privateKey: Column = varchar( - "private_key", - length = 10000 + "private_key", length = 10000 ).nullable() val createdAt: Column = long("created_at") val keyId = varchar("key_id", length = 1000) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt index 97b7c527..6e056286 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt @@ -19,7 +19,7 @@ class MediaRepositoryImpl(private val idGenerateService: IdGenerateService) : Me override suspend fun save(media: EntityMedia): EntityMedia { if (Media.select { Media.id eq media.id - }.singleOrNull() != null + }.forUpdate().singleOrNull() != null ) { Media.update({ Media.id eq media.id }) { it[name] = media.name diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt index e1e323e2..6716268a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt @@ -2,24 +2,24 @@ package dev.usbharu.hideout.core.infrastructure.exposedrepository import dev.usbharu.hideout.application.infrastructure.exposed.QueryMapper import dev.usbharu.hideout.application.service.id.IdGenerateService -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.PostRepository -import dev.usbharu.hideout.util.singleOr import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.slf4j.Logger +import org.slf4j.LoggerFactory import org.springframework.stereotype.Repository @Repository class PostRepositoryImpl( private val idGenerateService: IdGenerateService, private val postQueryMapper: QueryMapper -) : PostRepository { +) : PostRepository, AbstractRepository() { override suspend fun generateId(): Long = idGenerateService.generateId() - override suspend fun save(post: Post): Boolean { - val singleOrNull = Posts.select { Posts.id eq post.id }.singleOrNull() + override suspend fun save(post: Post): Post = query { + val singleOrNull = Posts.select { Posts.id eq post.id }.forUpdate().singleOrNull() if (singleOrNull == null) { Posts.insert { it[id] = post.id @@ -61,18 +61,44 @@ class PostRepositoryImpl( it[deleted] = post.delted } } - return singleOrNull == null + return@query post } - override suspend fun findById(id: Long): Post = - Posts.leftJoin(PostsMedia) + override suspend fun findById(id: Long): Post? = query { + return@query Posts.leftJoin(PostsMedia) .select { Posts.id eq id } .let(postQueryMapper::map) - .singleOr { FailedToGetResourcesException("id: $id was not found.", it) } + .singleOrNull() + } - override suspend fun delete(id: Long) { + override suspend fun findByUrl(url: String): Post? = query { + return@query Posts.leftJoin(PostsMedia) + .select { Posts.url eq url } + .let(postQueryMapper::map) + .singleOrNull() + } + + override suspend fun findByApId(apId: String): Post? = query { + return@query Posts.leftJoin(PostsMedia) + .select { Posts.apId eq apId } + .let(postQueryMapper::map) + .singleOrNull() + } + + override suspend fun existByApIdWithLock(apId: String): Boolean = query { + return@query Posts.select { Posts.apId eq apId }.forUpdate().empty().not() + } + + override suspend fun delete(id: Long): Unit = query { Posts.deleteWhere { Posts.id eq id } } + + override val logger: Logger + get() = Companion.logger + + companion object { + private val logger = LoggerFactory.getLogger(PostRepositoryImpl::class.java) + } } object Posts : Table() { 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 fd57f210..71283023 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 @@ -7,8 +7,11 @@ 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.job.JobExecutionType import kjob.core.kjob import kjob.mongo.Mongo +import kotlinx.coroutines.CancellationException +import org.slf4j.MDC import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.stereotype.Service @@ -24,6 +27,8 @@ class KJobMongoJobQueueWorkerService( nonBlockingMaxJobs = 10 blockingMaxJobs = 10 jobExecutionPeriodInSeconds = 1 + maxRetries = 3 + defaultJobExecutor = JobExecutionType.NON_BLOCKING }.start() } @@ -36,9 +41,22 @@ class KJobMongoJobQueueWorkerService( } for (jobProcessor in jobQueueProcessorList) { kjob.register(jobProcessor.job()) { + execute { - val param = it.convertUnsafe(props) - jobProcessor.process(param) + try { + MDC.put("x-job-id", this.jobId) + val param = it.convertUnsafe(props) + jobProcessor.process(param) + } catch (e: CancellationException) { + throw e + } catch (e: Exception) { + logger.warn("FAILED Excute Job. job name: {} job id: {}", it.name, this.jobId, e) + throw e + } finally { + MDC.remove("x-job-id") + } + }.onError { + logger.warn("FAILED Excute Job. job name: {} job id: {}", this.jobName, this.jobId, error) } } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoTimelineRepositoryWrapper.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoTimelineRepositoryWrapper.kt index dfaebfce..f5148bdb 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoTimelineRepositoryWrapper.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoTimelineRepositoryWrapper.kt @@ -1,11 +1,15 @@ package dev.usbharu.hideout.core.infrastructure.mongorepository import dev.usbharu.hideout.application.service.id.IdGenerateService +import dev.usbharu.hideout.core.domain.exception.resource.DuplicateException +import dev.usbharu.hideout.core.domain.exception.resource.ResourceAccessException import dev.usbharu.hideout.core.domain.model.timeline.Timeline import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.dao.DataAccessException +import org.springframework.dao.DuplicateKeyException import org.springframework.stereotype.Repository @Repository @@ -23,8 +27,15 @@ class MongoTimelineRepositoryWrapper( } } - override suspend fun saveAll(timelines: List): List = - mongoTimelineRepository.saveAll(timelines) + override suspend fun saveAll(timelines: List): List { + try { + return mongoTimelineRepository.saveAll(timelines) + } catch (e: DuplicateKeyException) { + throw DuplicateException("Timeline duplicate.", e) + } catch (e: DataAccessException) { + throw ResourceAccessException(e) + } + } override suspend fun findByUserId(id: Long): List { return withContext(Dispatchers.IO) { diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt index 63cfb4ef..72e9fdd9 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt @@ -2,6 +2,8 @@ package dev.usbharu.hideout.core.service.post import dev.usbharu.hideout.activitypub.service.activity.create.ApSendCreateService import dev.usbharu.hideout.core.domain.exception.UserNotFoundException +import dev.usbharu.hideout.core.domain.exception.resource.DuplicateException +import dev.usbharu.hideout.core.domain.exception.resource.PostNotFoundException import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.Post @@ -9,9 +11,7 @@ import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.service.timeline.TimelineService -import org.jetbrains.exposed.exceptions.ExposedSQLException import org.slf4j.LoggerFactory -import org.springframework.dao.DuplicateKeyException import org.springframework.stereotype.Service import java.time.Instant @@ -79,18 +79,12 @@ class PostServiceImpl( private suspend fun internalCreate(post: Post, isLocal: Boolean, actor: Actor): Post { return try { - if (postRepository.save(post)) { - try { - timelineService.publishTimeline(post, isLocal) - actorRepository.save(actor.incrementPostsCount()) - } catch (e: DuplicateKeyException) { - logger.trace("Timeline already exists.", e) - } - } - post - } catch (e: ExposedSQLException) { - logger.warn("FAILED Save to post. url: ${post.apId}", e) - postQueryService.findByApId(post.apId) + val save = postRepository.save(post) + timelineService.publishTimeline(post, isLocal) + actorRepository.save(actor.incrementPostsCount()) + save + } catch (e: DuplicateException) { + postRepository.findByApId(post.apId) ?: throw PostNotFoundException.withApId(post.apId) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/resource/InMemoryCacheManager.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/resource/InMemoryCacheManager.kt index 6efbc980..8cb59ba7 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/resource/InMemoryCacheManager.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/resource/InMemoryCacheManager.kt @@ -33,6 +33,7 @@ class InMemoryCacheManager : CacheManager { val processed = try { block() } catch (e: Exception) { + e.printStackTrace() cacheKey.remove(key) throw e } @@ -46,7 +47,7 @@ class InMemoryCacheManager : CacheManager { override suspend fun getOrWait(key: String): ResolveResponse { while (valueStore.contains(key).not()) { if (cacheKey.containsKey(key).not()) { - throw IllegalStateException("Invalid cache key.") + throw IllegalStateException("Invalid cache key. $key") } delay(1) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt index d8b97c32..f51f5485 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt @@ -3,6 +3,7 @@ package dev.usbharu.hideout.core.service.user import dev.usbharu.hideout.activitypub.service.activity.delete.APSendDeleteService import dev.usbharu.hideout.application.config.ApplicationConfig import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.domain.exception.resource.DuplicateException import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.ActorRepository @@ -15,10 +16,8 @@ import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository import dev.usbharu.hideout.core.query.DeletedActorQueryService import dev.usbharu.hideout.core.service.instance.InstanceService import dev.usbharu.hideout.core.service.post.PostService -import org.jetbrains.exposed.exceptions.ExposedSQLException import org.slf4j.LoggerFactory import org.springframework.stereotype.Service -import org.springframework.transaction.annotation.Transactional import java.time.Instant @Service @@ -72,7 +71,6 @@ class UserServiceImpl( return save } - @Transactional override suspend fun createRemoteUser(user: RemoteUserCreateDto): Actor { logger.info("START Create New remote user. name: {} url: {}", user.name, user.url) @@ -113,8 +111,7 @@ class UserServiceImpl( val save = actorRepository.save(userEntity) logger.warn("SUCCESS Create New remote user. id: {} name: {} url: {}", userEntity.id, user.name, user.url) save - } catch (_: ExposedSQLException) { - logger.warn("FAILED User already exists. name: {} url: {}", user.name, user.url) + } catch (_: DuplicateException) { actorRepository.findByUrl(user.url)!! } } diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 41b1f895..ea1c0ecd 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -15,7 +15,7 @@ - %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{x-request-id}] [%X{x-job-id}] %logger{36} - + %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{x-request-id},%X{x-job-id}] %logger{36} - %msg%n From 3571ab22e30928402094259bb740e8618ea239e7 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 19 Dec 2023 17:52:08 +0900 Subject: [PATCH 03/12] =?UTF-8?q?refactor:=20FailedToGetResourceException?= =?UTF-8?q?=E3=82=92=E4=BD=BF=E3=82=8F=E3=81=AA=E3=81=84=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exposedquery/NoteQueryServiceImpl.kt | 27 +++--- .../api/actor/UserAPControllerImpl.kt | 4 +- .../api/webfinger/WebFingerController.kt | 4 +- .../activitypub/query/NoteQueryService.kt | 4 +- .../create/ApSendCreateServiceImpl.kt | 3 +- .../activity/delete/APDeleteProcessor.kt | 18 ++-- .../service/activity/like/APLikeProcessor.kt | 22 ++--- .../activity/like/APReactionService.kt | 5 +- .../service/activity/undo/APUndoProcessor.kt | 4 +- .../service/objects/note/APNoteService.kt | 92 ++++++++----------- .../objects/note/NoteApApiServiceImpl.kt | 10 +- .../resource/PostNotFoundException.kt | 4 + .../deletedActor/DeletedActorRepository.kt | 2 +- .../model/instance/InstanceRepository.kt | 2 +- .../domain/model/media/MediaRepository.kt | 2 +- .../DeletedActorQueryServiceImpl.kt | 10 +- .../exposedquery/InstanceQueryServiceImpl.kt | 6 +- .../exposedquery/MediaQueryServiceImpl.kt | 8 +- .../exposedquery/PostQueryServiceImpl.kt | 16 ++-- .../exposedquery/ReactionQueryServiceImpl.kt | 13 +-- .../DeletedActorRepositoryImpl.kt | 28 +++--- .../InstanceRepositoryImpl.kt | 6 +- .../exposedrepository/MediaRepositoryImpl.kt | 9 +- .../core/query/DeletedActorQueryService.kt | 2 +- .../core/query/InstanceQueryService.kt | 2 +- .../hideout/core/query/MediaQueryService.kt | 2 +- .../hideout/core/query/PostQueryService.kt | 6 +- .../core/query/ReactionQueryService.kt | 2 +- .../core/service/instance/InstanceService.kt | 12 +-- .../core/service/media/MediaServiceImpl.kt | 7 +- .../service/reaction/ReactionServiceImpl.kt | 33 ++++--- .../core/service/user/UserServiceImpl.kt | 7 +- .../exposedquery/AccountQueryServiceImpl.kt | 8 +- .../mastodon/query/AccountQueryService.kt | 2 +- .../service/account/AccountService.kt | 3 +- .../service/status/StatusesApiService.kt | 10 +- 36 files changed, 185 insertions(+), 210 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt index 9685d383..b0807f48 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt @@ -5,12 +5,10 @@ import dev.usbharu.hideout.activitypub.domain.model.Note import dev.usbharu.hideout.activitypub.query.NoteQueryService import dev.usbharu.hideout.activitypub.service.objects.note.APNoteServiceImpl.Companion.public import dev.usbharu.hideout.application.infrastructure.exposed.QueryMapper -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.domain.model.post.Visibility import dev.usbharu.hideout.core.infrastructure.exposedrepository.* -import dev.usbharu.hideout.util.singleOr import org.jetbrains.exposed.sql.Query import org.jetbrains.exposed.sql.ResultRow import org.jetbrains.exposed.sql.select @@ -21,39 +19,38 @@ import java.time.Instant @Repository class NoteQueryServiceImpl(private val postRepository: PostRepository, private val postQueryMapper: QueryMapper) : NoteQueryService { - override suspend fun findById(id: Long): Pair { + override suspend fun findById(id: Long): Pair? { return Posts .leftJoin(Actors) .leftJoin(PostsMedia) .leftJoin(Media) .select { Posts.id eq id } .let { - it.toNote() to postQueryMapper.map(it) - .singleOr { FailedToGetResourcesException("id: $id does not exist.") } + (it.toNote() ?: return null) to (postQueryMapper.map(it) + .singleOrNull() ?: return null) } } - override suspend fun findByApid(apId: String): Pair { + override suspend fun findByApid(apId: String): Pair? { return Posts .leftJoin(Actors) .leftJoin(PostsMedia) .leftJoin(Media) .select { Posts.apId eq apId } .let { - it.toNote() to postQueryMapper.map(it) - .singleOr { FailedToGetResourcesException("apid: $apId does not exist.") } + (it.toNote() ?: return null) to (postQueryMapper.map(it) + .singleOrNull() ?: return null) } } private suspend fun ResultRow.toNote(mediaList: List): Note { val replyId = this[Posts.replyId] val replyTo = if (replyId != null) { - try { - postRepository.findById(replyId)?.url ?: throw FailedToGetResourcesException() - } catch (e: FailedToGetResourcesException) { - logger.warn("Failed to get replyId: $replyId", e) - null + val url = postRepository.findById(replyId)?.url + if (url == null) { + logger.warn("Failed to get replyId: $replyId") } + url } else { null } @@ -76,11 +73,11 @@ class NoteQueryServiceImpl(private val postRepository: PostRepository, private v ) } - private suspend fun Query.toNote(): Note { + private suspend fun Query.toNote(): Note? { return this.groupBy { it[Posts.id] } .map { it.value } .map { it.first().toNote(it.mapNotNull { resultRow -> resultRow.toMediaOrNull() }) } - .singleOr { FailedToGetResourcesException("resource does not exist.") } + .singleOrNull() } private fun visibility(visibility: Visibility, followers: String?): Pair, List> { diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/UserAPControllerImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/UserAPControllerImpl.kt index ea8ad508..df90a913 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/UserAPControllerImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/UserAPControllerImpl.kt @@ -2,7 +2,7 @@ package dev.usbharu.hideout.activitypub.interfaces.api.actor import dev.usbharu.hideout.activitypub.domain.model.Person import dev.usbharu.hideout.activitypub.service.objects.user.APUserService -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.RestController @@ -12,7 +12,7 @@ class UserAPControllerImpl(private val apUserService: APUserService) : UserAPCon override suspend fun userAp(username: String): ResponseEntity { val person = try { apUserService.getPersonByName(username) - } catch (_: FailedToGetResourcesException) { + } catch (_: UserNotFoundException) { return ResponseEntity.notFound().build() } person.context += listOf("https://www.w3.org/ns/activitystreams") diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/webfinger/WebFingerController.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/webfinger/WebFingerController.kt index 3a7bfdd8..39665c71 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/webfinger/WebFingerController.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/webfinger/WebFingerController.kt @@ -3,7 +3,7 @@ package dev.usbharu.hideout.activitypub.interfaces.api.webfinger import dev.usbharu.hideout.activitypub.domain.model.webfinger.WebFinger import dev.usbharu.hideout.activitypub.service.webfinger.WebFingerApiService import dev.usbharu.hideout.application.config.ApplicationConfig -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import dev.usbharu.hideout.util.AcctUtil import kotlinx.coroutines.runBlocking import org.slf4j.LoggerFactory @@ -29,7 +29,7 @@ class WebFingerController( } val user = try { webFingerApiService.findByNameAndDomain(acct.username, acct.domain ?: applicationConfig.url.host) - } catch (_: FailedToGetResourcesException) { + } catch (_: UserNotFoundException) { return@runBlocking ResponseEntity.notFound().build() } val webFinger = WebFinger( diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/query/NoteQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/query/NoteQueryService.kt index f61b6992..4c57168c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/query/NoteQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/query/NoteQueryService.kt @@ -4,6 +4,6 @@ import dev.usbharu.hideout.activitypub.domain.model.Note import dev.usbharu.hideout.core.domain.model.post.Post interface NoteQueryService { - suspend fun findById(id: Long): Pair - suspend fun findByApid(apId: String): Pair + suspend fun findById(id: Long): Pair? + suspend fun findByApid(apId: String): Pair? } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImpl.kt index 7f6ea823..500a7c76 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImpl.kt @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper import dev.usbharu.hideout.activitypub.domain.model.Create import dev.usbharu.hideout.activitypub.query.NoteQueryService import dev.usbharu.hideout.application.config.ApplicationConfig +import dev.usbharu.hideout.core.domain.exception.resource.PostNotFoundException import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.Post @@ -31,7 +32,7 @@ class ApSendCreateServiceImpl( logger.debug("DELIVER Deliver Note Create ${followers.size} accounts.") val userEntity = actorRepository.findById(post.actorId) ?: throw UserNotFoundException.withId(post.actorId) - val note = noteQueryService.findById(post.id).first + val note = noteQueryService.findById(post.id)?.first ?: throw PostNotFoundException.withId(post.id) val create = Create( name = "Create Note", apObject = note, 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 index f56f6018..8a3559d8 100644 --- 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 @@ -8,9 +8,8 @@ import dev.usbharu.hideout.activitypub.service.common.AbstractActivityPubProcess 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.actor.ActorRepository -import dev.usbharu.hideout.core.query.PostQueryService +import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.service.post.PostService import dev.usbharu.hideout.core.service.user.UserService import org.springframework.stereotype.Service @@ -18,10 +17,10 @@ import org.springframework.stereotype.Service @Service class APDeleteProcessor( transaction: Transaction, - private val postQueryService: PostQueryService, private val userService: UserService, private val postService: PostService, - private val actorRepository: ActorRepository + private val actorRepository: ActorRepository, + private val postRepository: PostRepository ) : AbstractActivityPubProcessor(transaction) { override suspend fun internalProcess(activity: ActivityPubProcessContext) { @@ -38,12 +37,13 @@ class APDeleteProcessor( actor?.let { userService.deleteRemoteActor(it.id) } - try { - val post = postQueryService.findByApId(deleteId) - postService.deleteRemote(post) - } catch (e: FailedToGetResourcesException) { - logger.warn("FAILED delete id: {} is not found.", deleteId, e) + val post = postRepository.findByApId(deleteId) + if (post == null) { + logger.warn("FAILED Delete id: {} is not found.", deleteId) + return } + postService.deleteRemote(post) + } override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Delete 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 index ffa775e4..8ac309ed 100644 --- 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 @@ -8,7 +8,6 @@ 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 import org.springframework.stereotype.Service @@ -17,7 +16,6 @@ class APLikeProcessor( transaction: Transaction, private val apUserService: APUserService, private val apNoteService: APNoteService, - private val postQueryService: PostQueryService, private val reactionService: ReactionService ) : AbstractActivityPubProcessor(transaction) { @@ -30,23 +28,21 @@ class APLikeProcessor( val personWithEntity = apUserService.fetchPersonWithEntity(actor) try { - apNoteService.fetchNote(target) + val post = apNoteService.fetchNoteWithEntity(target).second + reactionService.receiveReaction( + content, + actor.substringAfter("://").substringBefore("/"), + personWithEntity.second.id, + post.id + ) + + logger.debug("SUCCESS Add Like($content) from ${personWithEntity.second.url} to ${post.url}") } 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 diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt index 94f67a4f..7e29a1e4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt @@ -1,6 +1,7 @@ package dev.usbharu.hideout.activitypub.service.activity.like import com.fasterxml.jackson.databind.ObjectMapper +import dev.usbharu.hideout.core.domain.exception.resource.PostNotFoundException import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.reaction.Reaction @@ -29,7 +30,7 @@ class APReactionServiceImpl( val followers = followerQueryService.findFollowersById(like.actorId) val user = actorRepository.findById(like.actorId) ?: throw UserNotFoundException.withId(like.actorId) val post = - postQueryService.findById(like.postId) + postQueryService.findById(like.postId) ?: throw PostNotFoundException.withId(like.postId) followers.forEach { follower -> jobQueueParentService.schedule(DeliverReactionJob) { props[DeliverReactionJob.actor] = user.url @@ -45,7 +46,7 @@ class APReactionServiceImpl( val followers = followerQueryService.findFollowersById(like.actorId) val user = actorRepository.findById(like.actorId) ?: throw UserNotFoundException.withId(like.actorId) val post = - postQueryService.findById(like.postId) + postQueryService.findById(like.postId) ?: throw PostNotFoundException.withId(like.postId) followers.forEach { follower -> jobQueueParentService.schedule(DeliverRemoveReactionJob) { props[DeliverRemoveReactionJob.actor] = user.url 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 index afd9a721..84eed5fa 100644 --- 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 @@ -7,6 +7,7 @@ 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.domain.exception.resource.PostNotFoundException import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import dev.usbharu.hideout.core.domain.exception.resource.local.LocalUserNotFoundException import dev.usbharu.hideout.core.domain.model.actor.ActorRepository @@ -79,7 +80,8 @@ class APUndoProcessor( "Like" -> { val like = undo.apObject as Like - val post = postQueryService.findByUrl(like.apObject) + val post = + postQueryService.findByUrl(like.apObject) ?: throw PostNotFoundException.withUrl(like.apObject) val signer = actorRepository.findById(post.actorId) ?: throw LocalUserNotFoundException.withId(post.actorId) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt index 48537741..18a32185 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt @@ -6,7 +6,6 @@ import dev.usbharu.hideout.activitypub.query.NoteQueryService import dev.usbharu.hideout.activitypub.service.common.APResourceResolveService import dev.usbharu.hideout.activitypub.service.common.resolve import dev.usbharu.hideout.activitypub.service.objects.user.APUserService -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.domain.model.post.Visibility @@ -20,8 +19,9 @@ import org.springframework.stereotype.Service import java.time.Instant interface APNoteService { - suspend fun fetchNote(url: String, targetActor: String? = null): Note + suspend fun fetchNote(url: String, targetActor: String? = null): Note = fetchNoteWithEntity(url, targetActor).first suspend fun fetchNote(note: Note, targetActor: String? = null): Note + suspend fun fetchNoteWithEntity(url: String, targetActor: String? = null): Pair } @Service @@ -40,13 +40,14 @@ class APNoteServiceImpl( private val logger = LoggerFactory.getLogger(APNoteServiceImpl::class.java) - override suspend fun fetchNote(url: String, targetActor: String?): Note { + override suspend fun fetchNoteWithEntity(url: String, targetActor: String?): Pair { logger.debug("START Fetch Note url: {}", url) - try { - val post = noteQueryService.findByApid(url) + + val post = noteQueryService.findByApid(url) + + if (post != null) { logger.debug("SUCCESS Found in local url: {}", url) - return post.first - } catch (_: FailedToGetResourcesException) { + return post } logger.info("AP GET url: {}", url) @@ -54,9 +55,7 @@ class APNoteServiceImpl( apResourceResolveService.resolve(url, null as Long?) } catch (e: ClientRequestException) { logger.warn( - "FAILED Failed to retrieve ActivityPub resource. HTTP Status Code: {} url: {}", - e.response.status, - url + "FAILED Failed to retrieve ActivityPub resource. HTTP Status Code: {} url: {}", e.response.status, url ) throw FailedToGetActivityPubResourceException("Could not retrieve $url.", e) } @@ -66,45 +65,33 @@ class APNoteServiceImpl( } private suspend fun saveIfMissing( - note: Note, - targetActor: String?, - url: String - ): Note { - requireNotNull(note.id) { "id is null" } - - - - return try { - noteQueryService.findByApid(note.id).first - } catch (e: FailedToGetResourcesException) { - saveNote(note, targetActor, url) - } - - + note: Note, targetActor: String?, url: String + ): Pair { + return noteQueryService.findByApid(note.id) ?: saveNote(note, targetActor, url) } - private suspend fun saveNote(note: Note, targetActor: String?, url: String): Note { + private suspend fun saveNote(note: Note, targetActor: String?, url: String): Pair { val person = apUserService.fetchPersonWithEntity( - note.attributedTo, - targetActor + note.attributedTo, targetActor ) - if (postRepository.existByApIdWithLock(note.id)) { - return note + val post = postRepository.findByApId(note.id) + + if (post != null) { + return note to post } logger.debug("VISIBILITY url: {} to: {} cc: {}", note.id, note.to, note.cc) - val visibility = - if (note.to.contains(public)) { - Visibility.PUBLIC - } else if (note.to.contains(person.second.followers) && note.cc.contains(public)) { - Visibility.UNLISTED - } else if (note.to.contains(person.second.followers)) { - Visibility.FOLLOWERS - } else { - Visibility.DIRECT - } + val visibility = if (note.to.contains(public)) { + Visibility.PUBLIC + } else if (note.to.contains(person.second.followers) && note.cc.contains(public)) { + Visibility.UNLISTED + } else if (note.to.contains(person.second.followers)) { + Visibility.FOLLOWERS + } else { + Visibility.DIRECT + } logger.debug("VISIBILITY is {} url: {}", visibility.name, note.id) @@ -113,22 +100,15 @@ class APNoteServiceImpl( postQueryService.findByUrl(it) } - val mediaList = note.attachment - .filter { it.url != null } - .map { - mediaService.uploadRemoteMedia( - RemoteMedia( - it.name, - it.url, - it.mediaType, - description = it.name - ) + val mediaList = note.attachment.map { + mediaService.uploadRemoteMedia( + RemoteMedia( + it.name, it.url, it.mediaType, description = it.name ) - } - .map { it.id } + ) + }.map { it.id } - // TODO: リモートのメディア処理を追加 - postService.createRemote( + val createRemote = postService.createRemote( postBuilder.of( id = postRepository.generateId(), actorId = person.second.id, @@ -142,11 +122,11 @@ class APNoteServiceImpl( mediaIds = mediaList ) ) - return note + return note to createRemote } override suspend fun fetchNote(note: Note, targetActor: String?): Note = - saveIfMissing(note, targetActor, note.id) + saveIfMissing(note, targetActor, note.id).first companion object { const val public: String = "https://www.w3.org/ns/activitystreams#Public" diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/NoteApApiServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/NoteApApiServiceImpl.kt index 4420ceb0..e6dc9ca0 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/NoteApApiServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/NoteApApiServiceImpl.kt @@ -3,7 +3,6 @@ package dev.usbharu.hideout.activitypub.service.objects.note import dev.usbharu.hideout.activitypub.domain.model.Note import dev.usbharu.hideout.activitypub.query.NoteQueryService import dev.usbharu.hideout.application.external.Transaction -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.Visibility import dev.usbharu.hideout.core.query.FollowerQueryService @@ -17,12 +16,13 @@ class NoteApApiServiceImpl( private val transaction: Transaction ) : NoteApApiService { override suspend fun getNote(postId: Long, userId: Long?): Note? = transaction.transaction { - val findById = try { - noteQueryService.findById(postId) - } catch (e: FailedToGetResourcesException) { - logger.warn("Note not found.", e) + val findById = noteQueryService.findById(postId) + + if (findById == null) { + logger.warn("Note not found. $postId $userId") return@transaction null } + when (findById.second.visibility) { Visibility.PUBLIC, Visibility.UNLISTED -> { return@transaction findById.first diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/PostNotFoundException.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/PostNotFoundException.kt index f66c41d8..cae271aa 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/PostNotFoundException.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/PostNotFoundException.kt @@ -19,5 +19,9 @@ class PostNotFoundException : NotFoundException { private const val serialVersionUID: Long = 1315818410686905717L fun withApId(apId: String): PostNotFoundException = PostNotFoundException("apId: $apId was not found.") + + fun withId(id: Long): PostNotFoundException = PostNotFoundException("id: $id was not found.") + + fun withUrl(url: String): PostNotFoundException = PostNotFoundException("url: $url was not found.") } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActorRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActorRepository.kt index f2d18368..1c5a291e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActorRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActorRepository.kt @@ -3,5 +3,5 @@ package dev.usbharu.hideout.core.domain.model.deletedActor interface DeletedActorRepository { suspend fun save(deletedActor: DeletedActor): DeletedActor suspend fun delete(deletedActor: DeletedActor) - suspend fun findById(id: Long): DeletedActor + suspend fun findById(id: Long): DeletedActor? } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/InstanceRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/InstanceRepository.kt index 35b6026e..9883cb35 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/InstanceRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/InstanceRepository.kt @@ -3,6 +3,6 @@ package dev.usbharu.hideout.core.domain.model.instance interface InstanceRepository { suspend fun generateId(): Long suspend fun save(instance: Instance): Instance - suspend fun findById(id: Long): Instance + suspend fun findById(id: Long): Instance? suspend fun delete(instance: Instance) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/media/MediaRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/media/MediaRepository.kt index 1e18f68b..b5e2abb2 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/media/MediaRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/media/MediaRepository.kt @@ -3,6 +3,6 @@ package dev.usbharu.hideout.core.domain.model.media interface MediaRepository { suspend fun generateId(): Long suspend fun save(media: Media): Media - suspend fun findById(id: Long): Media + suspend fun findById(id: Long): Media? suspend fun delete(id: Long) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/DeletedActorQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/DeletedActorQueryServiceImpl.kt index f412b310..a5518867 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/DeletedActorQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/DeletedActorQueryServiceImpl.kt @@ -1,23 +1,19 @@ package dev.usbharu.hideout.core.infrastructure.exposedquery -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.deletedActor.DeletedActor import dev.usbharu.hideout.core.infrastructure.exposedrepository.DeletedActors import dev.usbharu.hideout.core.infrastructure.exposedrepository.toDeletedActor import dev.usbharu.hideout.core.query.DeletedActorQueryService -import dev.usbharu.hideout.util.singleOr import org.jetbrains.exposed.sql.and import org.jetbrains.exposed.sql.select import org.springframework.stereotype.Repository @Repository class DeletedActorQueryServiceImpl : DeletedActorQueryService { - override suspend fun findByNameAndDomain(name: String, domain: String): DeletedActor { + override suspend fun findByNameAndDomain(name: String, domain: String): DeletedActor? { return DeletedActors .select { DeletedActors.name eq name and (DeletedActors.domain eq domain) } - .singleOr { - FailedToGetResourcesException("name: $name domain: $domain was not exist or duplicate.", it) - } - .toDeletedActor() + .singleOrNull() + ?.toDeletedActor() } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/InstanceQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/InstanceQueryServiceImpl.kt index c7d276ef..9c518904 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/InstanceQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/InstanceQueryServiceImpl.kt @@ -1,16 +1,14 @@ package dev.usbharu.hideout.core.infrastructure.exposedquery -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.infrastructure.exposedrepository.Instance import dev.usbharu.hideout.core.infrastructure.exposedrepository.toInstance import dev.usbharu.hideout.core.query.InstanceQueryService -import dev.usbharu.hideout.util.singleOr import org.jetbrains.exposed.sql.select import org.springframework.stereotype.Repository import dev.usbharu.hideout.core.domain.model.instance.Instance as InstanceEntity @Repository class InstanceQueryServiceImpl : InstanceQueryService { - override suspend fun findByUrl(url: String): InstanceEntity = Instance.select { Instance.url eq url } - .singleOr { FailedToGetResourcesException("$url is doesn't exist", it) }.toInstance() + override suspend fun findByUrl(url: String): InstanceEntity? = Instance.select { Instance.url eq url } + .singleOrNull()?.toInstance() } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt index df87d4c9..f4b777aa 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt @@ -1,11 +1,9 @@ package dev.usbharu.hideout.core.infrastructure.exposedquery -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.infrastructure.exposedrepository.Media import dev.usbharu.hideout.core.infrastructure.exposedrepository.PostsMedia import dev.usbharu.hideout.core.infrastructure.exposedrepository.toMedia import dev.usbharu.hideout.core.query.MediaQueryService -import dev.usbharu.hideout.util.singleOr import org.jetbrains.exposed.sql.innerJoin import org.jetbrains.exposed.sql.select import org.springframework.stereotype.Repository @@ -23,9 +21,9 @@ class MediaQueryServiceImpl : MediaQueryService { .map { it.toMedia() } } - override suspend fun findByRemoteUrl(remoteUrl: String): MediaEntity { + override suspend fun findByRemoteUrl(remoteUrl: String): MediaEntity? { return Media.select { Media.remoteUrl eq remoteUrl }.forUpdate() - .singleOr { FailedToGetResourcesException("remoteUrl: $remoteUrl is duplicate or not exist.", it) } - .toMedia() + .singleOrNull() + ?.toMedia() } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/PostQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/PostQueryServiceImpl.kt index 65d8d492..c69027e9 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/PostQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/PostQueryServiceImpl.kt @@ -2,12 +2,10 @@ package dev.usbharu.hideout.core.infrastructure.exposedquery import dev.usbharu.hideout.application.infrastructure.exposed.QueryMapper import dev.usbharu.hideout.application.infrastructure.exposed.ResultRowMapper -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts import dev.usbharu.hideout.core.infrastructure.exposedrepository.PostsMedia import dev.usbharu.hideout.core.query.PostQueryService -import dev.usbharu.hideout.util.singleOr import org.jetbrains.exposed.sql.select import org.springframework.stereotype.Repository @@ -16,23 +14,23 @@ class PostQueryServiceImpl( private val postResultRowMapper: ResultRowMapper, private val postQueryMapper: QueryMapper ) : PostQueryService { - override suspend fun findById(id: Long): Post = + override suspend fun findById(id: Long): Post? = Posts.leftJoin(PostsMedia) .select { Posts.id eq id } - .singleOr { FailedToGetResourcesException("id: $id is duplicate or does not exist.", it) } - .let(postResultRowMapper::map) + .singleOrNull() + ?.let(postResultRowMapper::map) - override suspend fun findByUrl(url: String): Post = + override suspend fun findByUrl(url: String): Post? = Posts.leftJoin(PostsMedia) .select { Posts.url eq url } .let(postQueryMapper::map) - .singleOr { FailedToGetResourcesException("url: $url is duplicate or does not exist.", it) } + .singleOrNull() - override suspend fun findByApId(string: String): Post = + override suspend fun findByApId(string: String): Post? = Posts.leftJoin(PostsMedia) .select { Posts.apId eq string } .let(postQueryMapper::map) - .singleOr { FailedToGetResourcesException("apId: $string is duplicate or does not exist.", it) } + .singleOrNull() override suspend fun findByActorId(actorId: Long): List = Posts.leftJoin(PostsMedia).select { Posts.actorId eq actorId }.let(postQueryMapper::map) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ReactionQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ReactionQueryServiceImpl.kt index 8e51e2e6..349de146 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ReactionQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ReactionQueryServiceImpl.kt @@ -1,11 +1,9 @@ package dev.usbharu.hideout.core.infrastructure.exposedquery -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.reaction.Reaction import dev.usbharu.hideout.core.infrastructure.exposedrepository.Reactions import dev.usbharu.hideout.core.infrastructure.exposedrepository.toReaction import dev.usbharu.hideout.core.query.ReactionQueryService -import dev.usbharu.hideout.util.singleOr import org.jetbrains.exposed.sql.and import org.jetbrains.exposed.sql.select import org.springframework.stereotype.Repository @@ -19,20 +17,15 @@ class ReactionQueryServiceImpl : ReactionQueryService { } @Suppress("FunctionMaxLength") - override suspend fun findByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Reaction { + override suspend fun findByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Reaction? { return Reactions .select { Reactions.postId.eq(postId).and(Reactions.actorId.eq(actorId)).and( Reactions.emojiId.eq(emojiId) ) } - .singleOr { - FailedToGetResourcesException( - "postId: $postId,userId: $actorId,emojiId: $emojiId is duplicate or does not exist.", - it - ) - } - .toReaction() + .singleOrNull() + ?.toReaction() } override suspend fun reactionAlreadyExist(postId: Long, actorId: Long, emojiId: Long): Boolean { diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt index 440c1a36..31246dbd 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt @@ -1,18 +1,18 @@ package dev.usbharu.hideout.core.infrastructure.exposedrepository -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.deletedActor.DeletedActor import dev.usbharu.hideout.core.domain.model.deletedActor.DeletedActorRepository -import dev.usbharu.hideout.util.singleOr import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.javatime.timestamp +import org.slf4j.Logger +import org.slf4j.LoggerFactory import org.springframework.stereotype.Repository @Repository -class DeletedActorRepositoryImpl : DeletedActorRepository { - override suspend fun save(deletedActor: DeletedActor): DeletedActor { - val singleOrNull = DeletedActors.select { DeletedActors.id eq deletedActor.id }.singleOrNull() +class DeletedActorRepositoryImpl : DeletedActorRepository, AbstractRepository() { + override suspend fun save(deletedActor: DeletedActor): DeletedActor = query { + val singleOrNull = DeletedActors.select { DeletedActors.id eq deletedActor.id }.forUpdate().singleOrNull() if (singleOrNull == null) { DeletedActors.insert { @@ -30,18 +30,24 @@ class DeletedActorRepositoryImpl : DeletedActorRepository { it[DeletedActors.deletedAt] = deletedActor.deletedAt } } - return deletedActor + return@query deletedActor } - override suspend fun delete(deletedActor: DeletedActor) { + override suspend fun delete(deletedActor: DeletedActor): Unit = query { DeletedActors.deleteWhere { DeletedActors.id eq deletedActor.id } } - override suspend fun findById(id: Long): DeletedActor { - val singleOr = DeletedActors.select { DeletedActors.id eq id } - .singleOr { FailedToGetResourcesException("id: $id was not exist or duplicate", it) } + override suspend fun findById(id: Long): DeletedActor? = query { + return@query DeletedActors.select { DeletedActors.id eq id } + .singleOrNull() + ?.let { it.toDeletedActor() } + } - return deletedActor(singleOr) + override val logger: Logger + get() = Companion.logger + + companion object { + private val logger = LoggerFactory.getLogger(DeletedActorRepositoryImpl::class.java) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt index 883a5b48..41aa2535 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt @@ -1,9 +1,7 @@ package dev.usbharu.hideout.core.infrastructure.exposedrepository import dev.usbharu.hideout.application.service.id.IdGenerateService -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository -import dev.usbharu.hideout.util.singleOr import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.javatime.timestamp @@ -48,9 +46,9 @@ class InstanceRepositoryImpl(private val idGenerateService: IdGenerateService) : return instance } - override suspend fun findById(id: Long): InstanceEntity { + override suspend fun findById(id: Long): InstanceEntity? { return Instance.select { Instance.id eq id } - .singleOr { FailedToGetResourcesException("id: $id doesn't exist.") }.toInstance() + .singleOrNull()?.toInstance() } override suspend fun delete(instance: InstanceEntity) { diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt index 6e056286..3039dc77 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt @@ -1,12 +1,10 @@ package dev.usbharu.hideout.core.infrastructure.exposedrepository import dev.usbharu.hideout.application.service.id.IdGenerateService -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.media.MediaRepository import dev.usbharu.hideout.core.infrastructure.exposedrepository.Media.mimeType import dev.usbharu.hideout.core.service.media.FileType import dev.usbharu.hideout.core.service.media.MimeType -import dev.usbharu.hideout.util.singleOr import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.springframework.stereotype.Repository @@ -47,14 +45,13 @@ class MediaRepositoryImpl(private val idGenerateService: IdGenerateService) : Me return media } - override suspend fun findById(id: Long): EntityMedia { + override suspend fun findById(id: Long): EntityMedia? { return Media .select { Media.id eq id } - .singleOr { - FailedToGetResourcesException("id: $id was not found.") - }.toMedia() + .singleOrNull() + ?.toMedia() } override suspend fun delete(id: Long) { diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/DeletedActorQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/DeletedActorQueryService.kt index de7fcc53..e7dd164d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/query/DeletedActorQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/query/DeletedActorQueryService.kt @@ -3,5 +3,5 @@ package dev.usbharu.hideout.core.query import dev.usbharu.hideout.core.domain.model.deletedActor.DeletedActor interface DeletedActorQueryService { - suspend fun findByNameAndDomain(name: String, domain: String): DeletedActor + suspend fun findByNameAndDomain(name: String, domain: String): DeletedActor? } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/InstanceQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/InstanceQueryService.kt index 79e6b213..b735273b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/query/InstanceQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/query/InstanceQueryService.kt @@ -3,5 +3,5 @@ package dev.usbharu.hideout.core.query import dev.usbharu.hideout.core.domain.model.instance.Instance interface InstanceQueryService { - suspend fun findByUrl(url: String): Instance + suspend fun findByUrl(url: String): Instance? } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/MediaQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/MediaQueryService.kt index 876c2f1e..1a0e5e2b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/query/MediaQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/query/MediaQueryService.kt @@ -4,5 +4,5 @@ import dev.usbharu.hideout.core.domain.model.media.Media interface MediaQueryService { suspend fun findByPostId(postId: Long): List - suspend fun findByRemoteUrl(remoteUrl: String): Media + suspend fun findByRemoteUrl(remoteUrl: String): Media? } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/PostQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/PostQueryService.kt index 64999e89..dcf7d6b1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/query/PostQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/query/PostQueryService.kt @@ -5,8 +5,8 @@ import org.springframework.stereotype.Repository @Repository interface PostQueryService { - suspend fun findById(id: Long): Post - suspend fun findByUrl(url: String): Post - suspend fun findByApId(string: String): Post + suspend fun findById(id: Long): Post? + suspend fun findByUrl(url: String): Post? + suspend fun findByApId(string: String): Post? suspend fun findByActorId(actorId: Long): List } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/ReactionQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/ReactionQueryService.kt index ece7b040..091af139 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/query/ReactionQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/query/ReactionQueryService.kt @@ -8,7 +8,7 @@ interface ReactionQueryService { suspend fun findByPostId(postId: Long, actorId: Long? = null): List @Suppress("FunctionMaxLength") - suspend fun findByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Reaction + suspend fun findByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Reaction? suspend fun reactionAlreadyExist(postId: Long, actorId: Long, emojiId: Long): Boolean diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceService.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceService.kt index d06e53ad..a3e4cecb 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceService.kt @@ -1,7 +1,6 @@ package dev.usbharu.hideout.core.service.instance import com.fasterxml.jackson.databind.ObjectMapper -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.instance.Instance import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository import dev.usbharu.hideout.core.domain.model.instance.Nodeinfo @@ -30,13 +29,14 @@ class InstanceServiceImpl( val u = URL(url) val resolveInstanceUrl = u.protocol + "://" + u.host - try { - return instanceQueryService.findByUrl(resolveInstanceUrl) - } catch (e: FailedToGetResourcesException) { - logger.info("Instance not found. try fetch instance info. url: {}", resolveInstanceUrl) - logger.debug("Failed to get resources. url: {}", resolveInstanceUrl, e) + val instance = instanceQueryService.findByUrl(resolveInstanceUrl) + + if (instance != null) { + return instance } + logger.info("Instance not found. try fetch instance info. url: {}", resolveInstanceUrl) + val nodeinfoJson = resourceResolveService.resolve("$resolveInstanceUrl/.well-known/nodeinfo").bodyAsText() val nodeinfo = objectMapper.readValue(nodeinfoJson, Nodeinfo::class.java) val nodeinfoPathMap = nodeinfo.links.associate { it.rel to it.href } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt index 80d26318..cf6a1113 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt @@ -1,6 +1,5 @@ package dev.usbharu.hideout.core.service.media -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.exception.media.MediaSaveException import dev.usbharu.hideout.core.domain.exception.media.UnsupportedMediaException import dev.usbharu.hideout.core.domain.model.media.Media @@ -102,11 +101,11 @@ class MediaServiceImpl( override suspend fun uploadRemoteMedia(remoteMedia: RemoteMedia): Media { logger.info("MEDIA Remote media. filename:${remoteMedia.name} url:${remoteMedia.url}") - try { - val findByRemoteUrl = mediaQueryService.findByRemoteUrl(remoteMedia.url) + + val findByRemoteUrl = mediaQueryService.findByRemoteUrl(remoteMedia.url) + if (findByRemoteUrl != null) { logger.warn("DUPLICATED Remote media is duplicated. url: {}", remoteMedia.url) return findByRemoteUrl - } catch (_: FailedToGetResourcesException) { } remoteMediaDownloadService.download(remoteMedia.url).withDelete().use { diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt index 0323dc97..a49099bf 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt @@ -1,7 +1,6 @@ package dev.usbharu.hideout.core.service.reaction import dev.usbharu.hideout.activitypub.service.activity.like.APReactionService -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.reaction.Reaction import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository import dev.usbharu.hideout.core.query.ReactionQueryService @@ -29,30 +28,38 @@ class ReactionServiceImpl( override suspend fun receiveRemoveReaction(actorId: Long, postId: Long) { val reaction = reactionQueryService.findByPostIdAndActorIdAndEmojiId(postId, actorId, 0) + if (reaction == null) { + LOGGER.warn("FAILED receive Remove Reaction. $actorId $postId") + return + } reactionRepository.delete(reaction) } override suspend fun sendReaction(name: String, actorId: Long, postId: Long) { - try { - val findByPostIdAndUserIdAndEmojiId = - reactionQueryService.findByPostIdAndActorIdAndEmojiId(postId, actorId, 0) - apReactionService.removeReaction(findByPostIdAndUserIdAndEmojiId) - reactionRepository.delete(findByPostIdAndUserIdAndEmojiId) - } catch (_: FailedToGetResourcesException) { + val findByPostIdAndUserIdAndEmojiId = + reactionQueryService.findByPostIdAndActorIdAndEmojiId(postId, actorId, 0) + + if (findByPostIdAndUserIdAndEmojiId == null) { + LOGGER.warn("FAILED Send reaction. $postId $actorId") + return } + + apReactionService.removeReaction(findByPostIdAndUserIdAndEmojiId) + reactionRepository.delete(findByPostIdAndUserIdAndEmojiId) val reaction = Reaction(reactionRepository.generateId(), 0, postId, actorId) reactionRepository.save(reaction) apReactionService.reaction(reaction) } override suspend fun removeReaction(actorId: Long, postId: Long) { - try { - val findByPostIdAndUserIdAndEmojiId = - reactionQueryService.findByPostIdAndActorIdAndEmojiId(postId, actorId, 0) - reactionRepository.delete(findByPostIdAndUserIdAndEmojiId) - apReactionService.removeReaction(findByPostIdAndUserIdAndEmojiId) - } catch (_: FailedToGetResourcesException) { + val findByPostIdAndUserIdAndEmojiId = + reactionQueryService.findByPostIdAndActorIdAndEmojiId(postId, actorId, 0) + if (findByPostIdAndUserIdAndEmojiId == null) { + LOGGER.warn("FAILED Remove reaction. actorId: $actorId postId: $postId") + return } + reactionRepository.delete(findByPostIdAndUserIdAndEmojiId) + apReactionService.removeReaction(findByPostIdAndUserIdAndEmojiId) } companion object { diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt index f51f5485..6e97f028 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt @@ -2,7 +2,6 @@ package dev.usbharu.hideout.core.service.user import dev.usbharu.hideout.activitypub.service.activity.delete.APSendDeleteService import dev.usbharu.hideout.application.config.ApplicationConfig -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.exception.resource.DuplicateException import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import dev.usbharu.hideout.core.domain.model.actor.Actor @@ -74,11 +73,11 @@ class UserServiceImpl( override suspend fun createRemoteUser(user: RemoteUserCreateDto): Actor { logger.info("START Create New remote user. name: {} url: {}", user.name, user.url) - try { - deletedActorQueryService.findByNameAndDomain(user.name, user.domain) + val deletedActor = deletedActorQueryService.findByNameAndDomain(user.name, user.domain) + + if (deletedActor != null) { logger.warn("FAILED Deleted actor. user: ${user.name} domain: ${user.domain}") throw IllegalStateException("Cannot create Deleted actor.") - } catch (_: FailedToGetResourcesException) { } @Suppress("TooGenericExceptionCaught") diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/AccountQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/AccountQueryServiceImpl.kt index 92f38f09..4cd4ed55 100644 --- a/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/AccountQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/AccountQueryServiceImpl.kt @@ -1,11 +1,9 @@ package dev.usbharu.hideout.mastodon.infrastructure.exposedquery import dev.usbharu.hideout.application.config.ApplicationConfig -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.infrastructure.exposedrepository.Actors import dev.usbharu.hideout.domain.mastodon.model.generated.Account import dev.usbharu.hideout.mastodon.query.AccountQueryService -import dev.usbharu.hideout.util.singleOr import org.jetbrains.exposed.sql.ResultRow import org.jetbrains.exposed.sql.select import org.springframework.stereotype.Repository @@ -13,12 +11,12 @@ import java.time.Instant @Repository class AccountQueryServiceImpl(private val applicationConfig: ApplicationConfig) : AccountQueryService { - override suspend fun findById(accountId: Long): Account { + override suspend fun findById(accountId: Long): Account? { val query = Actors.select { Actors.id eq accountId } return query - .singleOr { FailedToGetResourcesException("accountId: $accountId wad not exist or duplicate", it) } - .let { toAccount(it) } + .singleOrNull() + ?.let { toAccount(it) } } override suspend fun findByIds(accountIds: List): List { diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/query/AccountQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/mastodon/query/AccountQueryService.kt index 37eb2d98..eab3b746 100644 --- a/src/main/kotlin/dev/usbharu/hideout/mastodon/query/AccountQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/mastodon/query/AccountQueryService.kt @@ -3,6 +3,6 @@ package dev.usbharu.hideout.mastodon.query import dev.usbharu.hideout.domain.mastodon.model.generated.Account interface AccountQueryService { - suspend fun findById(accountId: Long): Account + suspend fun findById(accountId: Long): Account? suspend fun findByIds(accountIds: List): List } diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountService.kt b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountService.kt index b3f57aaf..09b55cbd 100644 --- a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountService.kt @@ -14,7 +14,8 @@ interface AccountService { class AccountServiceImpl( private val accountQueryService: AccountQueryService ) : AccountService { - override suspend fun findById(id: Long): Account = accountQueryService.findById(id) + override suspend fun findById(id: Long): Account = + accountQueryService.findById(id) ?: throw IllegalArgumentException("Account $id not found.") override suspend fun findByIds(ids: List): List = accountQueryService.findByIds(ids) } diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt index 53c4326b..ac5a150d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt @@ -53,13 +53,19 @@ class StatsesApiServiceImpl( val account = accountService.findById(userId) val replyUser = if (post.replyId != null) { - actorRepository.findById(postQueryService.findById(post.replyId).actorId)?.id + val findById = postQueryService.findById(post.replyId) + if (findById == null) { + null + } else { + actorRepository.findById(findById.actorId)?.id + } + } else { null } // TODO: n+1解消 - val mediaAttachment = post.mediaIds.map { mediaId -> + val mediaAttachment = post.mediaIds.mapNotNull { mediaId -> mediaRepository.findById(mediaId) }.map { it.toMediaAttachments() From bf4d694aa26434e1b5ef4db3161d98b4ca3f4679 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 21 Dec 2023 11:08:59 +0900 Subject: [PATCH 04/12] =?UTF-8?q?refactor:=20=E4=B8=8D=E8=A6=81=E3=81=AAQu?= =?UTF-8?q?eryService=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/like/APReactionService.kt | 10 ++--- .../service/activity/undo/APUndoProcessor.kt | 8 ++-- .../service/objects/note/APNoteService.kt | 4 +- .../deletedActor/DeletedActorRepository.kt | 1 + .../model/instance/InstanceRepository.kt | 1 + .../domain/model/media/MediaRepository.kt | 1 + .../core/domain/model/post/PostRepository.kt | 4 +- .../model/reaction/ReactionRepository.kt | 4 ++ .../relationship/RelationshipRepository.kt | 11 ++++++ .../DeletedActorQueryServiceImpl.kt | 1 - .../exposedquery/FollowerQueryServiceImpl.kt | 4 +- .../exposedquery/InstanceQueryServiceImpl.kt | 1 - .../exposedquery/MediaQueryServiceImpl.kt | 12 ------ .../exposedquery/PostQueryServiceImpl.kt | 37 ------------------- .../exposedquery/ReactionQueryServiceImpl.kt | 35 ------------------ .../RelationshipQueryServiceImpl.kt | 35 ------------------ .../core/query/DeletedActorQueryService.kt | 7 ---- .../core/query/InstanceQueryService.kt | 7 ---- .../hideout/core/query/MediaQueryService.kt | 8 ---- .../hideout/core/query/PostQueryService.kt | 12 ------ .../core/query/ReactionQueryService.kt | 16 -------- .../core/query/RelationshipQueryService.kt | 18 --------- .../core/service/instance/InstanceService.kt | 6 +-- .../core/service/media/MediaServiceImpl.kt | 6 +-- .../core/service/post/PostServiceImpl.kt | 4 +- .../service/reaction/ReactionServiceImpl.kt | 12 +++--- .../core/service/user/UserServiceImpl.kt | 4 +- .../service/account/AccountApiService.kt | 3 +- .../service/status/StatusesApiService.kt | 8 ++-- .../like/APReactionServiceImplTest.kt | 1 - .../objects/note/APNoteServiceImplTest.kt | 6 --- .../core/service/post/PostServiceImplTest.kt | 1 - .../reaction/ReactionServiceImplTest.kt | 1 - .../core/service/user/ActorServiceTest.kt | 3 -- .../account/AccountApiServiceImplTest.kt | 1 - 35 files changed, 46 insertions(+), 247 deletions(-) delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/PostQueryServiceImpl.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/query/DeletedActorQueryService.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/query/InstanceQueryService.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/query/MediaQueryService.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/query/PostQueryService.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/query/ReactionQueryService.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/query/RelationshipQueryService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt index 7e29a1e4..ae87392c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionService.kt @@ -4,11 +4,11 @@ import com.fasterxml.jackson.databind.ObjectMapper import dev.usbharu.hideout.core.domain.exception.resource.PostNotFoundException import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import dev.usbharu.hideout.core.domain.model.actor.ActorRepository +import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.domain.model.reaction.Reaction import dev.usbharu.hideout.core.external.job.DeliverReactionJob import dev.usbharu.hideout.core.external.job.DeliverRemoveReactionJob import dev.usbharu.hideout.core.query.FollowerQueryService -import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.service.job.JobQueueParentService import org.springframework.beans.factory.annotation.Qualifier import org.springframework.stereotype.Service @@ -22,15 +22,15 @@ interface APReactionService { class APReactionServiceImpl( private val jobQueueParentService: JobQueueParentService, private val followerQueryService: FollowerQueryService, - private val postQueryService: PostQueryService, private val actorRepository: ActorRepository, - @Qualifier("activitypub") private val objectMapper: ObjectMapper + @Qualifier("activitypub") private val objectMapper: ObjectMapper, + private val postRepository: PostRepository ) : APReactionService { override suspend fun reaction(like: Reaction) { val followers = followerQueryService.findFollowersById(like.actorId) val user = actorRepository.findById(like.actorId) ?: throw UserNotFoundException.withId(like.actorId) val post = - postQueryService.findById(like.postId) ?: throw PostNotFoundException.withId(like.postId) + postRepository.findById(like.postId) ?: throw PostNotFoundException.withId(like.postId) followers.forEach { follower -> jobQueueParentService.schedule(DeliverReactionJob) { props[DeliverReactionJob.actor] = user.url @@ -46,7 +46,7 @@ class APReactionServiceImpl( val followers = followerQueryService.findFollowersById(like.actorId) val user = actorRepository.findById(like.actorId) ?: throw UserNotFoundException.withId(like.actorId) val post = - postQueryService.findById(like.postId) ?: throw PostNotFoundException.withId(like.postId) + postRepository.findById(like.postId) ?: throw PostNotFoundException.withId(like.postId) followers.forEach { follower -> jobQueueParentService.schedule(DeliverRemoveReactionJob) { props[DeliverRemoveReactionJob.actor] = user.url 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 index 84eed5fa..84d25edb 100644 --- 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 @@ -11,7 +11,7 @@ import dev.usbharu.hideout.core.domain.exception.resource.PostNotFoundException import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import dev.usbharu.hideout.core.domain.exception.resource.local.LocalUserNotFoundException import dev.usbharu.hideout.core.domain.model.actor.ActorRepository -import dev.usbharu.hideout.core.query.PostQueryService +import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.service.reaction.ReactionService import dev.usbharu.hideout.core.service.relationship.RelationshipService import org.springframework.stereotype.Service @@ -21,9 +21,9 @@ class APUndoProcessor( transaction: Transaction, private val apUserService: APUserService, private val relationshipService: RelationshipService, - private val postQueryService: PostQueryService, private val reactionService: ReactionService, - private val actorRepository: ActorRepository + private val actorRepository: ActorRepository, + private val postRepository: PostRepository ) : AbstractActivityPubProcessor(transaction) { override suspend fun internalProcess(activity: ActivityPubProcessContext) { @@ -81,7 +81,7 @@ class APUndoProcessor( val like = undo.apObject as Like val post = - postQueryService.findByUrl(like.apObject) ?: throw PostNotFoundException.withUrl(like.apObject) + postRepository.findByUrl(like.apObject) ?: throw PostNotFoundException.withUrl(like.apObject) val signer = actorRepository.findById(post.actorId) ?: throw LocalUserNotFoundException.withId(post.actorId) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt index 18a32185..c0c4bea1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt @@ -9,7 +9,6 @@ import dev.usbharu.hideout.activitypub.service.objects.user.APUserService import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.domain.model.post.Visibility -import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.service.media.MediaService import dev.usbharu.hideout.core.service.media.RemoteMedia import dev.usbharu.hideout.core.service.post.PostService @@ -29,7 +28,6 @@ interface APNoteService { class APNoteServiceImpl( private val postRepository: PostRepository, private val apUserService: APUserService, - private val postQueryService: PostQueryService, private val postService: PostService, private val apResourceResolveService: APResourceResolveService, private val postBuilder: Post.PostBuilder, @@ -97,7 +95,7 @@ class APNoteServiceImpl( val reply = note.inReplyTo?.let { fetchNote(it, targetActor) - postQueryService.findByUrl(it) + postRepository.findByUrl(it) } val mediaList = note.attachment.map { diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActorRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActorRepository.kt index 1c5a291e..0a9bb6c2 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActorRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActorRepository.kt @@ -4,4 +4,5 @@ interface DeletedActorRepository { suspend fun save(deletedActor: DeletedActor): DeletedActor suspend fun delete(deletedActor: DeletedActor) suspend fun findById(id: Long): DeletedActor? + suspend fun findByNameAndDomain(name: String, domain: String): DeletedActor? } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/InstanceRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/InstanceRepository.kt index 9883cb35..c9ada9ff 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/InstanceRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/InstanceRepository.kt @@ -5,4 +5,5 @@ interface InstanceRepository { suspend fun save(instance: Instance): Instance suspend fun findById(id: Long): Instance? suspend fun delete(instance: Instance) + suspend fun findByUrl(url:String):Instance? } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/media/MediaRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/media/MediaRepository.kt index b5e2abb2..7f1bd6cf 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/media/MediaRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/media/MediaRepository.kt @@ -5,4 +5,5 @@ interface MediaRepository { suspend fun save(media: Media): Media suspend fun findById(id: Long): Media? suspend fun delete(id: Long) + suspend fun findByRemoteUrl(remoteUrl: String): Media? } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/PostRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/PostRepository.kt index 60384aee..004be864 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/PostRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/PostRepository.kt @@ -10,10 +10,8 @@ interface PostRepository { suspend fun delete(id: Long) suspend fun findById(id: Long): Post? suspend fun findByUrl(url: String): Post? - suspend fun findByUrl2(url: String): Post? { - throw Exception() - } suspend fun findByApId(apId: String): Post? suspend fun existByApIdWithLock(apId: String): Boolean + suspend fun findByActorId(actorId: Long): List } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt index 64b324ff..ae8cad08 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt @@ -9,4 +9,8 @@ interface ReactionRepository { suspend fun delete(reaction: Reaction): Reaction suspend fun deleteByPostId(postId: Long): Int suspend fun deleteByActorId(actorId: Long): Int + suspend fun findByPostId(postId: Long): List + suspend fun findByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Reaction? + suspend fun existByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Boolean + suspend fun findByPostIdAndActorId(postId: Long, actorId: Long): List } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt index 6335a878..4496f146 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt @@ -30,4 +30,15 @@ interface RelationshipRepository { suspend fun findByUserIdAndTargetUserId(actorId: Long, targetActorId: Long): Relationship? suspend fun deleteByActorIdOrTargetActorId(actorId: Long, targetActorId: Long) + + suspend fun findByTargetIdAndFollowing(targetId: Long,following:Boolean):List + + suspend fun findByTargetIdAndFollowRequestAndIgnoreFollowRequest( + maxId: Long?, + sinceId: Long?, + limit: Int, + targetId: Long, + followRequest: Boolean, + ignoreFollowRequest: Boolean + ): List } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/DeletedActorQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/DeletedActorQueryServiceImpl.kt index a5518867..040e6482 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/DeletedActorQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/DeletedActorQueryServiceImpl.kt @@ -3,7 +3,6 @@ package dev.usbharu.hideout.core.infrastructure.exposedquery import dev.usbharu.hideout.core.domain.model.deletedActor.DeletedActor import dev.usbharu.hideout.core.infrastructure.exposedrepository.DeletedActors import dev.usbharu.hideout.core.infrastructure.exposedrepository.toDeletedActor -import dev.usbharu.hideout.core.query.DeletedActorQueryService import org.jetbrains.exposed.sql.and import org.jetbrains.exposed.sql.select import org.springframework.stereotype.Repository diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/FollowerQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/FollowerQueryServiceImpl.kt index 9c841f15..fde53cd3 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/FollowerQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/FollowerQueryServiceImpl.kt @@ -4,18 +4,16 @@ import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository import dev.usbharu.hideout.core.query.FollowerQueryService -import dev.usbharu.hideout.core.query.RelationshipQueryService import org.springframework.stereotype.Repository @Repository class FollowerQueryServiceImpl( - private val relationshipQueryService: RelationshipQueryService, private val relationshipRepository: RelationshipRepository, private val actorRepository: ActorRepository ) : FollowerQueryService { override suspend fun findFollowersById(id: Long): List { return actorRepository.findByIds( - relationshipQueryService.findByTargetIdAndFollowing(id, true).map { it.actorId } + relationshipRepository.findByTargetIdAndFollowing(id, true).map { it.actorId } ) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/InstanceQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/InstanceQueryServiceImpl.kt index 9c518904..7c152b8b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/InstanceQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/InstanceQueryServiceImpl.kt @@ -2,7 +2,6 @@ package dev.usbharu.hideout.core.infrastructure.exposedquery import dev.usbharu.hideout.core.infrastructure.exposedrepository.Instance import dev.usbharu.hideout.core.infrastructure.exposedrepository.toInstance -import dev.usbharu.hideout.core.query.InstanceQueryService import org.jetbrains.exposed.sql.select import org.springframework.stereotype.Repository import dev.usbharu.hideout.core.domain.model.instance.Instance as InstanceEntity diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt index f4b777aa..2e2f9182 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt @@ -1,25 +1,13 @@ package dev.usbharu.hideout.core.infrastructure.exposedquery import dev.usbharu.hideout.core.infrastructure.exposedrepository.Media -import dev.usbharu.hideout.core.infrastructure.exposedrepository.PostsMedia import dev.usbharu.hideout.core.infrastructure.exposedrepository.toMedia -import dev.usbharu.hideout.core.query.MediaQueryService -import org.jetbrains.exposed.sql.innerJoin import org.jetbrains.exposed.sql.select import org.springframework.stereotype.Repository import dev.usbharu.hideout.core.domain.model.media.Media as MediaEntity @Repository class MediaQueryServiceImpl : MediaQueryService { - override suspend fun findByPostId(postId: Long): List { - return Media.innerJoin( - PostsMedia, - onColumn = { id }, - otherColumn = { mediaId } - ) - .select { PostsMedia.postId eq postId } - .map { it.toMedia() } - } override suspend fun findByRemoteUrl(remoteUrl: String): MediaEntity? { return Media.select { Media.remoteUrl eq remoteUrl }.forUpdate() diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/PostQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/PostQueryServiceImpl.kt deleted file mode 100644 index c69027e9..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/PostQueryServiceImpl.kt +++ /dev/null @@ -1,37 +0,0 @@ -package dev.usbharu.hideout.core.infrastructure.exposedquery - -import dev.usbharu.hideout.application.infrastructure.exposed.QueryMapper -import dev.usbharu.hideout.application.infrastructure.exposed.ResultRowMapper -import dev.usbharu.hideout.core.domain.model.post.Post -import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts -import dev.usbharu.hideout.core.infrastructure.exposedrepository.PostsMedia -import dev.usbharu.hideout.core.query.PostQueryService -import org.jetbrains.exposed.sql.select -import org.springframework.stereotype.Repository - -@Repository -class PostQueryServiceImpl( - private val postResultRowMapper: ResultRowMapper, - private val postQueryMapper: QueryMapper -) : PostQueryService { - override suspend fun findById(id: Long): Post? = - Posts.leftJoin(PostsMedia) - .select { Posts.id eq id } - .singleOrNull() - ?.let(postResultRowMapper::map) - - override suspend fun findByUrl(url: String): Post? = - Posts.leftJoin(PostsMedia) - .select { Posts.url eq url } - .let(postQueryMapper::map) - .singleOrNull() - - override suspend fun findByApId(string: String): Post? = - Posts.leftJoin(PostsMedia) - .select { Posts.apId eq string } - .let(postQueryMapper::map) - .singleOrNull() - - override suspend fun findByActorId(actorId: Long): List = - Posts.leftJoin(PostsMedia).select { Posts.actorId eq actorId }.let(postQueryMapper::map) -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ReactionQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ReactionQueryServiceImpl.kt index 349de146..6cdd901b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ReactionQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ReactionQueryServiceImpl.kt @@ -1,43 +1,8 @@ package dev.usbharu.hideout.core.infrastructure.exposedquery -import dev.usbharu.hideout.core.domain.model.reaction.Reaction -import dev.usbharu.hideout.core.infrastructure.exposedrepository.Reactions -import dev.usbharu.hideout.core.infrastructure.exposedrepository.toReaction -import dev.usbharu.hideout.core.query.ReactionQueryService -import org.jetbrains.exposed.sql.and -import org.jetbrains.exposed.sql.select import org.springframework.stereotype.Repository @Repository class ReactionQueryServiceImpl : ReactionQueryService { - override suspend fun findByPostId(postId: Long, actorId: Long?): List { - return Reactions.select { - Reactions.postId.eq(postId) - }.map { it.toReaction() } - } - @Suppress("FunctionMaxLength") - override suspend fun findByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Reaction? { - return Reactions - .select { - Reactions.postId.eq(postId).and(Reactions.actorId.eq(actorId)).and( - Reactions.emojiId.eq(emojiId) - ) - } - .singleOrNull() - ?.toReaction() - } - - override suspend fun reactionAlreadyExist(postId: Long, actorId: Long, emojiId: Long): Boolean { - return Reactions.select { - Reactions.postId.eq(postId).and(Reactions.actorId.eq(actorId)).and( - Reactions.emojiId.eq(emojiId) - ) - }.empty().not() - } - - override suspend fun findByPostIdAndActorId(postId: Long, actorId: Long): List { - return Reactions.select { Reactions.postId eq postId and (Reactions.actorId eq actorId) } - .map { it.toReaction() } - } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/RelationshipQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/RelationshipQueryServiceImpl.kt index 43d8206a..5e5a8407 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/RelationshipQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/RelationshipQueryServiceImpl.kt @@ -1,43 +1,8 @@ package dev.usbharu.hideout.core.infrastructure.exposedquery -import dev.usbharu.hideout.core.domain.model.relationship.Relationship -import dev.usbharu.hideout.core.domain.model.relationship.Relationships -import dev.usbharu.hideout.core.domain.model.relationship.toRelationships -import dev.usbharu.hideout.core.query.RelationshipQueryService -import org.jetbrains.exposed.sql.and -import org.jetbrains.exposed.sql.andWhere -import org.jetbrains.exposed.sql.select import org.springframework.stereotype.Service @Service class RelationshipQueryServiceImpl : RelationshipQueryService { - override suspend fun findByTargetIdAndFollowing(targetId: Long, following: Boolean): List = - Relationships.select { Relationships.targetActorId eq targetId and (Relationships.following eq following) } - .map { it.toRelationships() } - override suspend fun findByTargetIdAndFollowRequestAndIgnoreFollowRequest( - maxId: Long?, - sinceId: Long?, - limit: Int, - targetId: Long, - followRequest: Boolean, - ignoreFollowRequest: Boolean - ): List { - val query = Relationships - .select { - Relationships.targetActorId.eq(targetId) - .and(Relationships.followRequest.eq(followRequest)) - .and(Relationships.ignoreFollowRequestFromTarget.eq(ignoreFollowRequest)) - }.limit(limit) - - if (maxId != null) { - query.andWhere { Relationships.id greater maxId } - } - - if (sinceId != null) { - query.andWhere { Relationships.id less sinceId } - } - - return query.map { it.toRelationships() } - } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/DeletedActorQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/DeletedActorQueryService.kt deleted file mode 100644 index e7dd164d..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/query/DeletedActorQueryService.kt +++ /dev/null @@ -1,7 +0,0 @@ -package dev.usbharu.hideout.core.query - -import dev.usbharu.hideout.core.domain.model.deletedActor.DeletedActor - -interface DeletedActorQueryService { - suspend fun findByNameAndDomain(name: String, domain: String): DeletedActor? -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/InstanceQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/InstanceQueryService.kt deleted file mode 100644 index b735273b..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/query/InstanceQueryService.kt +++ /dev/null @@ -1,7 +0,0 @@ -package dev.usbharu.hideout.core.query - -import dev.usbharu.hideout.core.domain.model.instance.Instance - -interface InstanceQueryService { - suspend fun findByUrl(url: String): Instance? -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/MediaQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/MediaQueryService.kt deleted file mode 100644 index 1a0e5e2b..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/query/MediaQueryService.kt +++ /dev/null @@ -1,8 +0,0 @@ -package dev.usbharu.hideout.core.query - -import dev.usbharu.hideout.core.domain.model.media.Media - -interface MediaQueryService { - suspend fun findByPostId(postId: Long): List - suspend fun findByRemoteUrl(remoteUrl: String): Media? -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/PostQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/PostQueryService.kt deleted file mode 100644 index dcf7d6b1..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/query/PostQueryService.kt +++ /dev/null @@ -1,12 +0,0 @@ -package dev.usbharu.hideout.core.query - -import dev.usbharu.hideout.core.domain.model.post.Post -import org.springframework.stereotype.Repository - -@Repository -interface PostQueryService { - suspend fun findById(id: Long): Post? - suspend fun findByUrl(url: String): Post? - suspend fun findByApId(string: String): Post? - suspend fun findByActorId(actorId: Long): List -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/ReactionQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/ReactionQueryService.kt deleted file mode 100644 index 091af139..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/query/ReactionQueryService.kt +++ /dev/null @@ -1,16 +0,0 @@ -package dev.usbharu.hideout.core.query - -import dev.usbharu.hideout.core.domain.model.reaction.Reaction -import org.springframework.stereotype.Repository - -@Repository -interface ReactionQueryService { - suspend fun findByPostId(postId: Long, actorId: Long? = null): List - - @Suppress("FunctionMaxLength") - suspend fun findByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Reaction? - - suspend fun reactionAlreadyExist(postId: Long, actorId: Long, emojiId: Long): Boolean - - suspend fun findByPostIdAndActorId(postId: Long, actorId: Long): List -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/RelationshipQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/RelationshipQueryService.kt deleted file mode 100644 index c7b2fb18..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/query/RelationshipQueryService.kt +++ /dev/null @@ -1,18 +0,0 @@ -package dev.usbharu.hideout.core.query - -import dev.usbharu.hideout.core.domain.model.relationship.Relationship - -interface RelationshipQueryService { - - suspend fun findByTargetIdAndFollowing(targetId: Long, following: Boolean): List - - @Suppress("LongParameterList", "FunctionMaxLength") - suspend fun findByTargetIdAndFollowRequestAndIgnoreFollowRequest( - maxId: Long?, - sinceId: Long?, - limit: Int, - targetId: Long, - followRequest: Boolean, - ignoreFollowRequest: Boolean - ): List -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceService.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceService.kt index a3e4cecb..318db8ff 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceService.kt @@ -5,7 +5,6 @@ import dev.usbharu.hideout.core.domain.model.instance.Instance import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository import dev.usbharu.hideout.core.domain.model.instance.Nodeinfo import dev.usbharu.hideout.core.domain.model.instance.Nodeinfo2_0 -import dev.usbharu.hideout.core.query.InstanceQueryService import dev.usbharu.hideout.core.service.resource.ResourceResolveService import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Qualifier @@ -22,14 +21,13 @@ interface InstanceService { class InstanceServiceImpl( private val instanceRepository: InstanceRepository, private val resourceResolveService: ResourceResolveService, - @Qualifier("activitypub") private val objectMapper: ObjectMapper, - private val instanceQueryService: InstanceQueryService + @Qualifier("activitypub") private val objectMapper: ObjectMapper ) : InstanceService { override suspend fun fetchInstance(url: String, sharedInbox: String?): Instance { val u = URL(url) val resolveInstanceUrl = u.protocol + "://" + u.host - val instance = instanceQueryService.findByUrl(resolveInstanceUrl) + val instance = instanceRepository.findByUrl(resolveInstanceUrl) if (instance != null) { return instance diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt index cf6a1113..1bcf9c69 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt @@ -4,7 +4,6 @@ import dev.usbharu.hideout.core.domain.exception.media.MediaSaveException import dev.usbharu.hideout.core.domain.exception.media.UnsupportedMediaException import dev.usbharu.hideout.core.domain.model.media.Media import dev.usbharu.hideout.core.domain.model.media.MediaRepository -import dev.usbharu.hideout.core.query.MediaQueryService import dev.usbharu.hideout.core.service.media.converter.MediaProcessService import dev.usbharu.hideout.mastodon.interfaces.api.media.MediaRequest import dev.usbharu.hideout.util.withDelete @@ -23,8 +22,7 @@ class MediaServiceImpl( private val mediaRepository: MediaRepository, private val mediaProcessServices: List, private val remoteMediaDownloadService: RemoteMediaDownloadService, - private val renameService: MediaFileRenameService, - private val mediaQueryService: MediaQueryService + private val renameService: MediaFileRenameService ) : MediaService { @Suppress("LongMethod", "NestedBlockDepth") override suspend fun uploadLocalMedia(mediaRequest: MediaRequest): EntityMedia { @@ -102,7 +100,7 @@ class MediaServiceImpl( logger.info("MEDIA Remote media. filename:${remoteMedia.name} url:${remoteMedia.url}") - val findByRemoteUrl = mediaQueryService.findByRemoteUrl(remoteMedia.url) + val findByRemoteUrl = mediaRepository.findByRemoteUrl(remoteMedia.url) if (findByRemoteUrl != null) { logger.warn("DUPLICATED Remote media is duplicated. url: {}", remoteMedia.url) return findByRemoteUrl diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt index 72e9fdd9..52211b17 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt @@ -9,7 +9,6 @@ import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository -import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.service.timeline.TimelineService import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -20,7 +19,6 @@ class PostServiceImpl( private val postRepository: PostRepository, private val actorRepository: ActorRepository, private val timelineService: TimelineService, - private val postQueryService: PostQueryService, private val postBuilder: Post.PostBuilder, private val apSendCreateService: ApSendCreateService, private val reactionRepository: ReactionRepository @@ -69,7 +67,7 @@ class PostServiceImpl( } override suspend fun deleteByActor(actorId: Long) { - postQueryService.findByActorId(actorId).filterNot { it.delted }.forEach { postRepository.save(it.delete()) } + postRepository.findByActorId(actorId).filterNot { it.delted }.forEach { postRepository.save(it.delete()) } val actor = actorRepository.findById(actorId) ?: throw IllegalStateException("actor: $actorId was not found.") diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt index a49099bf..7830aa98 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt @@ -3,7 +3,6 @@ package dev.usbharu.hideout.core.service.reaction import dev.usbharu.hideout.activitypub.service.activity.like.APReactionService import dev.usbharu.hideout.core.domain.model.reaction.Reaction import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository -import dev.usbharu.hideout.core.query.ReactionQueryService import org.jetbrains.exposed.exceptions.ExposedSQLException import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -12,11 +11,10 @@ import org.springframework.stereotype.Service @Service class ReactionServiceImpl( private val reactionRepository: ReactionRepository, - private val apReactionService: APReactionService, - private val reactionQueryService: ReactionQueryService + private val apReactionService: APReactionService ) : ReactionService { override suspend fun receiveReaction(name: String, domain: String, actorId: Long, postId: Long) { - if (reactionQueryService.reactionAlreadyExist(postId, actorId, 0).not()) { + if (reactionRepository.existByPostIdAndActorIdAndEmojiId(postId, actorId, 0).not()) { try { reactionRepository.save( Reaction(reactionRepository.generateId(), 0, postId, actorId) @@ -27,7 +25,7 @@ class ReactionServiceImpl( } override suspend fun receiveRemoveReaction(actorId: Long, postId: Long) { - val reaction = reactionQueryService.findByPostIdAndActorIdAndEmojiId(postId, actorId, 0) + val reaction = reactionRepository.findByPostIdAndActorIdAndEmojiId(postId, actorId, 0) if (reaction == null) { LOGGER.warn("FAILED receive Remove Reaction. $actorId $postId") return @@ -37,7 +35,7 @@ class ReactionServiceImpl( override suspend fun sendReaction(name: String, actorId: Long, postId: Long) { val findByPostIdAndUserIdAndEmojiId = - reactionQueryService.findByPostIdAndActorIdAndEmojiId(postId, actorId, 0) + reactionRepository.findByPostIdAndActorIdAndEmojiId(postId, actorId, 0) if (findByPostIdAndUserIdAndEmojiId == null) { LOGGER.warn("FAILED Send reaction. $postId $actorId") @@ -53,7 +51,7 @@ class ReactionServiceImpl( override suspend fun removeReaction(actorId: Long, postId: Long) { val findByPostIdAndUserIdAndEmojiId = - reactionQueryService.findByPostIdAndActorIdAndEmojiId(postId, actorId, 0) + reactionRepository.findByPostIdAndActorIdAndEmojiId(postId, actorId, 0) if (findByPostIdAndUserIdAndEmojiId == null) { LOGGER.warn("FAILED Remove reaction. actorId: $actorId postId: $postId") return diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt index 6e97f028..df4b4fd6 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt @@ -12,7 +12,6 @@ import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository -import dev.usbharu.hideout.core.query.DeletedActorQueryService import dev.usbharu.hideout.core.service.instance.InstanceService import dev.usbharu.hideout.core.service.post.PostService import org.slf4j.LoggerFactory @@ -29,7 +28,6 @@ class UserServiceImpl( private val instanceService: InstanceService, private val userDetailRepository: UserDetailRepository, private val deletedActorRepository: DeletedActorRepository, - private val deletedActorQueryService: DeletedActorQueryService, private val reactionRepository: ReactionRepository, private val relationshipRepository: RelationshipRepository, private val postService: PostService, @@ -73,7 +71,7 @@ class UserServiceImpl( override suspend fun createRemoteUser(user: RemoteUserCreateDto): Actor { logger.info("START Create New remote user. name: {} url: {}", user.name, user.url) - val deletedActor = deletedActorQueryService.findByNameAndDomain(user.name, user.domain) + val deletedActor = deletedActorRepository.findByNameAndDomain(user.name, user.domain) if (deletedActor != null) { logger.warn("FAILED Deleted actor. user: ${user.name} domain: ${user.domain}") diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiService.kt b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiService.kt index 98cfdb3e..67fa42d1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiService.kt @@ -2,7 +2,6 @@ package dev.usbharu.hideout.mastodon.service.account import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository -import dev.usbharu.hideout.core.query.RelationshipQueryService import dev.usbharu.hideout.core.service.media.MediaService import dev.usbharu.hideout.core.service.relationship.RelationshipService import dev.usbharu.hideout.core.service.user.UpdateUserDto @@ -221,7 +220,7 @@ class AccountApiServiceImpl( limit: Int, withIgnore: Boolean ): List = transaction.transaction { - val actorIdList = relationshipQueryService + val actorIdList = relationshipRepository .findByTargetIdAndFollowRequestAndIgnoreFollowRequest( maxId = maxId, sinceId = sinceId, diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt index ac5a150d..c51aca0c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt @@ -4,7 +4,7 @@ import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.media.MediaRepository import dev.usbharu.hideout.core.domain.model.media.toMediaAttachments -import dev.usbharu.hideout.core.query.PostQueryService +import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.service.post.PostCreateDto import dev.usbharu.hideout.core.service.post.PostService import dev.usbharu.hideout.domain.mastodon.model.generated.Status @@ -28,10 +28,10 @@ interface StatusesApiService { class StatsesApiServiceImpl( private val postService: PostService, private val accountService: AccountService, - private val postQueryService: PostQueryService, private val mediaRepository: MediaRepository, private val transaction: Transaction, - private val actorRepository: ActorRepository + private val actorRepository: ActorRepository, + private val postRepository: PostRepository ) : StatusesApiService { override suspend fun postStatus( @@ -53,7 +53,7 @@ class StatsesApiServiceImpl( val account = accountService.findById(userId) val replyUser = if (post.replyId != null) { - val findById = postQueryService.findById(post.replyId) + val findById = postRepository.findById(post.replyId) if (findById == null) { null } else { diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionServiceImplTest.kt index 0dd3ae9a..939a4246 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionServiceImplTest.kt @@ -6,7 +6,6 @@ import dev.usbharu.hideout.core.domain.model.reaction.Reaction import dev.usbharu.hideout.core.external.job.DeliverReactionJob import dev.usbharu.hideout.core.external.job.DeliverRemoveReactionJob import dev.usbharu.hideout.core.query.FollowerQueryService -import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.service.job.JobQueueParentService import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Test diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteServiceImplTest.kt index 59978164..fdf19ab2 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteServiceImplTest.kt @@ -16,7 +16,6 @@ import dev.usbharu.hideout.application.service.id.TwitterSnowflakeIdGenerateServ import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.PostRepository -import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.service.post.PostService import io.ktor.client.* import io.ktor.client.call.* @@ -70,7 +69,6 @@ class APNoteServiceImplTest { val apNoteServiceImpl = APNoteServiceImpl( postRepository = mock(), apUserService = mock(), - postQueryService = mock(), postService = mock(), apResourceResolveService = mock(), postBuilder = Post.PostBuilder(CharacterLimit()), @@ -144,7 +142,6 @@ class APNoteServiceImplTest { val apNoteServiceImpl = APNoteServiceImpl( postRepository = postRepository, apUserService = apUserService, - postQueryService = postQueryService, postService = mock(), apResourceResolveService = apResourceResolveService, postBuilder = Post.PostBuilder(CharacterLimit()), @@ -211,7 +208,6 @@ class APNoteServiceImplTest { val apNoteServiceImpl = APNoteServiceImpl( postRepository = mock(), apUserService = mock(), - postQueryService = postQueryService, postService = mock(), apResourceResolveService = apResourceResolveService, postBuilder = Post.PostBuilder(CharacterLimit()), @@ -262,7 +258,6 @@ class APNoteServiceImplTest { val apNoteServiceImpl = APNoteServiceImpl( postRepository = postRepository, apUserService = apUserService, - postQueryService = mock(), postService = postService, apResourceResolveService = mock(), postBuilder = postBuilder, @@ -318,7 +313,6 @@ class APNoteServiceImplTest { val apNoteServiceImpl = APNoteServiceImpl( postRepository = mock(), apUserService = mock(), - postQueryService = mock(), postService = mock(), apResourceResolveService = mock(), postBuilder = postBuilder, diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImplTest.kt index cd43fd90..cd890af2 100644 --- a/src/test/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImplTest.kt @@ -6,7 +6,6 @@ import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository -import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.service.timeline.TimelineService import kotlinx.coroutines.test.runTest import org.assertj.core.api.Assertions.assertThat diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImplTest.kt index 89e4feae..3dc6e04e 100644 --- a/src/test/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImplTest.kt @@ -6,7 +6,6 @@ import dev.usbharu.hideout.application.service.id.TwitterSnowflakeIdGenerateServ import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.reaction.Reaction import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository -import dev.usbharu.hideout.core.query.ReactionQueryService import kotlinx.coroutines.test.runTest import org.jetbrains.exposed.exceptions.ExposedSQLException import org.junit.jupiter.api.Test diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt b/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt index fa1f438d..1d2e089f 100644 --- a/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt @@ -8,7 +8,6 @@ import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.Post -import dev.usbharu.hideout.core.query.DeletedActorQueryService import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Test @@ -43,7 +42,6 @@ class ActorServiceTest { instanceService = mock(), userDetailRepository = mock(), deletedActorRepository = mock(), - deletedActorQueryService = mock(), reactionRepository = mock(), relationshipRepository = mock(), postService = mock(), @@ -89,7 +87,6 @@ class ActorServiceTest { instanceService = mock(), userDetailRepository = mock(), deletedActorRepository = mock(), - deletedActorQueryService = deletedActorQueryService, reactionRepository = mock(), relationshipRepository = mock(), postService = mock(), diff --git a/src/test/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiServiceImplTest.kt index 652997c5..8c264507 100644 --- a/src/test/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiServiceImplTest.kt @@ -4,7 +4,6 @@ import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository import dev.usbharu.hideout.core.query.FollowerQueryService -import dev.usbharu.hideout.core.query.RelationshipQueryService import dev.usbharu.hideout.core.service.media.MediaService import dev.usbharu.hideout.core.service.relationship.RelationshipService import dev.usbharu.hideout.core.service.user.UserService From fddc29bdfd6a16305852842759580f177976b35a Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 21 Dec 2023 11:15:16 +0900 Subject: [PATCH 05/12] =?UTF-8?q?fix:=20=E5=89=8A=E9=99=A4=E3=81=95?= =?UTF-8?q?=E3=82=8C=E3=81=A6=E3=81=84=E3=81=AA=E3=81=8B=E3=81=A3=E3=81=9F?= =?UTF-8?q?=E5=AE=9F=E8=A3=85=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DeletedActorQueryServiceImpl.kt | 18 ------------------ .../exposedquery/InstanceQueryServiceImpl.kt | 13 ------------- .../exposedquery/MediaQueryServiceImpl.kt | 17 ----------------- .../exposedquery/ReactionQueryServiceImpl.kt | 8 -------- .../RelationshipQueryServiceImpl.kt | 8 -------- .../DeletedActorRepositoryImpl.kt | 12 ++++++++++-- .../InstanceRepositoryImpl.kt | 4 ++++ .../exposedrepository/MediaRepositoryImpl.kt | 4 ++++ .../service/account/AccountApiService.kt | 3 +-- 9 files changed, 19 insertions(+), 68 deletions(-) delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/DeletedActorQueryServiceImpl.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/InstanceQueryServiceImpl.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ReactionQueryServiceImpl.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/RelationshipQueryServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/DeletedActorQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/DeletedActorQueryServiceImpl.kt deleted file mode 100644 index 040e6482..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/DeletedActorQueryServiceImpl.kt +++ /dev/null @@ -1,18 +0,0 @@ -package dev.usbharu.hideout.core.infrastructure.exposedquery - -import dev.usbharu.hideout.core.domain.model.deletedActor.DeletedActor -import dev.usbharu.hideout.core.infrastructure.exposedrepository.DeletedActors -import dev.usbharu.hideout.core.infrastructure.exposedrepository.toDeletedActor -import org.jetbrains.exposed.sql.and -import org.jetbrains.exposed.sql.select -import org.springframework.stereotype.Repository - -@Repository -class DeletedActorQueryServiceImpl : DeletedActorQueryService { - override suspend fun findByNameAndDomain(name: String, domain: String): DeletedActor? { - return DeletedActors - .select { DeletedActors.name eq name and (DeletedActors.domain eq domain) } - .singleOrNull() - ?.toDeletedActor() - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/InstanceQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/InstanceQueryServiceImpl.kt deleted file mode 100644 index 7c152b8b..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/InstanceQueryServiceImpl.kt +++ /dev/null @@ -1,13 +0,0 @@ -package dev.usbharu.hideout.core.infrastructure.exposedquery - -import dev.usbharu.hideout.core.infrastructure.exposedrepository.Instance -import dev.usbharu.hideout.core.infrastructure.exposedrepository.toInstance -import org.jetbrains.exposed.sql.select -import org.springframework.stereotype.Repository -import dev.usbharu.hideout.core.domain.model.instance.Instance as InstanceEntity - -@Repository -class InstanceQueryServiceImpl : InstanceQueryService { - override suspend fun findByUrl(url: String): InstanceEntity? = Instance.select { Instance.url eq url } - .singleOrNull()?.toInstance() -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt deleted file mode 100644 index 2e2f9182..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt +++ /dev/null @@ -1,17 +0,0 @@ -package dev.usbharu.hideout.core.infrastructure.exposedquery - -import dev.usbharu.hideout.core.infrastructure.exposedrepository.Media -import dev.usbharu.hideout.core.infrastructure.exposedrepository.toMedia -import org.jetbrains.exposed.sql.select -import org.springframework.stereotype.Repository -import dev.usbharu.hideout.core.domain.model.media.Media as MediaEntity - -@Repository -class MediaQueryServiceImpl : MediaQueryService { - - override suspend fun findByRemoteUrl(remoteUrl: String): MediaEntity? { - return Media.select { Media.remoteUrl eq remoteUrl }.forUpdate() - .singleOrNull() - ?.toMedia() - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ReactionQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ReactionQueryServiceImpl.kt deleted file mode 100644 index 6cdd901b..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/ReactionQueryServiceImpl.kt +++ /dev/null @@ -1,8 +0,0 @@ -package dev.usbharu.hideout.core.infrastructure.exposedquery - -import org.springframework.stereotype.Repository - -@Repository -class ReactionQueryServiceImpl : ReactionQueryService { - -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/RelationshipQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/RelationshipQueryServiceImpl.kt deleted file mode 100644 index 5e5a8407..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/RelationshipQueryServiceImpl.kt +++ /dev/null @@ -1,8 +0,0 @@ -package dev.usbharu.hideout.core.infrastructure.exposedquery - -import org.springframework.stereotype.Service - -@Service -class RelationshipQueryServiceImpl : RelationshipQueryService { - -} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt index 31246dbd..4495e151 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt @@ -38,9 +38,17 @@ class DeletedActorRepositoryImpl : DeletedActorRepository, AbstractRepository() } override suspend fun findById(id: Long): DeletedActor? = query { - return@query DeletedActors.select { DeletedActors.id eq id } + return@query DeletedActors + .select { DeletedActors.id eq id } .singleOrNull() - ?.let { it.toDeletedActor() } + ?.toDeletedActor() + } + + override suspend fun findByNameAndDomain(name: String, domain: String): DeletedActor? = query { + return@query DeletedActors + .select { DeletedActors.name eq name and (DeletedActors.domain eq domain) } + .singleOrNull() + ?.toDeletedActor() } override val logger: Logger diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt index 41aa2535..e375dfe8 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt @@ -54,6 +54,10 @@ class InstanceRepositoryImpl(private val idGenerateService: IdGenerateService) : override suspend fun delete(instance: InstanceEntity) { Instance.deleteWhere { id eq instance.id } } + + override suspend fun findByUrl(url: String): dev.usbharu.hideout.core.domain.model.instance.Instance? { + return Instance.select { Instance.url eq url }.singleOrNull()?.toInstance() + } } fun ResultRow.toInstance(): InstanceEntity { diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt index 3039dc77..19012f6c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt @@ -59,6 +59,10 @@ class MediaRepositoryImpl(private val idGenerateService: IdGenerateService) : Me Media.id eq id } } + + override suspend fun findByRemoteUrl(remoteUrl: String): dev.usbharu.hideout.core.domain.model.media.Media? { + return Media.select { Media.remoteUrl eq remoteUrl }.singleOrNull()?.toMedia() + } } fun ResultRow.toMedia(): EntityMedia { diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiService.kt b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiService.kt index 67fa42d1..0cefb38c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiService.kt @@ -70,8 +70,7 @@ class AccountApiServiceImpl( private val statusQueryService: StatusQueryService, private val relationshipService: RelationshipService, private val relationshipRepository: RelationshipRepository, - private val mediaService: MediaService, - private val relationshipQueryService: RelationshipQueryService + private val mediaService: MediaService ) : AccountApiService { override suspend fun accountsStatuses( From e3a819f94d29f947ecc970d8e6c4be5f0242dbfe Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 21 Dec 2023 11:27:46 +0900 Subject: [PATCH 06/12] =?UTF-8?q?feat:=20=E6=9C=AA=E5=AE=9F=E8=A3=85?= =?UTF-8?q?=E9=A0=85=E7=9B=AE=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RelationshipRepositoryImpl.kt | 30 +++++++++++++++++++ .../exposedrepository/PostRepositoryImpl.kt | 4 +++ .../ReactionRepositoryImpl.kt | 22 ++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt index 57610d1d..8dea030a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt @@ -63,6 +63,36 @@ class RelationshipRepositoryImpl : RelationshipRepository { Relationships.actorId.eq(actorId).or(Relationships.targetActorId.eq(targetActorId)) } } + + override suspend fun findByTargetIdAndFollowing(targetId: Long, following: Boolean): List { + return Relationships.select { Relationships.targetActorId eq targetId and (Relationships.following eq following) } + .map { it.toRelationships() } + } + + override suspend fun findByTargetIdAndFollowRequestAndIgnoreFollowRequest( + maxId: Long?, + sinceId: Long?, + limit: Int, + targetId: Long, + followRequest: Boolean, + ignoreFollowRequest: Boolean + ): List { + val query = Relationships.select { + Relationships.targetActorId.eq(targetId) + .and(Relationships.followRequest.eq(followRequest)) + .and(Relationships.ignoreFollowRequestFromTarget.eq(ignoreFollowRequest)) + }.limit(limit) + + if (maxId != null) { + query.andWhere { Relationships.id lessEq maxId } + } + + if (sinceId != null) { + query.andWhere { Relationships.id greaterEq sinceId } + } + + return query.map { it.toRelationships() } + } } fun ResultRow.toRelationships(): Relationship = Relationship( diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt index 6716268a..c8e88d96 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt @@ -89,6 +89,10 @@ class PostRepositoryImpl( return@query Posts.select { Posts.apId eq apId }.forUpdate().empty().not() } + override suspend fun findByActorId(actorId: Long): List = query { + return@query Posts.select { Posts.actorId eq actorId }.let(postQueryMapper::map) + } + override suspend fun delete(id: Long): Unit = query { Posts.deleteWhere { Posts.id eq id } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt index 0b14d787..d39f996d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt @@ -54,6 +54,28 @@ class ReactionRepositoryImpl( Reactions.actorId eq actorId } } + + override suspend fun findByPostId(postId: Long): List { + return Reactions.select { Reactions.postId eq postId }.map { it.toReaction() } + } + + override suspend fun findByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Reaction? { + return Reactions.select { + Reactions.postId eq postId and (Reactions.actorId eq actorId).and( + Reactions.emojiId.eq( + emojiId + ) + ) + }.singleOrNull()?.toReaction() + } + + override suspend fun existByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Boolean { + TODO("Not yet implemented") + } + + override suspend fun findByPostIdAndActorId(postId: Long, actorId: Long): List { + TODO("Not yet implemented") + } } fun ResultRow.toReaction(): Reaction { From e7743c77f242d0ed987d4eae9ed74a240f061dbb Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 21 Dec 2023 12:57:06 +0900 Subject: [PATCH 07/12] =?UTF-8?q?test:=20=E3=83=86=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/reaction/ReactionServiceImpl.kt | 9 ++- .../api/actor/ActorAPControllerImplTest.kt | 4 +- .../api/webfinger/WebFingerControllerTest.kt | 11 ++-- .../accept/APDeliverAcceptJobProcessorTest.kt | 5 +- .../activity/accept/ApAcceptProcessorTest.kt | 7 ++- .../create/ApSendCreateServiceImplTest.kt | 5 +- .../like/APReactionServiceImplTest.kt | 20 +++++-- .../objects/note/APNoteServiceImplTest.kt | 41 +++----------- .../core/service/post/PostServiceImplTest.kt | 35 +++--------- .../reaction/ReactionServiceImplTest.kt | 24 ++++---- .../RelationshipServiceImplTest.kt | 56 +++++++++---------- .../service/timeline/TimelineServiceTest.kt | 5 +- .../core/service/user/ActorServiceTest.kt | 10 +--- .../account/AccountApiServiceImplTest.kt | 5 +- 14 files changed, 99 insertions(+), 138 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt index 7830aa98..9d957dc1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt @@ -37,13 +37,12 @@ class ReactionServiceImpl( val findByPostIdAndUserIdAndEmojiId = reactionRepository.findByPostIdAndActorIdAndEmojiId(postId, actorId, 0) - if (findByPostIdAndUserIdAndEmojiId == null) { - LOGGER.warn("FAILED Send reaction. $postId $actorId") - return + if (findByPostIdAndUserIdAndEmojiId != null) { + apReactionService.removeReaction(findByPostIdAndUserIdAndEmojiId) + reactionRepository.delete(findByPostIdAndUserIdAndEmojiId) } - apReactionService.removeReaction(findByPostIdAndUserIdAndEmojiId) - reactionRepository.delete(findByPostIdAndUserIdAndEmojiId) + val reaction = Reaction(reactionRepository.generateId(), 0, postId, actorId) reactionRepository.save(reaction) apReactionService.reaction(reaction) diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/ActorAPControllerImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/ActorAPControllerImplTest.kt index 36cfa4c5..fdb9a65b 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/ActorAPControllerImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/actor/ActorAPControllerImplTest.kt @@ -5,7 +5,7 @@ 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.ActivityPubConfig -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -75,7 +75,7 @@ class ActorAPControllerImplTest { @Test fun `userAP 存在しないユーザーにGETすると404が返ってくる`() = runTest { - whenever(apUserService.getPersonByName(eq("fuga"))).doThrow(FailedToGetResourcesException::class) + whenever(apUserService.getPersonByName(eq("fuga"))).doThrow(UserNotFoundException::class) mockMvc .get("/users/fuga") diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/webfinger/WebFingerControllerTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/webfinger/WebFingerControllerTest.kt index 41017444..7e038487 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/webfinger/WebFingerControllerTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/webfinger/WebFingerControllerTest.kt @@ -5,7 +5,7 @@ import com.fasterxml.jackson.module.kotlin.readValue import dev.usbharu.hideout.activitypub.domain.model.webfinger.WebFinger import dev.usbharu.hideout.activitypub.service.webfinger.WebFingerApiService import dev.usbharu.hideout.application.config.ApplicationConfig -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.domain.exception.resource.UserNotFoundException import kotlinx.coroutines.test.runTest import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.BeforeEach @@ -82,9 +82,12 @@ class WebFingerControllerTest { @Test fun `webfinger 存在しないacctを指定したとき404 Not Foundが返ってくる`() = runTest { - whenever(webFingerApiService.findByNameAndDomain(eq("fuga"), eq("example.com"))).doThrow( - FailedToGetResourcesException::class - ) + whenever( + webFingerApiService.findByNameAndDomain( + eq("fuga"), + eq("example.com") + ) + ).doThrow(UserNotFoundException::class) mockMvc.perform(get("/.well-known/webfinger?resource=acct:fuga@example.com")) .andDo(print()) diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessorTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessorTest.kt index d89fbe6d..336e1bf6 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessorTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APDeliverAcceptJobProcessorTest.kt @@ -3,6 +3,7 @@ package dev.usbharu.hideout.activitypub.service.activity.accept 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.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.external.job.DeliverAcceptJob import dev.usbharu.hideout.core.external.job.DeliverAcceptJobParam import kotlinx.coroutines.test.runTest @@ -24,7 +25,7 @@ class APDeliverAcceptJobProcessorTest { private lateinit var apRequestService: APRequestService @Mock - private lateinit var actorQueryService: ActorQueryService + private lateinit var actorRepository: ActorRepository @Mock private lateinit var deliverAcceptJob: DeliverAcceptJob @@ -39,7 +40,7 @@ class APDeliverAcceptJobProcessorTest { fun `process apPostが発行される`() = runTest { val user = UserBuilder.localUserOf() - whenever(actorQueryService.findById(eq(1))).doReturn(user) + whenever(actorRepository.findById(eq(1))).doReturn(user) val accept = Accept( apObject = Follow( diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessorTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessorTest.kt index d9b8f24e..c7ac9bde 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessorTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/ApAcceptProcessorTest.kt @@ -7,6 +7,7 @@ import dev.usbharu.hideout.activitypub.domain.model.Like import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessContext import dev.usbharu.hideout.activitypub.service.common.ActivityType import dev.usbharu.hideout.application.config.ActivityPubConfig +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.service.relationship.RelationshipService import dev.usbharu.httpsignature.common.HttpHeaders import dev.usbharu.httpsignature.common.HttpMethod @@ -33,7 +34,7 @@ import java.net.URL class ApAcceptProcessorTest { @Mock - private lateinit var actorQueryService: ActorQueryService + private lateinit var actorRepository: ActorRepository @Mock private lateinit var relationshipService: RelationshipService @@ -66,9 +67,9 @@ class ApAcceptProcessorTest { ) val user = UserBuilder.localUserOf() - whenever(actorQueryService.findByUrl(eq("https://example.com"))).doReturn(user) + whenever(actorRepository.findByUrl(eq("https://example.com"))).doReturn(user) val remoteUser = UserBuilder.remoteUserOf() - whenever(actorQueryService.findByUrl(eq("https://remote.example.com"))).doReturn(remoteUser) + whenever(actorRepository.findByUrl(eq("https://remote.example.com"))).doReturn(remoteUser) apAcceptProcessor.internalProcess(activity) diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImplTest.kt index 0f5ec6f8..24cdbf1b 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/ApSendCreateServiceImplTest.kt @@ -6,6 +6,7 @@ import dev.usbharu.hideout.activitypub.query.NoteQueryService import dev.usbharu.hideout.activitypub.service.objects.note.APNoteServiceImpl import dev.usbharu.hideout.application.config.ActivityPubConfig import dev.usbharu.hideout.application.config.ApplicationConfig +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.external.job.DeliverPostJob import dev.usbharu.hideout.core.query.FollowerQueryService import dev.usbharu.hideout.core.service.job.JobQueueParentService @@ -35,7 +36,7 @@ class ApSendCreateServiceImplTest { private lateinit var jobQueueParentService: JobQueueParentService @Mock - private lateinit var actorQueryService: ActorQueryService + private lateinit var actorRepository: ActorRepository @Mock private lateinit var noteQueryService: NoteQueryService @@ -67,7 +68,7 @@ class ApSendCreateServiceImplTest { ) whenever(followerQueryService.findFollowersById(eq(post.actorId))).doReturn(followers) - whenever(actorQueryService.findById(eq(post.actorId))).doReturn(user) + whenever(actorRepository.findById(eq(post.actorId))).doReturn(user) whenever(noteQueryService.findById(eq(post.id))).doReturn(note to post) apSendCreateServiceImpl.createNote(post) diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionServiceImplTest.kt index 939a4246..716762b3 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APReactionServiceImplTest.kt @@ -2,6 +2,8 @@ package dev.usbharu.hideout.activitypub.service.activity.like import dev.usbharu.hideout.application.service.id.TwitterSnowflakeIdGenerateService +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository +import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.domain.model.reaction.Reaction import dev.usbharu.hideout.core.external.job.DeliverReactionJob import dev.usbharu.hideout.core.external.job.DeliverRemoveReactionJob @@ -21,7 +23,7 @@ class APReactionServiceImplTest { val user = UserBuilder.localUserOf() val post = PostBuilder.of() - val postQueryService = mock { + val postQueryService = mock { onBlocking { findById(eq(post.id)) } doReturn post } val followerQueryService = mock { @@ -32,11 +34,14 @@ class APReactionServiceImplTest { ) } val jobQueueParentService = mock() + val actorRepository = mock { + onBlocking { findById(eq(user.id)) }.doReturn(user) + } val apReactionServiceImpl = APReactionServiceImpl( jobQueueParentService = jobQueueParentService, - actorQueryService = mock(), + actorRepository = actorRepository, followerQueryService = followerQueryService, - postQueryService = postQueryService, + postRepository = postQueryService, objectMapper = objectMapper ) @@ -58,7 +63,7 @@ class APReactionServiceImplTest { val user = UserBuilder.localUserOf() val post = PostBuilder.of() - val postQueryService = mock { + val postQueryService = mock { onBlocking { findById(eq(post.id)) } doReturn post } val followerQueryService = mock { @@ -69,11 +74,14 @@ class APReactionServiceImplTest { ) } val jobQueueParentService = mock() + val actorRepository = mock { + onBlocking { findById(eq(user.id)) }.doReturn(user) + } val apReactionServiceImpl = APReactionServiceImpl( jobQueueParentService = jobQueueParentService, - actorQueryService = mock(), + actorRepository = actorRepository, followerQueryService = followerQueryService, - postQueryService = postQueryService, + postRepository = postQueryService, objectMapper = objectMapper ) diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteServiceImplTest.kt index fdf19ab2..cece7a5b 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteServiceImplTest.kt @@ -13,7 +13,7 @@ import dev.usbharu.hideout.activitypub.service.objects.note.APNoteServiceImpl.Co import dev.usbharu.hideout.activitypub.service.objects.user.APUserService import dev.usbharu.hideout.application.config.CharacterLimit import dev.usbharu.hideout.application.service.id.TwitterSnowflakeIdGenerateService -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.service.post.PostService @@ -50,7 +50,7 @@ class APNoteServiceImplTest { val post = PostBuilder.of() val user = UserBuilder.localUserOf(id = post.actorId) - val actorQueryService = mock { + val actorQueryService = mock { onBlocking { findById(eq(post.actorId)) } doReturn user } val expected = Note( @@ -86,13 +86,9 @@ class APNoteServiceImplTest { val url = "https://example.com/note" val post = PostBuilder.of() - val postQueryService = mock { - onBlocking { findByApId(eq(post.apId)) } doReturn post - } + val user = UserBuilder.localUserOf(id = post.actorId) - val actorQueryService = mock { - onBlocking { findById(eq(post.actorId)) } doReturn user - } + val note = Note( id = post.apId, attributedTo = user.url, @@ -107,7 +103,7 @@ class APNoteServiceImplTest { onBlocking { resolve(eq(url), any(), isNull()) } doReturn note } val noteQueryService = mock { - onBlocking { findByApid(eq(url)) } doThrow FailedToGetResourcesException() + onBlocking { findByApid(eq(url)) } doReturn null } val person = Person( name = user.name, @@ -132,7 +128,7 @@ class APNoteServiceImplTest { following = user.following, manuallyApprovesFollowers = false - ) + ) val apUserService = mock { onBlocking { fetchPersonWithEntity(eq(note.attributedTo!!), isNull()) } doReturn (person to user) } @@ -159,25 +155,7 @@ class APNoteServiceImplTest { fun `fetchNote(String,String) ノートをリモートから取得した際にエラーが返ってきたらFailedToGetActivityPubResourceExceptionがthrowされる`() = runTest { val url = "https://example.com/note" - val post = PostBuilder.of() - val postQueryService = mock { - onBlocking { findByApId(eq(post.apId)) } doReturn post - } - val user = UserBuilder.localUserOf(id = post.actorId) - val actorQueryService = mock { - onBlocking { findById(eq(post.actorId)) } doReturn user - } - val note = Note( - id = post.apId, - attributedTo = user.url, - content = post.text, - published = Instant.ofEpochMilli(post.createdAt).toString(), - to = listOfNotNull(public, user.followers), - sensitive = post.sensitive, - cc = listOfNotNull(public, user.followers), - inReplyTo = null - ) val apResourceResolveService = mock { val responseData = HttpResponseData( HttpStatusCode.BadRequest, @@ -203,7 +181,7 @@ class APNoteServiceImplTest { ) } val noteQueryService = mock { - onBlocking { findByApid(eq(url)) } doThrow FailedToGetResourcesException() + onBlocking { findByApid(eq(url)) } doReturn null } val apNoteServiceImpl = APNoteServiceImpl( postRepository = mock(), @@ -253,7 +231,7 @@ class APNoteServiceImplTest { } val postService = mock() val noteQueryService = mock { - onBlocking { findByApid(eq(post.apId)) } doThrow FailedToGetResourcesException() + onBlocking { findByApid(eq(post.apId)) } doReturn null } val apNoteServiceImpl = APNoteServiceImpl( postRepository = postRepository, @@ -294,9 +272,6 @@ class APNoteServiceImplTest { val user = UserBuilder.localUserOf() val post = PostBuilder.of(userId = user.id) - val actorQueryService = mock { - onBlocking { findById(eq(user.id)) } doReturn user - } val note = Note( id = post.apId, attributedTo = user.url, diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImplTest.kt index cd890af2..5a76ea07 100644 --- a/src/test/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImplTest.kt @@ -2,6 +2,7 @@ package dev.usbharu.hideout.core.service.post import dev.usbharu.hideout.activitypub.service.activity.create.ApSendCreateService import dev.usbharu.hideout.application.config.CharacterLimit +import dev.usbharu.hideout.core.domain.exception.resource.DuplicateException import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.PostRepository @@ -9,7 +10,6 @@ import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository import dev.usbharu.hideout.core.service.timeline.TimelineService import kotlinx.coroutines.test.runTest import org.assertj.core.api.Assertions.assertThat -import org.jetbrains.exposed.exceptions.ExposedSQLException import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import org.mockito.InjectMocks @@ -19,7 +19,6 @@ import org.mockito.Mockito.mockStatic import org.mockito.Spy import org.mockito.junit.jupiter.MockitoExtension import org.mockito.kotlin.* -import org.springframework.dao.DuplicateKeyException import utils.PostBuilder import utils.UserBuilder import java.time.Instant @@ -35,10 +34,6 @@ class PostServiceImplTest { @Mock private lateinit var timelineService: TimelineService - - @Mock - private lateinit var postQueryService: PostQueryService - @Spy private var postBuilder: Post.PostBuilder = Post.PostBuilder(CharacterLimit()) @@ -57,7 +52,7 @@ class PostServiceImplTest { val now = Instant.now() val post = PostBuilder.of(createdAt = now.toEpochMilli()) - whenever(postRepository.save(eq(post))).doReturn(true) + whenever(postRepository.save(eq(post))).doReturn(post) whenever(postRepository.generateId()).doReturn(post.id) whenever(actorRepository.findById(eq(post.actorId))).doReturn(UserBuilder.localUserOf(id = post.actorId)) whenever(timelineService.publishTimeline(eq(post), eq(true))).doReturn(Unit) @@ -90,7 +85,7 @@ class PostServiceImplTest { val post = PostBuilder.of() whenever(actorRepository.findById(eq(post.actorId))).doReturn(UserBuilder.remoteUserOf(id = post.actorId)) - whenever(postRepository.save(eq(post))).doReturn(true) + whenever(postRepository.save(eq(post))).doReturn(post) whenever(timelineService.publishTimeline(eq(post), eq(false))).doReturn(Unit) @@ -108,23 +103,8 @@ class PostServiceImplTest { val post = PostBuilder.of() whenever(actorRepository.findById(eq(post.actorId))).doReturn(UserBuilder.remoteUserOf(id = post.actorId)) - whenever(postRepository.save(eq(post))).doReturn(false) - - val createLocal = postServiceImpl.createRemote(post) - - assertThat(createLocal).isEqualTo(post) - - verify(postRepository, times(1)).save(eq(post)) - verify(timelineService, times(0)).publishTimeline(any(), any()) - } - - @Test - fun `createRemote 既に作成されていることを検知できず例外が発生した場合はDBから取得して返す`() = runTest { - val post = PostBuilder.of() - - whenever(actorRepository.findById(eq(post.actorId))).doReturn(UserBuilder.remoteUserOf(id = post.actorId)) - whenever(postRepository.save(eq(post))).doAnswer { throw ExposedSQLException(null, emptyList(), mock()) } - whenever(postQueryService.findByApId(eq(post.apId))).doReturn(post) + whenever(postRepository.save(eq(post))).doAnswer { throw DuplicateException() } + whenever(postRepository.findByApId(eq(post.apId))).doReturn(post) val createLocal = postServiceImpl.createRemote(post) @@ -139,8 +119,9 @@ class PostServiceImplTest { val post = PostBuilder.of() whenever(actorRepository.findById(eq(post.actorId))).doReturn(UserBuilder.remoteUserOf(id = post.actorId)) - whenever(postRepository.save(eq(post))).doReturn(true) - whenever(timelineService.publishTimeline(eq(post), eq(false))).doThrow(DuplicateKeyException::class) + whenever(postRepository.save(eq(post))).doReturn(post) + whenever(timelineService.publishTimeline(eq(post), eq(false))).doThrow(DuplicateException::class) + whenever(postRepository.findByApId(eq(post.apId))).doReturn(post) val createLocal = postServiceImpl.createRemote(post) diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImplTest.kt index 3dc6e04e..8dc8f5ec 100644 --- a/src/test/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImplTest.kt @@ -3,7 +3,6 @@ package dev.usbharu.hideout.core.service.reaction import dev.usbharu.hideout.activitypub.service.activity.like.APReactionService import dev.usbharu.hideout.application.service.id.TwitterSnowflakeIdGenerateService -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.reaction.Reaction import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository import kotlinx.coroutines.test.runTest @@ -25,9 +24,6 @@ class ReactionServiceImplTest { @Mock private lateinit var apReactionService: APReactionService - @Mock - private lateinit var reactionQueryService: ReactionQueryService - @InjectMocks private lateinit var reactionServiceImpl: ReactionServiceImpl @@ -36,7 +32,9 @@ class ReactionServiceImplTest { val post = PostBuilder.of() - whenever(reactionQueryService.reactionAlreadyExist(eq(post.id), eq(post.actorId), eq(0))).doReturn(false) + whenever(reactionRepository.existByPostIdAndActorIdAndEmojiId(eq(post.id), eq(post.actorId), eq(0))).doReturn( + false + ) val generateId = TwitterSnowflakeIdGenerateService.generateId() whenever(reactionRepository.generateId()).doReturn(generateId) @@ -49,7 +47,9 @@ class ReactionServiceImplTest { fun `receiveReaction リアクションが既に作成されていることを検知出来ずに例外が発生した場合は何もしない`() = runTest { val post = PostBuilder.of() - whenever(reactionQueryService.reactionAlreadyExist(eq(post.id), eq(post.actorId), eq(0))).doReturn(false) + whenever(reactionRepository.existByPostIdAndActorIdAndEmojiId(eq(post.id), eq(post.actorId), eq(0))).doReturn( + false + ) val generateId = TwitterSnowflakeIdGenerateService.generateId() whenever( reactionRepository.save( @@ -78,7 +78,9 @@ class ReactionServiceImplTest { @Test fun `receiveReaction リアクションが既に作成されている場合は何もしない`() = runTest() { val post = PostBuilder.of() - whenever(reactionQueryService.reactionAlreadyExist(eq(post.id), eq(post.actorId), eq(0))).doReturn(true) + whenever(reactionRepository.existByPostIdAndActorIdAndEmojiId(eq(post.id), eq(post.actorId), eq(0))).doReturn( + true + ) reactionServiceImpl.receiveReaction("❤", "example.com", post.actorId, post.id) @@ -88,8 +90,8 @@ class ReactionServiceImplTest { @Test fun `sendReaction リアクションが存在しないとき保存して配送する`() = runTest { val post = PostBuilder.of() - whenever(reactionQueryService.findByPostIdAndActorIdAndEmojiId(eq(post.id), eq(post.actorId), eq(0))).doThrow( - FailedToGetResourcesException::class + whenever(reactionRepository.findByPostIdAndActorIdAndEmojiId(eq(post.id), eq(post.actorId), eq(0))).doReturn( + null ) val generateId = TwitterSnowflakeIdGenerateService.generateId() whenever(reactionRepository.generateId()).doReturn(generateId) @@ -104,7 +106,7 @@ class ReactionServiceImplTest { fun `sendReaction リアクションが存在するときは削除して保存して配送する`() = runTest { val post = PostBuilder.of() val id = TwitterSnowflakeIdGenerateService.generateId() - whenever(reactionQueryService.findByPostIdAndActorIdAndEmojiId(eq(post.id), eq(post.actorId), eq(0))).doReturn( + whenever(reactionRepository.findByPostIdAndActorIdAndEmojiId(eq(post.id), eq(post.actorId), eq(0))).doReturn( Reaction(id, 0, post.id, post.actorId) ) val generateId = TwitterSnowflakeIdGenerateService.generateId() @@ -122,7 +124,7 @@ class ReactionServiceImplTest { @Test fun `removeReaction リアクションが存在する場合削除して配送`() = runTest { val post = PostBuilder.of() - whenever(reactionQueryService.findByPostIdAndActorIdAndEmojiId(eq(post.id), eq(post.actorId), eq(0))).doReturn( + whenever(reactionRepository.findByPostIdAndActorIdAndEmojiId(eq(post.id), eq(post.actorId), eq(0))).doReturn( Reaction(0, 0, post.id, post.actorId) ) diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImplTest.kt index b21bd0a5..44e43a17 100644 --- a/src/test/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImplTest.kt @@ -28,9 +28,6 @@ class RelationshipServiceImplTest { @Spy private val applicationConfig = ApplicationConfig(URL("https://example.com")) - @Mock - private lateinit var actorQueryService: ActorQueryService - @Mock private lateinit var relationshipRepository: RelationshipRepository @@ -57,7 +54,7 @@ class RelationshipServiceImplTest { @Test fun `followRequest ローカルの場合followRequestフラグがtrueで永続化される`() = runTest { - whenever(actorQueryService.findById(eq(5678))).doReturn(UserBuilder.localUserOf(domain = "example.com")) + whenever(actorRepository.findById(eq(5678))).doReturn(UserBuilder.localUserOf(domain = "example.com")) relationshipServiceImpl.followRequest(1234, 5678) @@ -79,9 +76,9 @@ class RelationshipServiceImplTest { @Test fun `followRequest リモートの場合Followアクティビティが配送される`() = runTest { val localUser = UserBuilder.localUserOf(domain = "example.com") - whenever(actorQueryService.findById(eq(1234))).doReturn(localUser) + whenever(actorRepository.findById(eq(1234))).doReturn(localUser) val remoteUser = UserBuilder.remoteUserOf(domain = "remote.example.com") - whenever(actorQueryService.findById(eq(5678))).doReturn(remoteUser) + whenever(actorRepository.findById(eq(5678))).doReturn(remoteUser) relationshipServiceImpl.followRequest(1234, 5678) @@ -144,9 +141,9 @@ class RelationshipServiceImplTest { @Test fun `followRequest 既にフォローしている場合は念の為フォロー承認を自動で行う`() = runTest { val remoteUser = UserBuilder.remoteUserOf(domain = "remote.example.com") - whenever(actorQueryService.findById(eq(1234))).doReturn(remoteUser) + whenever(actorRepository.findById(eq(1234))).doReturn(remoteUser) val localUser = UserBuilder.localUserOf(domain = "example.com") - whenever(actorQueryService.findById(eq(5678))).doReturn(localUser) + whenever(actorRepository.findById(eq(5678))).doReturn(localUser) whenever(relationshipRepository.findByUserIdAndTargetUserId(eq(1234), eq(5678))).doReturn( Relationship( actorId = 1234, @@ -212,8 +209,8 @@ class RelationshipServiceImplTest { @Test fun `block ローカルユーザーの場合永続化される`() = runTest { - whenever(actorQueryService.findById(eq(1234))).doReturn(UserBuilder.localUserOf(domain = "example.com")) - whenever(actorQueryService.findById(eq(5678))).doReturn(UserBuilder.localUserOf(domain = "example.com")) + whenever(actorRepository.findById(eq(1234))).doReturn(UserBuilder.localUserOf(domain = "example.com")) + whenever(actorRepository.findById(eq(5678))).doReturn(UserBuilder.localUserOf(domain = "example.com")) relationshipServiceImpl.block(1234, 5678) @@ -235,9 +232,9 @@ class RelationshipServiceImplTest { @Test fun `block リモートユーザーの場合永続化されて配送される`() = runTest { val localUser = UserBuilder.localUserOf(domain = "example.com") - whenever(actorQueryService.findById(eq(1234))).doReturn(localUser) + whenever(actorRepository.findById(eq(1234))).doReturn(localUser) val remoteUser = UserBuilder.remoteUserOf(domain = "remote.example.com") - whenever(actorQueryService.findById(eq(5678))).doReturn(remoteUser) + whenever(actorRepository.findById(eq(5678))).doReturn(remoteUser) relationshipServiceImpl.block(1234, 5678) @@ -260,8 +257,8 @@ class RelationshipServiceImplTest { @Test fun `acceptFollowRequest ローカルユーザーの場合永続化される`() = runTest { - whenever(actorQueryService.findById(eq(1234))).doReturn(UserBuilder.localUserOf(domain = "example.com")) - whenever(actorQueryService.findById(eq(5678))).doReturn(UserBuilder.localUserOf(domain = "example.com")) + whenever(actorRepository.findById(eq(1234))).doReturn(UserBuilder.localUserOf(domain = "example.com")) + whenever(actorRepository.findById(eq(5678))).doReturn(UserBuilder.localUserOf(domain = "example.com")) whenever(relationshipRepository.findByUserIdAndTargetUserId(eq(5678), eq(1234))).doReturn( Relationship( @@ -295,9 +292,9 @@ class RelationshipServiceImplTest { @Test fun `acceptFollowRequest リモートユーザーの場合永続化されて配送される`() = runTest { val localUser = UserBuilder.localUserOf(domain = "example.com") - whenever(actorQueryService.findById(eq(1234))).doReturn(localUser) + whenever(actorRepository.findById(eq(1234))).doReturn(localUser) val remoteUser = UserBuilder.remoteUserOf(domain = "remote.example.com") - whenever(actorQueryService.findById(eq(5678))).doReturn(remoteUser) + whenever(actorRepository.findById(eq(5678))).doReturn(remoteUser) whenever(relationshipRepository.findByUserIdAndTargetUserId(eq(5678), eq(1234))).doReturn( Relationship( @@ -352,8 +349,8 @@ class RelationshipServiceImplTest { @Test fun `acceptFollowRequest フォローリクエストが存在せずforceがtrueのときフォローを承認する`() = runTest { - whenever(actorQueryService.findById(eq(1234))).doReturn(UserBuilder.localUserOf(domain = "example.com")) - whenever(actorQueryService.findById(eq(5678))).doReturn(UserBuilder.remoteUserOf(domain = "remote.example.com")) + whenever(actorRepository.findById(eq(1234))).doReturn(UserBuilder.localUserOf(domain = "example.com")) + whenever(actorRepository.findById(eq(5678))).doReturn(UserBuilder.remoteUserOf(domain = "remote.example.com")) whenever(relationshipRepository.findByUserIdAndTargetUserId(eq(5678), eq(1234))).doReturn( Relationship( @@ -416,7 +413,7 @@ class RelationshipServiceImplTest { @Test fun `rejectFollowRequest ローカルユーザーの場合永続化される`() = runTest { - whenever(actorQueryService.findById(eq(5678))).doReturn(UserBuilder.localUserOf(domain = "example.com")) + whenever(actorRepository.findById(eq(5678))).doReturn(UserBuilder.localUserOf(domain = "example.com")) whenever(relationshipRepository.findByUserIdAndTargetUserId(eq(5678), eq(1234))).doReturn( Relationship( @@ -452,10 +449,10 @@ class RelationshipServiceImplTest { @Test fun `rejectFollowRequest リモートユーザーの場合永続化されて配送される`() = runTest { val localUser = UserBuilder.localUserOf(domain = "example.com") - whenever(actorQueryService.findById(eq(1234))).doReturn(localUser) + whenever(actorRepository.findById(eq(1234))).doReturn(localUser) val remoteUser = UserBuilder.remoteUserOf(domain = "remote.example.com") - whenever(actorQueryService.findById(eq(5678))).doReturn(remoteUser) + whenever(actorRepository.findById(eq(5678))).doReturn(remoteUser) whenever(relationshipRepository.findByUserIdAndTargetUserId(eq(5678), eq(1234))).doReturn( Relationship( @@ -536,8 +533,8 @@ class RelationshipServiceImplTest { @Test fun `unfollow ローカルユーザーの場合永続化される`() = runTest { - whenever(actorQueryService.findById(eq(1234))).doReturn(UserBuilder.remoteUserOf(domain = "remote.example.com")) - whenever(actorQueryService.findById(eq(5678))).doReturn(UserBuilder.localUserOf(domain = "example.com")) + whenever(actorRepository.findById(eq(1234))).doReturn(UserBuilder.remoteUserOf(domain = "remote.example.com")) + whenever(actorRepository.findById(eq(5678))).doReturn(UserBuilder.localUserOf(domain = "example.com")) whenever(relationshipRepository.findByUserIdAndTargetUserId(eq(1234), eq(5678))).doReturn( Relationship( actorId = 1234, @@ -572,10 +569,10 @@ class RelationshipServiceImplTest { @Test fun `unfollow リモートユーザー場合永続化されて配送される`() = runTest { val localUser = UserBuilder.localUserOf(domain = "example.com") - whenever(actorQueryService.findById(eq(1234))).doReturn(localUser) + whenever(actorRepository.findById(eq(1234))).doReturn(localUser) val remoteUser = UserBuilder.remoteUserOf(domain = "remote.example.com") - whenever(actorQueryService.findById(eq(5678))).doReturn(remoteUser) + whenever(actorRepository.findById(eq(5678))).doReturn(remoteUser) whenever(relationshipRepository.findByUserIdAndTargetUserId(eq(1234), eq(5678))).doReturn( Relationship( @@ -617,6 +614,9 @@ class RelationshipServiceImplTest { @Test fun `unfollow フォローしていなかった場合は何もしない`() = runTest { + whenever(actorRepository.findById(eq(1234))).doReturn(UserBuilder.localUserOf(id = 1234)) + whenever(actorRepository.findById(eq(5678))).doReturn(UserBuilder.localUserOf(id = 5678)) + whenever(relationshipRepository.findByUserIdAndTargetUserId(eq(1234), eq(5678))).doReturn( Relationship( actorId = 1234, @@ -636,7 +636,7 @@ class RelationshipServiceImplTest { @Test fun `unblock ローカルユーザーの場合永続化される`() = runTest { - whenever(actorQueryService.findById(eq(5678))).doReturn(UserBuilder.localUserOf(domain = "example.com")) + whenever(actorRepository.findById(eq(5678))).doReturn(UserBuilder.localUserOf(domain = "example.com")) whenever(relationshipRepository.findByUserIdAndTargetUserId(eq(1234), eq(5678))).doReturn( Relationship( actorId = 1234, @@ -671,10 +671,10 @@ class RelationshipServiceImplTest { @Test fun `unblock リモートユーザーの場合永続化されて配送される`() = runTest { val localUser = UserBuilder.localUserOf(domain = "example.com") - whenever(actorQueryService.findById(eq(1234))).doReturn(localUser) + whenever(actorRepository.findById(eq(1234))).doReturn(localUser) val remoteUser = UserBuilder.remoteUserOf(domain = "remote.example.com") - whenever(actorQueryService.findById(eq(5678))).doReturn(remoteUser) + whenever(actorRepository.findById(eq(5678))).doReturn(remoteUser) whenever(relationshipRepository.findByUserIdAndTargetUserId(eq(1234), eq(5678))).doReturn( Relationship( diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineServiceTest.kt b/src/test/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineServiceTest.kt index 22583888..940591f3 100644 --- a/src/test/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineServiceTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/core/service/timeline/TimelineServiceTest.kt @@ -2,6 +2,7 @@ package dev.usbharu.hideout.core.service.timeline import dev.usbharu.hideout.application.service.id.TwitterSnowflakeIdGenerateService import dev.usbharu.hideout.core.domain.model.actor.Actor +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.Visibility import dev.usbharu.hideout.core.domain.model.timeline.Timeline import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository @@ -26,7 +27,7 @@ class TimelineServiceTest { private lateinit var followerQueryService: FollowerQueryService @Mock - private lateinit var actorQueryService: ActorQueryService + private lateinit var actorRepository: ActorRepository @Mock private lateinit var timelineRepository: TimelineRepository @@ -44,7 +45,7 @@ class TimelineServiceTest { val localUserOf = UserBuilder.localUserOf(id = post.actorId) whenever(followerQueryService.findFollowersById(eq(post.actorId))).doReturn(listOf) - whenever(actorQueryService.findById(eq(post.actorId))).doReturn(localUserOf) + whenever(actorRepository.findById(eq(post.actorId))).doReturn(localUserOf) whenever(timelineRepository.generateId()).doReturn(TwitterSnowflakeIdGenerateService.generateId()) diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt b/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt index 1d2e089f..430c4ecd 100644 --- a/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt @@ -4,7 +4,6 @@ package dev.usbharu.hideout.core.service.user import dev.usbharu.hideout.application.config.ApplicationConfig import dev.usbharu.hideout.application.config.CharacterLimit -import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.Post @@ -70,14 +69,7 @@ class ActorServiceTest { val actorRepository = mock { onBlocking { nextId() } doReturn 113345L } - val deletedActorQueryService = mock { - onBlocking { - findByNameAndDomain( - eq("test"), - eq("remote.example.com") - ) - } doAnswer { throw FailedToGetResourcesException() } - } + val userService = UserServiceImpl( actorRepository = actorRepository, diff --git a/src/test/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiServiceImplTest.kt index 8c264507..192eeb3f 100644 --- a/src/test/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiServiceImplTest.kt @@ -48,10 +48,7 @@ class AccountApiServiceImplTest { @Mock private lateinit var relationshipRepository: RelationshipRepository - - @Mock - private lateinit var relationshipQueryService: RelationshipQueryService - + @Mock private lateinit var mediaService: MediaService From 0e547fce3d053370c5978a05bcd817bb3eca54ba Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 21 Dec 2023 13:36:45 +0900 Subject: [PATCH 08/12] =?UTF-8?q?fix:=20=E5=89=8A=E9=99=A4=E6=B8=88?= =?UTF-8?q?=E3=81=BF=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E3=81=A8=E3=82=A2?= =?UTF-8?q?=E3=82=AF=E3=83=86=E3=82=A3=E3=83=93=E3=83=86=E3=82=A3actor?= =?UTF-8?q?=E3=81=8C=E3=81=AA=E3=81=84=E3=81=A8=E3=81=8D=E3=81=AE=E3=83=95?= =?UTF-8?q?=E3=82=A9=E3=83=BC=E3=83=AB=E3=83=90=E3=83=83=E3=82=AF=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/e2eTest/resources/application.yml | 3 + .../service/inbox/InboxJobProcessor.kt | 10 +++- .../hideout/core/domain/model/actor/Actor.kt | 60 +++++++++++++------ 3 files changed, 55 insertions(+), 18 deletions(-) diff --git a/src/e2eTest/resources/application.yml b/src/e2eTest/resources/application.yml index 330660e2..dcd84955 100644 --- a/src/e2eTest/resources/application.yml +++ b/src/e2eTest/resources/application.yml @@ -9,6 +9,9 @@ hideout: public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCozMxH2Mo4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0/IzW7yWR7QkrmBL7jTKEn5u+qKhbwKfBstIs+bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyehkd3qqGElvW/VDL5AaWTg0nLVkjRo9z+40RQzuVaE8AkAFmxZzow3x+VJYKdjykkJ0iT9wCS0DRTXu269V264Vf/3jvredZiKRkgwlL9xNAwxXFg0x/XFw005UWVRIkdgcKWTjpBP2dPwVZ4WWC+9aGVd+Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbcmwIDAQAB" storage: type: local + debug: + trace-query-exception: true + trace-query-call: true spring: flyway: 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 660f5958..f090390e 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 @@ -94,7 +94,15 @@ class InboxJobProcessor( //todo 不正なactorを取得してしまわないようにする val verify = - signature?.let { verifyHttpSignature(httpRequest, it, transaction, jsonNode["actor"].textValue()) } ?: false + signature?.let { + verifyHttpSignature( + httpRequest, + it, + transaction, + jsonNode.get("actor")?.asText() ?: signature.keyId + ) + } + ?: false logger.debug("Is verifying success? {}", verify) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor.kt index 3833e71a..5eb351e3 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor.kt @@ -57,6 +57,32 @@ data class Actor private constructor( postsCount: Int = 0, lastPostDate: Instant? = null ): Actor { + + if (id == 0L) { + return Actor( + id = id, + name = name, + domain = domain, + screenName = screenName, + description = description, + inbox = inbox, + outbox = outbox, + url = url, + publicKey = publicKey, + privateKey = privateKey, + createdAt = createdAt, + keyId = keyId, + followers = followers, + following = following, + instance = instance, + locked = locked, + followersCount = followersCount, + followingCount = followingCount, + postsCount = postsCount, + lastPostDate = lastPostDate + ) + } + // idは0未満ではいけない require(id >= 0) { "id must be greater than or equal to 0." } @@ -184,22 +210,22 @@ data class Actor private constructor( override fun toString(): String { return "Actor(" + - "id=$id, " + - "name='$name', " + - "domain='$domain', " + - "screenName='$screenName', " + - "description='$description', " + - "inbox='$inbox', " + - "outbox='$outbox', " + - "url='$url', " + - "publicKey='$publicKey', " + - "privateKey=$privateKey, " + - "createdAt=$createdAt, " + - "keyId='$keyId', " + - "followers=$followers, " + - "following=$following, " + - "instance=$instance, " + - "locked=$locked" + - ")" + "id=$id, " + + "name='$name', " + + "domain='$domain', " + + "screenName='$screenName', " + + "description='$description', " + + "inbox='$inbox', " + + "outbox='$outbox', " + + "url='$url', " + + "publicKey='$publicKey', " + + "privateKey=$privateKey, " + + "createdAt=$createdAt, " + + "keyId='$keyId', " + + "followers=$followers, " + + "following=$following, " + + "instance=$instance, " + + "locked=$locked" + + ")" } } From 2105c47b0361418766ac8d425b5bab91e2759ec3 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 21 Dec 2023 14:28:17 +0900 Subject: [PATCH 09/12] =?UTF-8?q?feat:=20AbstractRepository=E3=82=92?= =?UTF-8?q?=E7=B6=99=E6=89=BF=E3=81=97=E3=81=A6=E3=81=84=E3=81=AA=E3=81=84?= =?UTF-8?q?Repository=E3=81=A7=E7=B6=99=E6=89=BF=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RelationshipRepositoryImpl.kt | 34 +++++--- .../ExposedTimelineRepository.kt | 38 +++++---- .../InstanceRepositoryImpl.kt | 28 +++++-- .../exposedrepository/MediaRepositoryImpl.kt | 26 ++++-- .../ReactionRepositoryImpl.kt | 82 +++++++++++-------- .../UserDetailRepositoryImpl.kt | 23 ++++-- 6 files changed, 146 insertions(+), 85 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt index 8dea030a..ab4278de 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt @@ -1,20 +1,23 @@ package dev.usbharu.hideout.core.domain.model.relationship +import dev.usbharu.hideout.core.infrastructure.exposedrepository.AbstractRepository import dev.usbharu.hideout.core.infrastructure.exposedrepository.Actors import org.jetbrains.exposed.dao.id.LongIdTable import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.slf4j.Logger +import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @Service -class RelationshipRepositoryImpl : RelationshipRepository { - override suspend fun save(relationship: Relationship): Relationship { +class RelationshipRepositoryImpl : RelationshipRepository, AbstractRepository() { + override suspend fun save(relationship: Relationship): Relationship = query { val singleOrNull = Relationships .select { (Relationships.actorId eq relationship.actorId) .and(Relationships.targetActorId eq relationship.targetActorId) - } + }.forUpdate() .singleOrNull() if (singleOrNull == null) { @@ -40,32 +43,32 @@ class RelationshipRepositoryImpl : RelationshipRepository { it[ignoreFollowRequestFromTarget] = relationship.ignoreFollowRequestToTarget } } - return relationship + return@query relationship } - override suspend fun delete(relationship: Relationship) { + override suspend fun delete(relationship: Relationship): Unit = query { Relationships.deleteWhere { (Relationships.actorId eq relationship.actorId) .and(Relationships.targetActorId eq relationship.targetActorId) } } - override suspend fun findByUserIdAndTargetUserId(actorId: Long, targetActorId: Long): Relationship? { - return Relationships.select { + override suspend fun findByUserIdAndTargetUserId(actorId: Long, targetActorId: Long): Relationship? = query { + return@query Relationships.select { (Relationships.actorId eq actorId) .and(Relationships.targetActorId eq targetActorId) }.singleOrNull() ?.toRelationships() } - override suspend fun deleteByActorIdOrTargetActorId(actorId: Long, targetActorId: Long) { + override suspend fun deleteByActorIdOrTargetActorId(actorId: Long, targetActorId: Long): Unit = query { Relationships.deleteWhere { Relationships.actorId.eq(actorId).or(Relationships.targetActorId.eq(targetActorId)) } } - override suspend fun findByTargetIdAndFollowing(targetId: Long, following: Boolean): List { - return Relationships.select { Relationships.targetActorId eq targetId and (Relationships.following eq following) } + override suspend fun findByTargetIdAndFollowing(targetId: Long, following: Boolean): List = query { + return@query Relationships.select { Relationships.targetActorId eq targetId and (Relationships.following eq following) } .map { it.toRelationships() } } @@ -76,7 +79,7 @@ class RelationshipRepositoryImpl : RelationshipRepository { targetId: Long, followRequest: Boolean, ignoreFollowRequest: Boolean - ): List { + ): List = query { val query = Relationships.select { Relationships.targetActorId.eq(targetId) .and(Relationships.followRequest.eq(followRequest)) @@ -91,7 +94,14 @@ class RelationshipRepositoryImpl : RelationshipRepository { query.andWhere { Relationships.id greaterEq sinceId } } - return query.map { it.toRelationships() } + return@query query.map { it.toRelationships() } + } + + override val logger: Logger + get() = Companion.logger + + companion object { + private val logger = LoggerFactory.getLogger(RelationshipRepositoryImpl::class.java) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt index f8b36460..e90a63e0 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt @@ -5,6 +5,8 @@ import dev.usbharu.hideout.core.domain.model.post.Visibility import dev.usbharu.hideout.core.domain.model.timeline.Timeline import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository import org.jetbrains.exposed.sql.* +import org.slf4j.Logger +import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Qualifier import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.stereotype.Repository @@ -12,11 +14,12 @@ import org.springframework.stereotype.Repository @Repository @Qualifier("jdbc") @ConditionalOnProperty("hideout.use-mongodb", havingValue = "false", matchIfMissing = true) -class ExposedTimelineRepository(private val idGenerateService: IdGenerateService) : TimelineRepository { +class ExposedTimelineRepository(private val idGenerateService: IdGenerateService) : TimelineRepository, + AbstractRepository() { override suspend fun generateId(): Long = idGenerateService.generateId() - override suspend fun save(timeline: Timeline): Timeline { - if (Timelines.select { Timelines.id eq timeline.id }.singleOrNull() == null) { + override suspend fun save(timeline: Timeline): Timeline = query { + if (Timelines.select { Timelines.id eq timeline.id }.forUpdate().singleOrNull() == null) { Timelines.insert { it[id] = timeline.id it[userId] = timeline.userId @@ -48,10 +51,10 @@ class ExposedTimelineRepository(private val idGenerateService: IdGenerateService it[mediaIds] = timeline.mediaIds.joinToString(",") } } - return timeline + return@query timeline } - override suspend fun saveAll(timelines: List): List { + override suspend fun saveAll(timelines: List): List = query { Timelines.batchInsert(timelines, true, false) { this[Timelines.id] = it.id this[Timelines.userId] = it.userId @@ -67,20 +70,28 @@ class ExposedTimelineRepository(private val idGenerateService: IdGenerateService this[Timelines.isPureRepost] = it.isPureRepost this[Timelines.mediaIds] = it.mediaIds.joinToString(",") } - return timelines + return@query timelines } - override suspend fun findByUserId(id: Long): List = - Timelines.select { Timelines.userId eq id }.map { it.toTimeline() } + override suspend fun findByUserId(id: Long): List = query { + return@query Timelines.select { Timelines.userId eq id }.map { it.toTimeline() } + } - override suspend fun findByUserIdAndTimelineId(userId: Long, timelineId: Long): List = - Timelines.select { Timelines.userId eq userId and (Timelines.timelineId eq timelineId) } + override suspend fun findByUserIdAndTimelineId(userId: Long, timelineId: Long): List = query { + return@query Timelines.select { Timelines.userId eq userId and (Timelines.timelineId eq timelineId) } .map { it.toTimeline() } + } + + override val logger: Logger + get() = Companion.logger + + companion object { + private val logger = LoggerFactory.getLogger(ExposedTimelineRepository::class.java) + } } fun ResultRow.toTimeline(): Timeline { - return Timeline( - id = this[Timelines.id], + return Timeline(id = this[Timelines.id], userId = this[Timelines.userId], timelineId = this[Timelines.timelineId], postId = this[Timelines.postId], @@ -92,8 +103,7 @@ fun ResultRow.toTimeline(): Timeline { sensitive = this[Timelines.sensitive], isLocal = this[Timelines.isLocal], isPureRepost = this[Timelines.isPureRepost], - mediaIds = this[Timelines.mediaIds].split(",").mapNotNull { it.toLongOrNull() } - ) + mediaIds = this[Timelines.mediaIds].split(",").mapNotNull { it.toLongOrNull() }) } object Timelines : Table("timelines") { diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt index e375dfe8..2a49c939 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt @@ -5,15 +5,18 @@ import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.javatime.timestamp +import org.slf4j.Logger +import org.slf4j.LoggerFactory import org.springframework.stereotype.Repository import dev.usbharu.hideout.core.domain.model.instance.Instance as InstanceEntity @Repository -class InstanceRepositoryImpl(private val idGenerateService: IdGenerateService) : InstanceRepository { +class InstanceRepositoryImpl(private val idGenerateService: IdGenerateService) : InstanceRepository, + AbstractRepository() { override suspend fun generateId(): Long = idGenerateService.generateId() - override suspend fun save(instance: InstanceEntity): InstanceEntity { - if (Instance.select { Instance.id.eq(instance.id) }.empty()) { + override suspend fun save(instance: InstanceEntity): InstanceEntity = query { + if (Instance.select { Instance.id.eq(instance.id) }.forUpdate().empty()) { Instance.insert { it[id] = instance.id it[name] = instance.name @@ -43,20 +46,27 @@ class InstanceRepositoryImpl(private val idGenerateService: IdGenerateService) : it[createdAt] = instance.createdAt } } - return instance + return@query instance } - override suspend fun findById(id: Long): InstanceEntity? { - return Instance.select { Instance.id eq id } + override suspend fun findById(id: Long): InstanceEntity? = query { + return@query Instance.select { Instance.id eq id } .singleOrNull()?.toInstance() } - override suspend fun delete(instance: InstanceEntity) { + override suspend fun delete(instance: InstanceEntity): Unit = query { Instance.deleteWhere { id eq instance.id } } - override suspend fun findByUrl(url: String): dev.usbharu.hideout.core.domain.model.instance.Instance? { - return Instance.select { Instance.url eq url }.singleOrNull()?.toInstance() + override suspend fun findByUrl(url: String): dev.usbharu.hideout.core.domain.model.instance.Instance? = query { + return@query Instance.select { Instance.url eq url }.singleOrNull()?.toInstance() + } + + override val logger: Logger + get() = Companion.logger + + companion object { + private val logger = LoggerFactory.getLogger(InstanceRepositoryImpl::class.java) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt index 19012f6c..979c4a76 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt @@ -7,14 +7,16 @@ import dev.usbharu.hideout.core.service.media.FileType import dev.usbharu.hideout.core.service.media.MimeType import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.slf4j.Logger +import org.slf4j.LoggerFactory import org.springframework.stereotype.Repository import dev.usbharu.hideout.core.domain.model.media.Media as EntityMedia @Repository -class MediaRepositoryImpl(private val idGenerateService: IdGenerateService) : MediaRepository { +class MediaRepositoryImpl(private val idGenerateService: IdGenerateService) : MediaRepository, AbstractRepository() { override suspend fun generateId(): Long = idGenerateService.generateId() - override suspend fun save(media: EntityMedia): EntityMedia { + override suspend fun save(media: EntityMedia): EntityMedia = query { if (Media.select { Media.id eq media.id }.forUpdate().singleOrNull() != null @@ -42,11 +44,11 @@ class MediaRepositoryImpl(private val idGenerateService: IdGenerateService) : Me it[description] = media.description } } - return media + return@query media } - override suspend fun findById(id: Long): EntityMedia? { - return Media + override suspend fun findById(id: Long): EntityMedia? = query { + return@query Media .select { Media.id eq id } @@ -54,14 +56,22 @@ class MediaRepositoryImpl(private val idGenerateService: IdGenerateService) : Me ?.toMedia() } - override suspend fun delete(id: Long) { + override suspend fun delete(id: Long): Unit = query { Media.deleteWhere { Media.id eq id } } - override suspend fun findByRemoteUrl(remoteUrl: String): dev.usbharu.hideout.core.domain.model.media.Media? { - return Media.select { Media.remoteUrl eq remoteUrl }.singleOrNull()?.toMedia() + override suspend fun findByRemoteUrl(remoteUrl: String): dev.usbharu.hideout.core.domain.model.media.Media? = + query { + return@query Media.select { Media.remoteUrl eq remoteUrl }.singleOrNull()?.toMedia() + } + + override val logger: Logger + get() = Companion.logger + + companion object { + private val logger = LoggerFactory.getLogger(MediaRepositoryImpl::class.java) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt index d39f996d..e1ead404 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt @@ -6,17 +6,19 @@ import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository import org.jetbrains.exposed.dao.id.LongIdTable import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.slf4j.Logger +import org.slf4j.LoggerFactory import org.springframework.stereotype.Repository @Repository class ReactionRepositoryImpl( private val idGenerateService: IdGenerateService -) : ReactionRepository { +) : ReactionRepository, AbstractRepository() { override suspend fun generateId(): Long = idGenerateService.generateId() - override suspend fun save(reaction: Reaction): Reaction { - if (Reactions.select { Reactions.id eq reaction.id }.empty()) { + override suspend fun save(reaction: Reaction): Reaction = query { + if (Reactions.select { Reactions.id eq reaction.id }.forUpdate().empty()) { Reactions.insert { it[id] = reaction.id it[emojiId] = reaction.emojiId @@ -30,69 +32,79 @@ class ReactionRepositoryImpl( it[actorId] = reaction.actorId } } - return reaction + return@query reaction } - override suspend fun delete(reaction: Reaction): Reaction { + override suspend fun delete(reaction: Reaction): Reaction = query { Reactions.deleteWhere { - id.eq(reaction.id) - .and(postId.eq(reaction.postId)) - .and(actorId.eq(reaction.actorId)) + id.eq(reaction.id).and(postId.eq(reaction.postId)).and(actorId.eq(reaction.actorId)) .and(emojiId.eq(reaction.emojiId)) } - return reaction + return@query reaction } - override suspend fun deleteByPostId(postId: Long): Int { - return Reactions.deleteWhere { + override suspend fun deleteByPostId(postId: Long): Int = query { + return@query Reactions.deleteWhere { Reactions.postId eq postId } } - override suspend fun deleteByActorId(actorId: Long): Int { - return Reactions.deleteWhere { + override suspend fun deleteByActorId(actorId: Long): Int = query { + return@query Reactions.deleteWhere { Reactions.actorId eq actorId } } - override suspend fun findByPostId(postId: Long): List { - return Reactions.select { Reactions.postId eq postId }.map { it.toReaction() } + override suspend fun findByPostId(postId: Long): List = query { + return@query Reactions.select { Reactions.postId eq postId }.map { it.toReaction() } } - override suspend fun findByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Reaction? { - return Reactions.select { - Reactions.postId eq postId and (Reactions.actorId eq actorId).and( - Reactions.emojiId.eq( - emojiId + override suspend fun findByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Reaction? = + query { + return@query Reactions.select { + Reactions.postId eq postId and (Reactions.actorId eq actorId).and( + Reactions.emojiId.eq( + emojiId + ) ) - ) - }.singleOrNull()?.toReaction() + }.singleOrNull()?.toReaction() + } + + override suspend fun existByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Boolean = + query { + return@query Reactions.select { + Reactions.postId + .eq(postId) + .and(Reactions.actorId.eq(actorId)) + .and(Reactions.emojiId.eq(emojiId)) + }.empty().not() + } + + override suspend fun findByPostIdAndActorId(postId: Long, actorId: Long): List = query { + return@query Reactions.select { Reactions.postId eq postId and (Reactions.actorId eq actorId) } + .map { it.toReaction() } } - override suspend fun existByPostIdAndActorIdAndEmojiId(postId: Long, actorId: Long, emojiId: Long): Boolean { - TODO("Not yet implemented") - } + override val logger: Logger + get() = Companion.logger - override suspend fun findByPostIdAndActorId(postId: Long, actorId: Long): List { - TODO("Not yet implemented") + companion object { + private val logger = LoggerFactory.getLogger(ReactionRepositoryImpl::class.java) } } fun ResultRow.toReaction(): Reaction { return Reaction( - this[Reactions.id].value, - this[Reactions.emojiId], - this[Reactions.postId], - this[Reactions.actorId] + this[Reactions.id].value, this[Reactions.emojiId], this[Reactions.postId], this[Reactions.actorId] ) } object Reactions : LongIdTable("reactions") { val emojiId: Column = long("emoji_id") - val postId: Column = long("post_id") - .references(Posts.id, onDelete = ReferenceOption.CASCADE, onUpdate = ReferenceOption.CASCADE) - val actorId: Column = long("actor_id") - .references(Actors.id, onDelete = ReferenceOption.CASCADE, onUpdate = ReferenceOption.CASCADE) + val postId: Column = + long("post_id").references(Posts.id, onDelete = ReferenceOption.CASCADE, onUpdate = ReferenceOption.CASCADE) + val actorId: Column = + long("actor_id").references(Actors.id, onDelete = ReferenceOption.CASCADE, onUpdate = ReferenceOption.CASCADE) init { uniqueIndex(emojiId, postId, actorId) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt index 4fb7b9c5..b64008dd 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt @@ -8,12 +8,14 @@ import org.jetbrains.exposed.sql.deleteWhere import org.jetbrains.exposed.sql.insert import org.jetbrains.exposed.sql.select import org.jetbrains.exposed.sql.update +import org.slf4j.Logger +import org.slf4j.LoggerFactory import org.springframework.stereotype.Repository @Repository -class UserDetailRepositoryImpl : UserDetailRepository { - override suspend fun save(userDetail: UserDetail): UserDetail { - val singleOrNull = UserDetails.select { UserDetails.actorId eq userDetail.actorId }.singleOrNull() +class UserDetailRepositoryImpl : UserDetailRepository, AbstractRepository() { + override suspend fun save(userDetail: UserDetail): UserDetail = query { + val singleOrNull = UserDetails.select { UserDetails.actorId eq userDetail.actorId }.forUpdate().singleOrNull() if (singleOrNull == null) { UserDetails.insert { it[actorId] = userDetail.actorId @@ -26,15 +28,15 @@ class UserDetailRepositoryImpl : UserDetailRepository { it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest } } - return userDetail + return@query userDetail } - override suspend fun delete(userDetail: UserDetail) { + override suspend fun delete(userDetail: UserDetail): Unit = query { UserDetails.deleteWhere { UserDetails.actorId eq userDetail.actorId } } - override suspend fun findByActorId(actorId: Long): UserDetail? { - return UserDetails + override suspend fun findByActorId(actorId: Long): UserDetail? = query { + return@query UserDetails .select { UserDetails.actorId eq actorId } .singleOrNull() ?.let { @@ -45,6 +47,13 @@ class UserDetailRepositoryImpl : UserDetailRepository { ) } } + + override val logger: Logger + get() = Companion.logger + + companion object { + private val logger = LoggerFactory.getLogger(UserDetailRepositoryImpl::class.java) + } } object UserDetails : LongIdTable("user_details") { From 3323229ef3fa53173db80bcc70f9ebe4daef7581 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 21 Dec 2023 14:48:21 +0900 Subject: [PATCH 10/12] style: fix lint --- .../activitypub/domain/model/Person.kt | 10 +- .../exposedquery/NoteQueryServiceImpl.kt | 12 +- .../activity/delete/APDeleteProcessor.kt | 2 - .../service/activity/like/APLikeProcessor.kt | 1 - .../service/activity/undo/APUndoProcessor.kt | 105 ++++++++++-------- .../service/inbox/InboxJobProcessor.kt | 3 +- .../service/objects/note/APNoteService.kt | 20 ++-- .../service/objects/user/APUserService.kt | 7 -- .../resource/UserNotFoundException.kt | 1 - .../local/LocalUserNotFoundException.kt | 2 - .../hideout/core/domain/model/actor/Actor.kt | 1 - .../domain/model/actor/ActorRepository.kt | 1 + .../model/instance/InstanceRepository.kt | 2 +- .../model/reaction/ReactionRepository.kt | 1 + .../relationship/RelationshipRepository.kt | 3 +- .../RelationshipRepositoryImpl.kt | 51 ++++----- .../exposedrepository/AbstractRepository.kt | 5 +- .../exposedrepository/ActorRepositoryImpl.kt | 15 +-- .../DeletedActorRepositoryImpl.kt | 6 +- .../ExposedTimelineRepository.kt | 12 +- .../InstanceRepositoryImpl.kt | 6 +- .../exposedrepository/MediaRepositoryImpl.kt | 8 +- .../exposedrepository/PostRepositoryImpl.kt | 5 +- .../ReactionRepositoryImpl.kt | 10 +- .../UserDetailRepositoryImpl.kt | 6 +- .../httpsignature/HttpRequestMixIn.kt | 1 + .../KJobMongoJobQueueWorkerService.kt | 2 +- .../interfaces/api/auth/AuthController.kt | 1 + .../media/LocalFileSystemMediaDataStore.kt | 2 + .../core/service/media/MediaServiceImpl.kt | 5 +- .../core/service/post/PostServiceImpl.kt | 2 +- .../service/reaction/ReactionServiceImpl.kt | 1 - .../service/resource/InMemoryCacheManager.kt | 1 - .../service/status/StatusesApiService.kt | 1 - 34 files changed, 159 insertions(+), 152 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt index 369905ec..5b6841c6 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt @@ -49,9 +49,9 @@ constructor( @Suppress("CyclomaticComplexMethod") override fun hashCode(): Int { var result = super.hashCode() - result = 31 * result + name.hashCode() + result = 31 * result + (name?.hashCode() ?: 0) result = 31 * result + id.hashCode() - result = 31 * result + (preferredUsername?.hashCode() ?: 0) + result = 31 * result + preferredUsername.hashCode() result = 31 * result + (summary?.hashCode() ?: 0) result = 31 * result + inbox.hashCode() result = 31 * result + outbox.hashCode() @@ -61,15 +61,15 @@ constructor( result = 31 * result + endpoints.hashCode() result = 31 * result + (followers?.hashCode() ?: 0) result = 31 * result + (following?.hashCode() ?: 0) - result = 31 * result + manuallyApprovesFollowers.hashCode() + result = 31 * result + (manuallyApprovesFollowers?.hashCode() ?: 0) return result } override fun toString(): String { return "Person(" + - "name='$name', " + + "name=$name, " + "id='$id', " + - "preferredUsername=$preferredUsername, " + + "preferredUsername='$preferredUsername', " + "summary=$summary, " + "inbox='$inbox', " + "outbox='$outbox', " + diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt index b0807f48..a009e6fe 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt @@ -26,8 +26,10 @@ class NoteQueryServiceImpl(private val postRepository: PostRepository, private v .leftJoin(Media) .select { Posts.id eq id } .let { - (it.toNote() ?: return null) to (postQueryMapper.map(it) - .singleOrNull() ?: return null) + (it.toNote() ?: return null) to ( + postQueryMapper.map(it) + .singleOrNull() ?: return null + ) } } @@ -38,8 +40,10 @@ class NoteQueryServiceImpl(private val postRepository: PostRepository, private v .leftJoin(Media) .select { Posts.apId eq apId } .let { - (it.toNote() ?: return null) to (postQueryMapper.map(it) - .singleOrNull() ?: return null) + (it.toNote() ?: return null) to ( + postQueryMapper.map(it) + .singleOrNull() ?: return null + ) } } 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 index 8a3559d8..1ad2acbf 100644 --- 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 @@ -36,14 +36,12 @@ class APDeleteProcessor( val actor = actorRepository.findByUrl(deleteId) actor?.let { userService.deleteRemoteActor(it.id) } - val post = postRepository.findByApId(deleteId) if (post == null) { logger.warn("FAILED Delete id: {} is not found.", deleteId) return } postService.deleteRemote(post) - } override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Delete 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 index 8ac309ed..994e2135 100644 --- 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 @@ -42,7 +42,6 @@ class APLikeProcessor( logger.trace("", e) return } - } override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Like 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 index 84d25edb..864c848f 100644 --- 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 @@ -24,70 +24,32 @@ class APUndoProcessor( private val reactionService: ReactionService, private val actorRepository: ActorRepository, private val postRepository: PostRepository -) : - AbstractActivityPubProcessor(transaction) { +) : AbstractActivityPubProcessor(transaction) { override suspend fun internalProcess(activity: ActivityPubProcessContext) { val undo = activity.activity - val type = - undo.apObject.type - .firstOrNull { it == "Block" || it == "Follow" || it == "Like" || it == "Announce" || it == "Accept" } - ?: return + val type = undo.apObject.type.firstOrNull { + it == "Block" || it == "Follow" || it == "Like" || it == "Announce" || it == "Accept" + } ?: return when (type) { "Follow" -> { - val follow = undo.apObject as Follow - - val follower = apUserService.fetchPersonWithEntity(undo.actor, follow.apObject).second - val target = - actorRepository.findByUrl(follow.apObject) ?: throw UserNotFoundException.withUrl(follow.apObject) - - relationshipService.unfollow(follower.id, target.id) + follow(undo) return } "Block" -> { - val block = undo.apObject as Block - - val blocker = apUserService.fetchPersonWithEntity(undo.actor, block.apObject).second - val target = - actorRepository.findByUrl(block.apObject) ?: throw UserNotFoundException.withUrl(block.apObject) - - relationshipService.unblock(blocker.id, target.id) + block(undo) return } "Accept" -> { - val accept = undo.apObject as Accept - - val acceptObject = if (accept.apObject is ObjectValue) { - accept.apObject.`object` - } else if (accept.apObject is Follow) { - accept.apObject.apObject - } else { - logger.warn("FAILED Unsupported type. Undo Accept {}", accept.apObject.type) - return - } - - val accepter = apUserService.fetchPersonWithEntity(undo.actor, acceptObject).second - val target = - actorRepository.findByUrl(acceptObject) ?: throw UserNotFoundException.withUrl(acceptObject) - - relationshipService.rejectFollowRequest(accepter.id, target.id) + accept(undo) return } "Like" -> { - val like = undo.apObject as Like - - val post = - postRepository.findByUrl(like.apObject) ?: throw PostNotFoundException.withUrl(like.apObject) - - val signer = - actorRepository.findById(post.actorId) ?: throw LocalUserNotFoundException.withId(post.actorId) - val actor = apUserService.fetchPersonWithEntity(like.actor, signer.url).second - - reactionService.receiveRemoveReaction(actor.id, post.id) + like(undo) return } @@ -96,6 +58,57 @@ class APUndoProcessor( TODO() } + private suspend fun accept(undo: Undo) { + val accept = undo.apObject as Accept + + val acceptObject = if (accept.apObject is ObjectValue) { + accept.apObject.`object` + } else if (accept.apObject is Follow) { + accept.apObject.apObject + } else { + logger.warn("FAILED Unsupported type. Undo Accept {}", accept.apObject.type) + return + } + + val accepter = apUserService.fetchPersonWithEntity(undo.actor, acceptObject).second + val target = actorRepository.findByUrl(acceptObject) ?: throw UserNotFoundException.withUrl(acceptObject) + + relationshipService.rejectFollowRequest(accepter.id, target.id) + return + } + + private suspend fun like(undo: Undo) { + val like = undo.apObject as Like + + val post = postRepository.findByUrl(like.apObject) ?: throw PostNotFoundException.withUrl(like.apObject) + + val signer = actorRepository.findById(post.actorId) ?: throw LocalUserNotFoundException.withId(post.actorId) + val actor = apUserService.fetchPersonWithEntity(like.actor, signer.url).second + + reactionService.receiveRemoveReaction(actor.id, post.id) + return + } + + private suspend fun block(undo: Undo) { + val block = undo.apObject as Block + + val blocker = apUserService.fetchPersonWithEntity(undo.actor, block.apObject).second + val target = actorRepository.findByUrl(block.apObject) ?: throw UserNotFoundException.withUrl(block.apObject) + + relationshipService.unblock(blocker.id, target.id) + return + } + + private suspend fun follow(undo: Undo) { + val follow = undo.apObject as Follow + + val follower = apUserService.fetchPersonWithEntity(undo.actor, follow.apObject).second + val target = actorRepository.findByUrl(follow.apObject) ?: throw UserNotFoundException.withUrl(follow.apObject) + + relationshipService.unfollow(follower.id, target.id) + return + } + 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/inbox/InboxJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/inbox/InboxJobProcessor.kt index f090390e..aac33e17 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 @@ -91,8 +91,7 @@ class InboxJobProcessor( logger.debug("Has signature? {}", signature != null) - - //todo 不正なactorを取得してしまわないようにする + // todo 不正なactorを取得してしまわないようにする val verify = signature?.let { verifyHttpSignature( diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt index c0c4bea1..7d284e0f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/note/APNoteService.kt @@ -53,7 +53,9 @@ class APNoteServiceImpl( apResourceResolveService.resolve(url, null as Long?) } catch (e: ClientRequestException) { logger.warn( - "FAILED Failed to retrieve ActivityPub resource. HTTP Status Code: {} url: {}", e.response.status, url + "FAILED Failed to retrieve ActivityPub resource. HTTP Status Code: {} url: {}", + e.response.status, + url ) throw FailedToGetActivityPubResourceException("Could not retrieve $url.", e) } @@ -63,14 +65,15 @@ class APNoteServiceImpl( } private suspend fun saveIfMissing( - note: Note, targetActor: String?, url: String - ): Pair { - return noteQueryService.findByApid(note.id) ?: saveNote(note, targetActor, url) - } + note: Note, + targetActor: String?, + url: String + ): Pair = noteQueryService.findByApid(note.id) ?: saveNote(note, targetActor, url) private suspend fun saveNote(note: Note, targetActor: String?, url: String): Pair { val person = apUserService.fetchPersonWithEntity( - note.attributedTo, targetActor + note.attributedTo, + targetActor ) val post = postRepository.findByApId(note.id) @@ -101,7 +104,10 @@ class APNoteServiceImpl( val mediaList = note.attachment.map { mediaService.uploadRemoteMedia( RemoteMedia( - it.name, it.url, it.mediaType, description = it.name + it.name, + it.url, + it.mediaType, + description = it.name ) ) }.map { it.id } 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 f366ac2f..503785c5 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 @@ -12,7 +12,6 @@ import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.service.user.RemoteUserCreateDto import dev.usbharu.hideout.core.service.user.UserService -import org.slf4j.LoggerFactory import org.springframework.stereotype.Service interface APUserService { @@ -83,7 +82,6 @@ class APUserServiceImpl( return entityToPerson(userEntity, userEntity.url) to userEntity } - val person = apResourceResolveService.resolve(url, null as Long?) val id = person.id @@ -111,7 +109,6 @@ class APUserServiceImpl( locked = person.manuallyApprovesFollowers ) ) - } private fun entityToPerson( @@ -141,8 +138,4 @@ class APUserServiceImpl( following = actorEntity.following, manuallyApprovesFollowers = actorEntity.locked ) - - companion object { - private val logger = LoggerFactory.getLogger(APUserServiceImpl::class.java) - } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/UserNotFoundException.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/UserNotFoundException.kt index 0560be92..30e2f133 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/UserNotFoundException.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/UserNotFoundException.kt @@ -18,7 +18,6 @@ open class UserNotFoundException : NotFoundException { @Serial private const val serialVersionUID: Long = 3219433672235626200L - fun withName(string: String, throwable: Throwable? = null): UserNotFoundException = UserNotFoundException("name: $string was not found.", throwable) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/local/LocalUserNotFoundException.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/local/LocalUserNotFoundException.kt index b2cdb0ae..672dfc53 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/local/LocalUserNotFoundException.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/resource/local/LocalUserNotFoundException.kt @@ -15,7 +15,6 @@ class LocalUserNotFoundException : UserNotFoundException { writableStackTrace ) - companion object { @Serial private const val serialVersionUID: Long = -4742548128672528145L @@ -29,5 +28,4 @@ class LocalUserNotFoundException : UserNotFoundException { fun withUrl(url: String, throwable: Throwable? = null): LocalUserNotFoundException = LocalUserNotFoundException("url: $url was not found.", throwable) } - } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor.kt index 5eb351e3..71fed7e9 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor.kt @@ -57,7 +57,6 @@ data class Actor private constructor( postsCount: Int = 0, lastPostDate: Instant? = null ): Actor { - if (id == 0L) { return Actor( id = id, diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorRepository.kt index ae39290a..5f87a817 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorRepository.kt @@ -3,6 +3,7 @@ package dev.usbharu.hideout.core.domain.model.actor import org.springframework.stereotype.Repository @Repository +@Suppress("TooManyFunctions") interface ActorRepository { suspend fun save(actor: Actor): Actor diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/InstanceRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/InstanceRepository.kt index c9ada9ff..c7676096 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/InstanceRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/instance/InstanceRepository.kt @@ -5,5 +5,5 @@ interface InstanceRepository { suspend fun save(instance: Instance): Instance suspend fun findById(id: Long): Instance? suspend fun delete(instance: Instance) - suspend fun findByUrl(url:String):Instance? + suspend fun findByUrl(url: String): Instance? } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt index ae8cad08..0b6183b5 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt @@ -3,6 +3,7 @@ package dev.usbharu.hideout.core.domain.model.reaction import org.springframework.stereotype.Repository @Repository +@Suppress("FunctionMaxLength") interface ReactionRepository { suspend fun generateId(): Long suspend fun save(reaction: Reaction): Reaction diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt index 4496f146..ac96db6b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt @@ -31,8 +31,9 @@ interface RelationshipRepository { suspend fun deleteByActorIdOrTargetActorId(actorId: Long, targetActorId: Long) - suspend fun findByTargetIdAndFollowing(targetId: Long,following:Boolean):List + suspend fun findByTargetIdAndFollowing(targetId: Long, following: Boolean): List + @Suppress("LongParameterList", "FunctionMaxLength") suspend fun findByTargetIdAndFollowRequestAndIgnoreFollowRequest( maxId: Long?, sinceId: Long?, diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt index ab4278de..a8085686 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt @@ -12,13 +12,11 @@ import org.springframework.stereotype.Service @Service class RelationshipRepositoryImpl : RelationshipRepository, AbstractRepository() { override suspend fun save(relationship: Relationship): Relationship = query { - val singleOrNull = - Relationships - .select { - (Relationships.actorId eq relationship.actorId) - .and(Relationships.targetActorId eq relationship.targetActorId) - }.forUpdate() - .singleOrNull() + val singleOrNull = Relationships.select { + (Relationships.actorId eq relationship.actorId).and( + Relationships.targetActorId eq relationship.targetActorId + ) + }.forUpdate().singleOrNull() if (singleOrNull == null) { Relationships.insert { @@ -31,34 +29,33 @@ class RelationshipRepositoryImpl : RelationshipRepository, AbstractRepository() it[ignoreFollowRequestFromTarget] = relationship.ignoreFollowRequestToTarget } } else { - Relationships - .update({ - (Relationships.actorId eq relationship.actorId) - .and(Relationships.targetActorId eq relationship.targetActorId) - }) { - it[following] = relationship.following - it[blocking] = relationship.blocking - it[muting] = relationship.muting - it[followRequest] = relationship.followRequest - it[ignoreFollowRequestFromTarget] = relationship.ignoreFollowRequestToTarget - } + Relationships.update({ + (Relationships.actorId eq relationship.actorId).and( + Relationships.targetActorId eq relationship.targetActorId + ) + }) { + it[following] = relationship.following + it[blocking] = relationship.blocking + it[muting] = relationship.muting + it[followRequest] = relationship.followRequest + it[ignoreFollowRequestFromTarget] = relationship.ignoreFollowRequestToTarget + } } return@query relationship } override suspend fun delete(relationship: Relationship): Unit = query { Relationships.deleteWhere { - (Relationships.actorId eq relationship.actorId) - .and(Relationships.targetActorId eq relationship.targetActorId) + (Relationships.actorId eq relationship.actorId).and( + Relationships.targetActorId eq relationship.targetActorId + ) } } override suspend fun findByUserIdAndTargetUserId(actorId: Long, targetActorId: Long): Relationship? = query { return@query Relationships.select { - (Relationships.actorId eq actorId) - .and(Relationships.targetActorId eq targetActorId) - }.singleOrNull() - ?.toRelationships() + (Relationships.actorId eq actorId).and(Relationships.targetActorId eq targetActorId) + }.singleOrNull()?.toRelationships() } override suspend fun deleteByActorIdOrTargetActorId(actorId: Long, targetActorId: Long): Unit = query { @@ -68,7 +65,8 @@ class RelationshipRepositoryImpl : RelationshipRepository, AbstractRepository() } override suspend fun findByTargetIdAndFollowing(targetId: Long, following: Boolean): List = query { - return@query Relationships.select { Relationships.targetActorId eq targetId and (Relationships.following eq following) } + return@query Relationships + .select { Relationships.targetActorId eq targetId and (Relationships.following eq following) } .map { it.toRelationships() } } @@ -81,8 +79,7 @@ class RelationshipRepositoryImpl : RelationshipRepository, AbstractRepository() ignoreFollowRequest: Boolean ): List = query { val query = Relationships.select { - Relationships.targetActorId.eq(targetId) - .and(Relationships.followRequest.eq(followRequest)) + Relationships.targetActorId.eq(targetId).and(Relationships.followRequest.eq(followRequest)) .and(Relationships.ignoreFollowRequestFromTarget.eq(ignoreFollowRequest)) }.limit(limit) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/AbstractRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/AbstractRepository.kt index 14da46c8..3e22db17 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/AbstractRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/AbstractRepository.kt @@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Value import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator import java.sql.SQLException +@Suppress("VarCouldBeVal") abstract class AbstractRepository { protected abstract val logger: Logger private val sqlErrorCodeSQLExceptionTranslator = SQLErrorCodeSQLExceptionTranslator() @@ -18,8 +19,8 @@ abstract class AbstractRepository { private var traceQueryCall: Boolean = false protected suspend fun query(block: () -> T): T = try { - if (traceQueryCall) { + @Suppress("ThrowingExceptionsWithoutMessageOrCause") logger.trace( """ ***** QUERY CALL STACK TRACE ***** @@ -29,11 +30,9 @@ ${Throwable().stackTrace.joinToString("\n")} ***** QUERY CALL STACK TRACE ***** """ ) - } block.invoke() - } catch (e: SQLException) { if (traceQueryException) { logger.trace("FAILED EXECUTE SQL", e) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ActorRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ActorRepositoryImpl.kt index fcb8a736..f4a70693 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ActorRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ActorRepositoryImpl.kt @@ -18,14 +18,12 @@ class ActorRepositoryImpl( private val actorResultRowMapper: ResultRowMapper, private val actorQueryMapper: QueryMapper ) : ActorRepository, AbstractRepository() { - + override val logger: Logger + get() = Companion.logger override suspend fun save(actor: Actor): Actor = query { - - val singleOrNull = Actors.select { Actors.id eq actor.id }.forUpdate().empty() if (singleOrNull) { - Actors.insert { it[id] = actor.id it[name] = actor.name @@ -125,9 +123,6 @@ class ActorRepositoryImpl( companion object { private val logger = LoggerFactory.getLogger(ActorRepositoryImpl::class.java) } - - override val logger: Logger - get() = Companion.logger } object Actors : Table("actors") { @@ -136,14 +131,16 @@ object Actors : Table("actors") { val domain: Column = varchar("domain", length = 1000) val screenName: Column = varchar("screen_name", length = 300) val description: Column = varchar( - "description", length = 10000 + "description", + length = 10000 ) val inbox: Column = varchar("inbox", length = 1000).uniqueIndex() val outbox: Column = varchar("outbox", length = 1000).uniqueIndex() val url: Column = varchar("url", length = 1000).uniqueIndex() val publicKey: Column = varchar("public_key", length = 10000) val privateKey: Column = varchar( - "private_key", length = 10000 + "private_key", + length = 10000 ).nullable() val createdAt: Column = long("created_at") val keyId = varchar("key_id", length = 1000) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt index 4495e151..36b22b80 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt @@ -11,6 +11,9 @@ import org.springframework.stereotype.Repository @Repository class DeletedActorRepositoryImpl : DeletedActorRepository, AbstractRepository() { + override val logger: Logger + get() = Companion.logger + override suspend fun save(deletedActor: DeletedActor): DeletedActor = query { val singleOrNull = DeletedActors.select { DeletedActors.id eq deletedActor.id }.forUpdate().singleOrNull() @@ -51,9 +54,6 @@ class DeletedActorRepositoryImpl : DeletedActorRepository, AbstractRepository() ?.toDeletedActor() } - override val logger: Logger - get() = Companion.logger - companion object { private val logger = LoggerFactory.getLogger(DeletedActorRepositoryImpl::class.java) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt index e90a63e0..2630f733 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt @@ -16,6 +16,9 @@ import org.springframework.stereotype.Repository @ConditionalOnProperty("hideout.use-mongodb", havingValue = "false", matchIfMissing = true) class ExposedTimelineRepository(private val idGenerateService: IdGenerateService) : TimelineRepository, AbstractRepository() { + override val logger: Logger + get() = Companion.logger + override suspend fun generateId(): Long = idGenerateService.generateId() override suspend fun save(timeline: Timeline): Timeline = query { @@ -82,16 +85,14 @@ class ExposedTimelineRepository(private val idGenerateService: IdGenerateService .map { it.toTimeline() } } - override val logger: Logger - get() = Companion.logger - companion object { private val logger = LoggerFactory.getLogger(ExposedTimelineRepository::class.java) } } fun ResultRow.toTimeline(): Timeline { - return Timeline(id = this[Timelines.id], + return Timeline( + id = this[Timelines.id], userId = this[Timelines.userId], timelineId = this[Timelines.timelineId], postId = this[Timelines.postId], @@ -103,7 +104,8 @@ fun ResultRow.toTimeline(): Timeline { sensitive = this[Timelines.sensitive], isLocal = this[Timelines.isLocal], isPureRepost = this[Timelines.isPureRepost], - mediaIds = this[Timelines.mediaIds].split(",").mapNotNull { it.toLongOrNull() }) + mediaIds = this[Timelines.mediaIds].split(",").mapNotNull { it.toLongOrNull() } + ) } object Timelines : Table("timelines") { diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt index 2a49c939..485cf6de 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt @@ -13,6 +13,9 @@ import dev.usbharu.hideout.core.domain.model.instance.Instance as InstanceEntity @Repository class InstanceRepositoryImpl(private val idGenerateService: IdGenerateService) : InstanceRepository, AbstractRepository() { + override val logger: Logger + get() = Companion.logger + override suspend fun generateId(): Long = idGenerateService.generateId() override suspend fun save(instance: InstanceEntity): InstanceEntity = query { @@ -62,9 +65,6 @@ class InstanceRepositoryImpl(private val idGenerateService: IdGenerateService) : return@query Instance.select { Instance.url eq url }.singleOrNull()?.toInstance() } - override val logger: Logger - get() = Companion.logger - companion object { private val logger = LoggerFactory.getLogger(InstanceRepositoryImpl::class.java) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt index 979c4a76..c838031c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt @@ -14,6 +14,9 @@ import dev.usbharu.hideout.core.domain.model.media.Media as EntityMedia @Repository class MediaRepositoryImpl(private val idGenerateService: IdGenerateService) : MediaRepository, AbstractRepository() { + override val logger: Logger + get() = Companion.logger + override suspend fun generateId(): Long = idGenerateService.generateId() override suspend fun save(media: EntityMedia): EntityMedia = query { @@ -65,10 +68,7 @@ class MediaRepositoryImpl(private val idGenerateService: IdGenerateService) : Me override suspend fun findByRemoteUrl(remoteUrl: String): dev.usbharu.hideout.core.domain.model.media.Media? = query { return@query Media.select { Media.remoteUrl eq remoteUrl }.singleOrNull()?.toMedia() - } - - override val logger: Logger - get() = Companion.logger + } companion object { private val logger = LoggerFactory.getLogger(MediaRepositoryImpl::class.java) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt index c8e88d96..2a1899fd 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt @@ -15,6 +15,8 @@ class PostRepositoryImpl( private val idGenerateService: IdGenerateService, private val postQueryMapper: QueryMapper ) : PostRepository, AbstractRepository() { + override val logger: Logger + get() = Companion.logger override suspend fun generateId(): Long = idGenerateService.generateId() @@ -97,9 +99,6 @@ class PostRepositoryImpl( Posts.deleteWhere { Posts.id eq id } } - override val logger: Logger - get() = Companion.logger - companion object { private val logger = LoggerFactory.getLogger(PostRepositoryImpl::class.java) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt index e1ead404..1a3a14ff 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt @@ -14,6 +14,8 @@ import org.springframework.stereotype.Repository class ReactionRepositoryImpl( private val idGenerateService: IdGenerateService ) : ReactionRepository, AbstractRepository() { + override val logger: Logger + get() = Companion.logger override suspend fun generateId(): Long = idGenerateService.generateId() @@ -85,9 +87,6 @@ class ReactionRepositoryImpl( .map { it.toReaction() } } - override val logger: Logger - get() = Companion.logger - companion object { private val logger = LoggerFactory.getLogger(ReactionRepositoryImpl::class.java) } @@ -95,7 +94,10 @@ class ReactionRepositoryImpl( fun ResultRow.toReaction(): Reaction { return Reaction( - this[Reactions.id].value, this[Reactions.emojiId], this[Reactions.postId], this[Reactions.actorId] + this[Reactions.id].value, + this[Reactions.emojiId], + this[Reactions.postId], + this[Reactions.actorId] ) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt index b64008dd..9b58365d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt @@ -14,6 +14,9 @@ import org.springframework.stereotype.Repository @Repository class UserDetailRepositoryImpl : UserDetailRepository, AbstractRepository() { + override val logger: Logger + get() = Companion.logger + override suspend fun save(userDetail: UserDetail): UserDetail = query { val singleOrNull = UserDetails.select { UserDetails.actorId eq userDetail.actorId }.forUpdate().singleOrNull() if (singleOrNull == null) { @@ -48,9 +51,6 @@ class UserDetailRepositoryImpl : UserDetailRepository, AbstractRepository() { } } - override val logger: Logger - get() = Companion.logger - companion object { private val logger = LoggerFactory.getLogger(UserDetailRepositoryImpl::class.java) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/httpsignature/HttpRequestMixIn.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/httpsignature/HttpRequestMixIn.kt index 4f998d91..4e14bdae 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/httpsignature/HttpRequestMixIn.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/httpsignature/HttpRequestMixIn.kt @@ -13,6 +13,7 @@ import java.net.URL @JsonDeserialize(using = HttpRequestDeserializer::class) @JsonSubTypes +@Suppress("UnnecessaryAbstractClass") abstract class HttpRequestMixIn class HttpRequestDeserializer : JsonDeserializer() { 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 71283023..6e5fdad1 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 @@ -41,8 +41,8 @@ class KJobMongoJobQueueWorkerService( } for (jobProcessor in jobQueueProcessorList) { kjob.register(jobProcessor.job()) { - execute { + @Suppress("TooGenericExceptionCaught") try { MDC.put("x-job-id", this.jobId) val param = it.convertUnsafe(props) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/AuthController.kt b/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/AuthController.kt index b42f791b..972df120 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/AuthController.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/AuthController.kt @@ -6,5 +6,6 @@ import org.springframework.web.bind.annotation.GetMapping @Controller class AuthController { @GetMapping("/auth/sign_up") + @Suppress("FunctionOnlyReturningConstant") fun signUp(): String = "sign_up" } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/LocalFileSystemMediaDataStore.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/media/LocalFileSystemMediaDataStore.kt index 2b329ebb..bae8977d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/media/LocalFileSystemMediaDataStore.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/media/LocalFileSystemMediaDataStore.kt @@ -74,6 +74,7 @@ class LocalFileSystemMediaDataStore( val fileSavePathString = fileSavePath.toAbsolutePath().toString() logger.info("MEDIA save. path: {}", fileSavePathString) + @Suppress("TooGenericExceptionCaught") try { dataSaveRequest.filePath.copyTo(fileSavePath) dataSaveRequest.thumbnailPath?.copyTo(thumbnailSavePath) @@ -97,6 +98,7 @@ class LocalFileSystemMediaDataStore( */ override suspend fun delete(id: String) { logger.info("START Media delete. id: {}", id) + @Suppress("TooGenericExceptionCaught") try { buildSavePath(savePath, id).deleteIfExists() buildSavePath(savePath, "thumbnail-$id").deleteIfExists() diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt index 1bcf9c69..6cc50463 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt @@ -99,7 +99,6 @@ class MediaServiceImpl( override suspend fun uploadRemoteMedia(remoteMedia: RemoteMedia): Media { logger.info("MEDIA Remote media. filename:${remoteMedia.name} url:${remoteMedia.url}") - val findByRemoteUrl = mediaRepository.findByRemoteUrl(remoteMedia.url) if (findByRemoteUrl != null) { logger.warn("DUPLICATED Remote media is duplicated. url: {}", remoteMedia.url) @@ -156,7 +155,7 @@ class MediaServiceImpl( } } - protected fun findMediaProcessor(mimeType: MimeType): MediaProcessService { + private fun findMediaProcessor(mimeType: MimeType): MediaProcessService { try { return mediaProcessServices.first { try { @@ -170,7 +169,7 @@ class MediaServiceImpl( } } - protected fun generateBlurhash(process: ProcessedMediaPath): String { + private fun generateBlurhash(process: ProcessedMediaPath): String { val path = if (process.thumbnailPath != null && process.thumbnailMimeType != null) { process.thumbnailPath } else { diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt index 52211b17..fcd44f67 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt @@ -81,7 +81,7 @@ class PostServiceImpl( timelineService.publishTimeline(post, isLocal) actorRepository.save(actor.incrementPostsCount()) save - } catch (e: DuplicateException) { + } catch (_: DuplicateException) { postRepository.findByApId(post.apId) ?: throw PostNotFoundException.withApId(post.apId) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt index 9d957dc1..2a731029 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/reaction/ReactionServiceImpl.kt @@ -42,7 +42,6 @@ class ReactionServiceImpl( reactionRepository.delete(findByPostIdAndUserIdAndEmojiId) } - val reaction = Reaction(reactionRepository.generateId(), 0, postId, actorId) reactionRepository.save(reaction) apReactionService.reaction(reaction) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/resource/InMemoryCacheManager.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/resource/InMemoryCacheManager.kt index 8cb59ba7..fc35b768 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/resource/InMemoryCacheManager.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/resource/InMemoryCacheManager.kt @@ -33,7 +33,6 @@ class InMemoryCacheManager : CacheManager { val processed = try { block() } catch (e: Exception) { - e.printStackTrace() cacheKey.remove(key) throw e } diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt index c51aca0c..1a095d82 100644 --- a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/status/StatusesApiService.kt @@ -59,7 +59,6 @@ class StatsesApiServiceImpl( } else { actorRepository.findById(findById.actorId)?.id } - } else { null } From f38d3398029e59ca1f51b1babb9c273f1282ddf7 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 21 Dec 2023 14:56:48 +0900 Subject: [PATCH 11/12] style: fix lint --- .../hideout/activitypub/service/inbox/InboxJobProcessor.kt | 1 - 1 file changed, 1 deletion(-) 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 1161fcc7..2a884ae0 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 @@ -87,7 +87,6 @@ class InboxJobProcessor( 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)) From 5be0d7d9c2f286870215d48edfeddbec36c52972 Mon Sep 17 00:00:00 2001 From: usbharu Date: Thu, 21 Dec 2023 15:07:28 +0900 Subject: [PATCH 12/12] Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../hideout/activitypub/domain/model/Person.kt | 4 ++-- .../exposedquery/NoteQueryServiceImpl.kt | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt index 5b6841c6..0b3e4ff1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt @@ -67,9 +67,9 @@ constructor( override fun toString(): String { return "Person(" + - "name=$name, " + + "name=$name, " + "id='$id', " + - "preferredUsername='$preferredUsername', " + + "preferredUsername='$preferredUsername', " + "summary=$summary, " + "inbox='$inbox', " + "outbox='$outbox', " + diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt index a009e6fe..1ebc9511 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt @@ -27,9 +27,9 @@ class NoteQueryServiceImpl(private val postRepository: PostRepository, private v .select { Posts.id eq id } .let { (it.toNote() ?: return null) to ( - postQueryMapper.map(it) - .singleOrNull() ?: return null - ) + postQueryMapper.map(it) + .singleOrNull() ?: return null + ) } } @@ -41,9 +41,9 @@ class NoteQueryServiceImpl(private val postRepository: PostRepository, private v .select { Posts.apId eq apId } .let { (it.toNote() ?: return null) to ( - postQueryMapper.map(it) - .singleOrNull() ?: return null - ) + postQueryMapper.map(it) + .singleOrNull() ?: return null + ) } }