From ee8bbf509167c671d9f17b77b1a3f639fdf3a432 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 11 Aug 2023 14:23:52 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=E3=83=88=E3=83=A9=E3=83=B3=E3=82=B6?= =?UTF-8?q?=E3=82=AF=E3=82=B7=E3=83=A7=E3=83=B3=E7=AE=A1=E7=90=86=E3=82=92?= =?UTF-8?q?=E6=8A=BD=E8=B1=A1=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/dev/usbharu/hideout/Application.kt | 10 +++------- .../dev/usbharu/hideout/plugins/Routing.kt | 8 ++++---- .../hideout/routing/activitypub/UserRouting.kt | 7 ++++--- .../hideout/service/api/PostApiServiceImpl.kt | 15 ++++++++------- .../hideout/service/api/UserApiServiceImpl.kt | 7 ++++--- .../service/api/UserAuthApiServiceImpl.kt | 9 +++++---- .../hideout/service/core/ExposedTransaction.kt | 13 +++++++++++++ .../hideout/service/core/MetaServiceImpl.kt | 8 ++++---- .../service/core/ServerInitialiseServiceImpl.kt | 11 +++++++---- .../usbharu/hideout/service/core/Transaction.kt | 5 +++++ .../hideout/routing/activitypub/UsersAPTest.kt | 7 ++++--- .../hideout/service/core/MetaServiceImplTest.kt | 17 +++++++---------- .../core/ServerInitialiseServiceImplTest.kt | 7 ++++--- src/test/kotlin/utils/TestTransaction.kt | 7 +++++++ 14 files changed, 79 insertions(+), 52 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/core/ExposedTransaction.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/core/Transaction.kt create mode 100644 src/test/kotlin/utils/TestTransaction.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/Application.kt b/src/main/kotlin/dev/usbharu/hideout/Application.kt index d711ea21..2c9fc9b5 100644 --- a/src/main/kotlin/dev/usbharu/hideout/Application.kt +++ b/src/main/kotlin/dev/usbharu/hideout/Application.kt @@ -21,13 +21,9 @@ import dev.usbharu.hideout.service.api.IPostApiService import dev.usbharu.hideout.service.api.IUserApiService import dev.usbharu.hideout.service.api.UserAuthApiService import dev.usbharu.hideout.service.auth.HttpSignatureVerifyService -import dev.usbharu.hideout.service.core.IMetaService -import dev.usbharu.hideout.service.core.IServerInitialiseService -import dev.usbharu.hideout.service.core.IdGenerateService -import dev.usbharu.hideout.service.core.TwitterSnowflakeIdGenerateService +import dev.usbharu.hideout.service.core.* import dev.usbharu.hideout.service.job.JobQueueParentService import dev.usbharu.hideout.service.job.KJobJobQueueParentService -import dev.usbharu.hideout.service.reaction.IReactionService import dev.usbharu.hideout.service.user.IUserService import dev.usbharu.kjob.exposed.ExposedKJob import io.ktor.client.* @@ -117,10 +113,10 @@ fun Application.parent() { activityPubUserService = inject().value, postService = inject().value, userApiService = inject().value, - reactionService = inject().value, userQueryService = inject().value, followerQueryService = inject().value, - userAuthApiService = inject().value + userAuthApiService = inject().value, + transaction = inject().value ) } diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt index faafba95..a4d5d3e8 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt @@ -15,7 +15,7 @@ import dev.usbharu.hideout.service.api.IPostApiService import dev.usbharu.hideout.service.api.IUserApiService import dev.usbharu.hideout.service.api.UserAuthApiService import dev.usbharu.hideout.service.auth.HttpSignatureVerifyService -import dev.usbharu.hideout.service.reaction.IReactionService +import dev.usbharu.hideout.service.core.Transaction import dev.usbharu.hideout.service.user.IUserService import io.ktor.server.application.* import io.ktor.server.plugins.autohead.* @@ -29,16 +29,16 @@ fun Application.configureRouting( activityPubUserService: ActivityPubUserService, postService: IPostApiService, userApiService: IUserApiService, - reactionService: IReactionService, userQueryService: UserQueryService, followerQueryService: FollowerQueryService, - userAuthApiService: UserAuthApiService + userAuthApiService: UserAuthApiService, + transaction: Transaction ) { install(AutoHeadResponse) routing { inbox(httpSignatureVerifyService, activityPubService) outbox() - usersAP(activityPubUserService, userQueryService, followerQueryService) + usersAP(activityPubUserService, userQueryService, followerQueryService, transaction) webfinger(userQueryService) route("/api/internal/v1") { posts(postService) diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt index 6bf36e8c..734c45c8 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt @@ -6,6 +6,7 @@ import dev.usbharu.hideout.plugins.respondAp import dev.usbharu.hideout.query.FollowerQueryService import dev.usbharu.hideout.query.UserQueryService import dev.usbharu.hideout.service.activitypub.ActivityPubUserService +import dev.usbharu.hideout.service.core.Transaction import dev.usbharu.hideout.util.HttpUtil.Activity import dev.usbharu.hideout.util.HttpUtil.JsonLd import io.ktor.http.* @@ -13,12 +14,12 @@ import io.ktor.server.application.* import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* -import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction fun Routing.usersAP( activityPubUserService: ActivityPubUserService, userQueryService: UserQueryService, - followerQueryService: FollowerQueryService + followerQueryService: FollowerQueryService, + transaction: Transaction ) { route("/users/{name}") { createChild(ContentTypeRouteSelector(ContentType.Application.Activity, ContentType.Application.JsonLd)).handle { @@ -34,7 +35,7 @@ fun Routing.usersAP( } get { // TODO: 暫定処置なので治す - newSuspendedTransaction { + transaction.transaction { val userEntity = userQueryService.findByNameAndDomain( call.parameters["name"] ?: throw ParameterNotExistException("Parameter(name='name') does not exist."), diff --git a/src/main/kotlin/dev/usbharu/hideout/service/api/PostApiServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/api/PostApiServiceImpl.kt index 45dce873..fe00e680 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/api/PostApiServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/api/PostApiServiceImpl.kt @@ -7,10 +7,10 @@ import dev.usbharu.hideout.domain.model.hideout.dto.ReactionResponse import dev.usbharu.hideout.query.PostResponseQueryService import dev.usbharu.hideout.query.ReactionQueryService import dev.usbharu.hideout.repository.IUserRepository +import dev.usbharu.hideout.service.core.Transaction import dev.usbharu.hideout.service.post.IPostService import dev.usbharu.hideout.service.reaction.IReactionService import dev.usbharu.hideout.util.AcctUtil -import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction import org.koin.core.annotation.Single import java.time.Instant import dev.usbharu.hideout.domain.model.hideout.form.Post as FormPost @@ -21,10 +21,11 @@ class PostApiServiceImpl( private val userRepository: IUserRepository, private val postResponseQueryService: PostResponseQueryService, private val reactionQueryService: ReactionQueryService, - private val reactionService: IReactionService + private val reactionService: IReactionService, + private val transaction: Transaction ) : IPostApiService { override suspend fun createPost(postForm: FormPost, userId: Long): PostResponse { - return newSuspendedTransaction { + return transaction.transaction { val createdPost = postService.createLocal( PostCreateDto( text = postForm.text, @@ -49,7 +50,7 @@ class PostApiServiceImpl( maxId: Long?, limit: Int?, userId: Long? - ): List = newSuspendedTransaction { + ): List = transaction.transaction { postResponseQueryService.findAll( since?.toEpochMilli(), until?.toEpochMilli(), @@ -79,16 +80,16 @@ class PostApiServiceImpl( } override suspend fun getReactionByPostId(postId: Long, userId: Long?): List = - newSuspendedTransaction { reactionQueryService.findByPostIdWithUsers(postId, userId) } + transaction.transaction { reactionQueryService.findByPostIdWithUsers(postId, userId) } override suspend fun appendReaction(reaction: String, userId: Long, postId: Long) { - newSuspendedTransaction { + transaction.transaction { reactionService.sendReaction(reaction, userId, postId) } } override suspend fun removeReaction(userId: Long, postId: Long) { - newSuspendedTransaction { + transaction.transaction { reactionService.removeReaction(userId, postId) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/api/UserApiServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/api/UserApiServiceImpl.kt index 37ac1890..0cd675c2 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/api/UserApiServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/api/UserApiServiceImpl.kt @@ -7,8 +7,8 @@ import dev.usbharu.hideout.domain.model.hideout.dto.UserResponse import dev.usbharu.hideout.exception.UsernameAlreadyExistException import dev.usbharu.hideout.query.FollowerQueryService import dev.usbharu.hideout.query.UserQueryService +import dev.usbharu.hideout.service.core.Transaction import dev.usbharu.hideout.service.user.IUserService -import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction import org.koin.core.annotation.Single import kotlin.math.min @@ -16,7 +16,8 @@ import kotlin.math.min class UserApiServiceImpl( private val userQueryService: UserQueryService, private val followerQueryService: FollowerQueryService, - private val userService: IUserService + private val userService: IUserService, + private val transaction: Transaction ) : IUserApiService { override suspend fun findAll(limit: Int?, offset: Long): List = userQueryService.findAll(min(limit ?: 100, 100), offset).map { UserResponse.from(it) } @@ -44,7 +45,7 @@ class UserApiServiceImpl( .map { UserResponse.from(it) } override suspend fun createUser(username: String, password: String): UserResponse { - return newSuspendedTransaction { + return transaction.transaction { if (userQueryService.existByNameAndDomain(username, Config.configData.domain)) { throw UsernameAlreadyExistException() } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/api/UserAuthApiServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/api/UserAuthApiServiceImpl.kt index 06f87f3e..6896419b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/api/UserAuthApiServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/api/UserAuthApiServiceImpl.kt @@ -6,18 +6,19 @@ import dev.usbharu.hideout.domain.model.hideout.form.RefreshToken import dev.usbharu.hideout.exception.InvalidUsernameOrPasswordException import dev.usbharu.hideout.query.UserQueryService import dev.usbharu.hideout.service.auth.IJwtService +import dev.usbharu.hideout.service.core.Transaction import dev.usbharu.hideout.service.user.UserAuthService -import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction import org.koin.core.annotation.Single @Single class UserAuthApiServiceImpl( private val userAuthService: UserAuthService, private val userQueryService: UserQueryService, - private val jwtService: IJwtService + private val jwtService: IJwtService, + private val transaction: Transaction ) : UserAuthApiService { override suspend fun login(username: String, password: String): JwtToken { - return newSuspendedTransaction { + return transaction.transaction { if (userAuthService.verifyAccount(username, password).not()) { throw InvalidUsernameOrPasswordException() } @@ -27,7 +28,7 @@ class UserAuthApiServiceImpl( } override suspend fun refreshToken(refreshToken: RefreshToken): JwtToken { - return newSuspendedTransaction { + return transaction.transaction { jwtService.refreshToken(refreshToken) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/core/ExposedTransaction.kt b/src/main/kotlin/dev/usbharu/hideout/service/core/ExposedTransaction.kt new file mode 100644 index 00000000..a58cfe04 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/core/ExposedTransaction.kt @@ -0,0 +1,13 @@ +package dev.usbharu.hideout.service.core + +import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction +import org.koin.core.annotation.Single + +@Single +class ExposedTransaction : Transaction { + override suspend fun transaction(block: suspend () -> T): T { + return newSuspendedTransaction { + block() + } + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/core/MetaServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/core/MetaServiceImpl.kt index ebd15efa..c971c177 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/core/MetaServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/core/MetaServiceImpl.kt @@ -4,15 +4,15 @@ import dev.usbharu.hideout.domain.model.hideout.entity.Jwt import dev.usbharu.hideout.domain.model.hideout.entity.Meta import dev.usbharu.hideout.exception.NotInitException import dev.usbharu.hideout.repository.IMetaRepository -import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction import org.koin.core.annotation.Single @Single -class MetaServiceImpl(private val metaRepository: IMetaRepository) : IMetaService { +class MetaServiceImpl(private val metaRepository: IMetaRepository, private val transaction: Transaction) : + IMetaService { override suspend fun getMeta(): Meta = - newSuspendedTransaction { metaRepository.get() ?: throw NotInitException("Meta is null") } + transaction.transaction { metaRepository.get() ?: throw NotInitException("Meta is null") } - override suspend fun updateMeta(meta: Meta) = newSuspendedTransaction { + override suspend fun updateMeta(meta: Meta) = transaction.transaction { metaRepository.save(meta) } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/core/ServerInitialiseServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/core/ServerInitialiseServiceImpl.kt index 6e9db865..1ca3c25f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/core/ServerInitialiseServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/core/ServerInitialiseServiceImpl.kt @@ -4,7 +4,6 @@ import dev.usbharu.hideout.domain.model.hideout.entity.Jwt import dev.usbharu.hideout.domain.model.hideout.entity.Meta import dev.usbharu.hideout.repository.IMetaRepository import dev.usbharu.hideout.util.ServerUtil -import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction import org.koin.core.annotation.Single import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -12,19 +11,23 @@ import java.security.KeyPairGenerator import java.util.* @Single -class ServerInitialiseServiceImpl(private val metaRepository: IMetaRepository) : IServerInitialiseService { +class ServerInitialiseServiceImpl( + private val metaRepository: IMetaRepository, + private val transaction: Transaction +) : + IServerInitialiseService { val logger: Logger = LoggerFactory.getLogger(ServerInitialiseServiceImpl::class.java) override suspend fun init() { - newSuspendedTransaction { + transaction.transaction { val savedMeta = metaRepository.get() val implementationVersion = ServerUtil.getImplementationVersion() if (wasInitialised(savedMeta).not()) { logger.info("Start Initialise") initialise(implementationVersion) logger.info("Finish Initialise") - return@newSuspendedTransaction + return@transaction } if (isVersionChanged(requireNotNull(savedMeta))) { diff --git a/src/main/kotlin/dev/usbharu/hideout/service/core/Transaction.kt b/src/main/kotlin/dev/usbharu/hideout/service/core/Transaction.kt new file mode 100644 index 00000000..40911be1 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/core/Transaction.kt @@ -0,0 +1,5 @@ +package dev.usbharu.hideout.service.core + +interface Transaction { + suspend fun transaction(block: suspend () -> T): T +} diff --git a/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt index 35c8ca50..3aaa4168 100644 --- a/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt @@ -26,6 +26,7 @@ import org.mockito.ArgumentMatchers.anyString import org.mockito.kotlin.doReturn import org.mockito.kotlin.eq import org.mockito.kotlin.mock +import utils.TestTransaction import java.time.Instant import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -69,7 +70,7 @@ class UsersAPTest { application { configureSerialization() routing { - usersAP(activityPubUserService, mock(), mock()) + usersAP(activityPubUserService, mock(), mock(), TestTransaction) } } client.get("/users/test") { @@ -127,7 +128,7 @@ class UsersAPTest { application { configureSerialization() routing { - usersAP(activityPubUserService, mock(), mock()) + usersAP(activityPubUserService, mock(), mock(), TestTransaction) } } client.get("/users/test") { @@ -188,7 +189,7 @@ class UsersAPTest { } application { routing { - usersAP(mock(), userService, mock()) + usersAP(mock(), userService, mock(), TestTransaction) } } client.get("/users/test") { diff --git a/src/test/kotlin/dev/usbharu/hideout/service/core/MetaServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/core/MetaServiceImplTest.kt index 9ba44f5c..02cf9e7e 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/core/MetaServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/core/MetaServiceImplTest.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import org.mockito.kotlin.* +import utils.TestTransaction import java.util.* import kotlin.test.assertEquals @@ -21,7 +22,7 @@ class MetaServiceImplTest { val metaRepository = mock { onBlocking { get() } doReturn meta } - val metaService = MetaServiceImpl(metaRepository) + val metaService = MetaServiceImpl(metaRepository, TestTransaction) val actual = metaService.getMeta() assertEquals(meta, actual) } @@ -31,7 +32,7 @@ class MetaServiceImplTest { val metaRepository = mock { onBlocking { get() } doReturn null } - val metaService = MetaServiceImpl(metaRepository) + val metaService = MetaServiceImpl(metaRepository, TestTransaction) assertThrows { metaService.getMeta() } } @@ -41,7 +42,7 @@ class MetaServiceImplTest { val metaRepository = mock { onBlocking { save(any()) } doReturn Unit } - val metaServiceImpl = MetaServiceImpl(metaRepository) + val metaServiceImpl = MetaServiceImpl(metaRepository, TestTransaction) metaServiceImpl.updateMeta(meta) argumentCaptor { verify(metaRepository).save(capture()) @@ -55,7 +56,7 @@ class MetaServiceImplTest { val metaRepository = mock { onBlocking { get() } doReturn meta } - val metaService = MetaServiceImpl(metaRepository) + val metaService = MetaServiceImpl(metaRepository, TestTransaction) val actual = metaService.getJwtMeta() assertEquals(meta.jwt, actual) } @@ -65,11 +66,7 @@ class MetaServiceImplTest { val metaRepository = mock { onBlocking { get() } doReturn null } - val metaService = MetaServiceImpl(metaRepository) - try { -// assertThrows { metaService.getJwtMeta() } - } catch (e: Exception) { - e.printStackTrace() - } + val metaService = MetaServiceImpl(metaRepository, TestTransaction) + assertThrows { metaService.getJwtMeta() } } } diff --git a/src/test/kotlin/dev/usbharu/hideout/service/core/ServerInitialiseServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/core/ServerInitialiseServiceImplTest.kt index 68367c14..c854754f 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/core/ServerInitialiseServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/core/ServerInitialiseServiceImplTest.kt @@ -10,6 +10,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Test import org.mockito.kotlin.* +import utils.TestTransaction import java.util.* import kotlin.test.assertEquals @@ -20,7 +21,7 @@ class ServerInitialiseServiceImplTest { onBlocking { get() } doReturn null onBlocking { save(any()) } doReturn Unit } - val serverInitialiseServiceImpl = ServerInitialiseServiceImpl(metaRepository) + val serverInitialiseServiceImpl = ServerInitialiseServiceImpl(metaRepository, TestTransaction) serverInitialiseServiceImpl.init() verify(metaRepository, times(1)).save(any()) @@ -32,7 +33,7 @@ class ServerInitialiseServiceImplTest { val metaRepository = mock { onBlocking { get() } doReturn meta } - val serverInitialiseServiceImpl = ServerInitialiseServiceImpl(metaRepository) + val serverInitialiseServiceImpl = ServerInitialiseServiceImpl(metaRepository, TestTransaction) serverInitialiseServiceImpl.init() verify(metaRepository, times(0)).save(any()) } @@ -45,7 +46,7 @@ class ServerInitialiseServiceImplTest { onBlocking { save(any()) } doReturn Unit } - val serverInitialiseServiceImpl = ServerInitialiseServiceImpl(metaRepository) + val serverInitialiseServiceImpl = ServerInitialiseServiceImpl(metaRepository, TestTransaction) serverInitialiseServiceImpl.init() verify(metaRepository, times(1)).save(any()) argumentCaptor { diff --git a/src/test/kotlin/utils/TestTransaction.kt b/src/test/kotlin/utils/TestTransaction.kt new file mode 100644 index 00000000..425372bd --- /dev/null +++ b/src/test/kotlin/utils/TestTransaction.kt @@ -0,0 +1,7 @@ +package utils + +import dev.usbharu.hideout.service.core.Transaction + +object TestTransaction : Transaction { + override suspend fun transaction(block: suspend () -> T): T = block() +}