From ba08f4da54461cb8b9b8020f0a4673e97796c7f8 Mon Sep 17 00:00:00 2001 From: vityaman Date: Sat, 25 May 2024 08:43:14 +0300 Subject: [PATCH 1/5] #123 Add OpenAPI operation id --- .../botalka/app/spring/api/http/endpoint/AuthHttpApi.kt | 2 +- .../app/spring/api/http/endpoint/HomeworkHttpApi.kt | 2 +- .../app/spring/api/http/endpoint/MonitoringHttpApi.kt | 2 +- .../app/spring/api/http/endpoint/PromotionHttpApi.kt | 4 ++-- .../botalka/app/spring/api/http/endpoint/UserHttpApi.kt | 4 ++-- botalka/src/main/resources/static/openapi/api.yml | 7 +++++++ .../vityaman/lms/botalka/app/spring/api/http/client/Api.kt | 2 +- .../lms/botalka/app/spring/api/http/client/Promotion.kt | 6 +++--- .../botalka/app/spring/api/http/endpoint/AuthApiTest.kt | 4 ++-- .../app/spring/api/http/endpoint/HomeworkApiTest.kt | 4 ++-- .../app/spring/api/http/endpoint/MonitoringApiTest.kt | 2 +- .../botalka/app/spring/api/http/endpoint/RatingApiTest.kt | 2 +- .../spring/api/http/endpoint/ResolvePromotionApiTest.kt | 2 +- 13 files changed, 25 insertions(+), 18 deletions(-) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/AuthHttpApi.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/AuthHttpApi.kt index a937924..0aff3f4 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/AuthHttpApi.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/AuthHttpApi.kt @@ -12,7 +12,7 @@ import ru.vityaman.lms.botalka.core.external.yandex.YandexOAuthCode class AuthHttpApi( private val yandex: SpringYandexOAuthService, ) : AuthApi { - override suspend fun authYandexCodePut( + override suspend fun authViaYandexCode( auth2ViaCodeMessage: Auth2ViaCodeMessage, ): ResponseEntity { val code = YandexOAuthCode(auth2ViaCodeMessage.code) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/HomeworkHttpApi.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/HomeworkHttpApi.kt index 274f669..74ccd43 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/HomeworkHttpApi.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/HomeworkHttpApi.kt @@ -29,7 +29,7 @@ class HomeworkHttpApi( @Autowired private val workspace: WorkspaceService, @Autowired private val authority: Authority, ) : HomeworkApi { - override suspend fun homeworkPost( + override suspend fun postHomework( homeworkDraftMessage: HomeworkDraftMessage, ): ResponseEntity { val draft = homeworkDraftMessage.toModel() diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/MonitoringHttpApi.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/MonitoringHttpApi.kt index 9cdc71c..01bb13c 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/MonitoringHttpApi.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/MonitoringHttpApi.kt @@ -6,6 +6,6 @@ import ru.vityaman.lms.botalka.app.spring.api.http.server.apis.MonitoringApi @RestController class MonitoringHttpApi : MonitoringApi { - override suspend fun monitoringPingGet(): ResponseEntity = + override suspend fun monitoringPing(): ResponseEntity = ResponseEntity.ok("pong") } diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/PromotionHttpApi.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/PromotionHttpApi.kt index a216835..ccb83b8 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/PromotionHttpApi.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/PromotionHttpApi.kt @@ -22,7 +22,7 @@ class PromotionHttpApi( @Autowired private val promotionService: PromotionService, @Autowired private val authority: Authority, ) : PromotionApi { - override suspend fun promotionRequestIdPatch( + override suspend fun patchPromotionRequest( id: Int, promotionRequestPatchMessage: PromotionRequestPatchMessage, ): ResponseEntity { @@ -54,7 +54,7 @@ class PromotionHttpApi( return ResponseEntity.status(HttpStatus.NO_CONTENT).build() } - override suspend fun promotionRequestPost( + override suspend fun postPromotionRequest( promotionRequestDraftMessage: PromotionRequestDraftMessage, ): ResponseEntity { val user = SpringSecurityContext.principal().id diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/UserHttpApi.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/UserHttpApi.kt index b7a0e32..8758119 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/UserHttpApi.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/UserHttpApi.kt @@ -20,14 +20,14 @@ class UserHttpApi( @Autowired private val userService: UserService, @Autowired private val auth: SpringYandexOAuthService, ) : UserApi { - override suspend fun userIdGet(id: Int): ResponseEntity { + override suspend fun getUserById(id: Int): ResponseEntity { val userId = User.Id(id) val user = userService.getById(userId) .orNotFound("User with id ${userId.number} not found") return ResponseEntity.ok(user.toMessage()) } - override suspend fun userPost( + override suspend fun postUser( postUserRequestMessage: PostUserRequestMessage, ): ResponseEntity { val draft = postUserRequestMessage.user.toModel() diff --git a/botalka/src/main/resources/static/openapi/api.yml b/botalka/src/main/resources/static/openapi/api.yml index e27754a..36569c9 100644 --- a/botalka/src/main/resources/static/openapi/api.yml +++ b/botalka/src/main/resources/static/openapi/api.yml @@ -8,6 +8,7 @@ paths: /monitoring/ping: get: tags: [ Monitoring ] + operationId: monitoringPing summary: Checks if service is alive description: Returns 'pong', if service is alive, else we will cry responses: @@ -21,6 +22,7 @@ paths: /homework: post: tags: [ Homework ] + operationId: postHomework summary: Creates a homework description: Creates a homework to be published at specified time security: @@ -154,6 +156,7 @@ paths: /user/{id}: get: tags: [ User ] + operationId: getUserById summary: Find a user by its id description: Find a user by its id security: @@ -186,6 +189,7 @@ paths: /user: post: tags: [ User ] + operationId: postUser summary: Creates a new user description: Creates a new user requestBody: @@ -211,6 +215,7 @@ paths: /promotion/request: post: tags: [ User ] + operationId: postPromotionRequest summary: Request for a user role promotion description: | Creates a promotion request that needs to be approved @@ -252,6 +257,7 @@ paths: /promotion/request/{id}: patch: tags: [ User ] + operationId: patchPromotionRequest summary: Updates a promotion request status description: | Used by admin to approve or cancel promotion request. @@ -295,6 +301,7 @@ paths: /auth/yandex/code: put: tags: [ Auth ] + operationId: authViaYandexCode summary: Authenticate via Yandex ID authentication code description: Takes an authentication code and checks authority requestBody: diff --git a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/client/Api.kt b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/client/Api.kt index 67491b9..a53efba 100644 --- a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/client/Api.kt +++ b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/client/Api.kt @@ -48,7 +48,7 @@ class Api private constructor( private suspend fun ofRegisteredAs(message: PostUserRequestMessage) = ofNewbie().user - .userPost(message) + .postUser(message) .awaitSingle() .let { Api(Data(it.user.id, it.token)) } diff --git a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/client/Promotion.kt b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/client/Promotion.kt index 8e3b893..4e8ecd3 100644 --- a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/client/Promotion.kt +++ b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/client/Promotion.kt @@ -3,14 +3,14 @@ package ru.vityaman.lms.botalka.app.spring.api.http.client import kotlinx.coroutines.reactor.awaitSingle suspend fun Api.requestRole(role: UserRoleMessage): Int = - user.promotionRequestPost( + user.postPromotionRequest( PromotionRequestDraftMessage( role = role, ), ).awaitSingle().id suspend fun Api.approve(requestId: Int): Unit = - user.promotionRequestIdPatch( + user.patchPromotionRequest( requestId, PromotionRequestPatchMessage( status = PromotionRequestStatusMessage.approved, @@ -18,7 +18,7 @@ suspend fun Api.approve(requestId: Int): Unit = ).awaitSingle() suspend fun Api.reject(requestId: Int): Unit = - user.promotionRequestIdPatch( + user.patchPromotionRequest( requestId, PromotionRequestPatchMessage( status = PromotionRequestStatusMessage.canceled, diff --git a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/AuthApiTest.kt b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/AuthApiTest.kt index 623ebb2..4c38040 100644 --- a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/AuthApiTest.kt +++ b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/AuthApiTest.kt @@ -15,7 +15,7 @@ class AuthApiTest : BotalkaTestSuite() { fun yandexCodeSmoking(): Unit = runBlocking { val api = Api.ofNewbie() - api.user.userPost( + api.user.postUser( PostUserRequestMessage( user = UserDraftMessage("tester"), credential = Auth2ViaCodeMessage( @@ -25,7 +25,7 @@ class AuthApiTest : BotalkaTestSuite() { ), ).awaitSingle() - api.auth.authYandexCodePut( + api.auth.authViaYandexCode( Auth2ViaCodeMessage( kind = CredentialKindMessage.yandex_code, code = 654_321, diff --git a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/HomeworkApiTest.kt b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/HomeworkApiTest.kt index 1b3f3fc..2db5a53 100644 --- a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/HomeworkApiTest.kt +++ b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/HomeworkApiTest.kt @@ -60,7 +60,7 @@ class HomeworkApiTest : BotalkaTestSuite() { val draftToResultList = drafts.map { draft -> val result = async { - tester.homework.homeworkPost(draft).awaitSingle() + tester.homework.postHomework(draft).awaitSingle() } Pair(draft, result) }.map { (draft, result) -> @@ -121,7 +121,7 @@ class HomeworkApiTest : BotalkaTestSuite() { publicationMoment: OffsetDateTime, deadlineMoment: OffsetDateTime, ) { - this.homework.homeworkPost( + this.homework.postHomework( sampleHomework( publicationMoment = publicationMoment, deadlineMoment = deadlineMoment, diff --git a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/MonitoringApiTest.kt b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/MonitoringApiTest.kt index a5b44bd..c1f2d54 100644 --- a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/MonitoringApiTest.kt +++ b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/MonitoringApiTest.kt @@ -11,7 +11,7 @@ class MonitoringApiTest : BotalkaTestSuite() { @Test fun pingSucceeds(): Unit = runBlocking { val api = Api.ofNewbie() - val body = api.monitoring.monitoringPingGet().awaitSingle() + val body = api.monitoring.monitoringPing().awaitSingle() assertEquals(body, "pong") } } diff --git a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/RatingApiTest.kt b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/RatingApiTest.kt index 02efb74..a02d5e1 100644 --- a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/RatingApiTest.kt +++ b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/RatingApiTest.kt @@ -99,7 +99,7 @@ class RatingApiTest : BotalkaTestSuite() { } private suspend fun Api.homeworkPost(draft: HomeworkDraftMessage): Int = - homework.homeworkPost(draft).awaitSingle().id + homework.postHomework(draft).awaitSingle().id private suspend fun Api.submit(homework: Int) = this.homework.postEvent( diff --git a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/ResolvePromotionApiTest.kt b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/ResolvePromotionApiTest.kt index ce76679..7d4fa3c 100644 --- a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/ResolvePromotionApiTest.kt +++ b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/ResolvePromotionApiTest.kt @@ -94,5 +94,5 @@ class ResolvePromotionApiTest : BotalkaTestSuite() { } private suspend fun roles(id: Int) = - admin.user.userIdGet(id).awaitSingle().roles + admin.user.getUserById(id).awaitSingle().roles } From 385105982ecd136d2c703c016d93805a27a4b3cc Mon Sep 17 00:00:00 2001 From: vityaman Date: Sat, 25 May 2024 08:50:14 +0300 Subject: [PATCH 2/5] #123 Fix compilation --- .../botalka/app/spring/api/http/endpoint/WorkspaceApiTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/WorkspaceApiTest.kt b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/WorkspaceApiTest.kt index 3003056..85a6d2e 100644 --- a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/WorkspaceApiTest.kt +++ b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/WorkspaceApiTest.kt @@ -54,7 +54,7 @@ class WorkspaceApiTest( this.student = student this.teacher = teacher - homework = teacher.homework.homeworkPost( + homework = teacher.homework.postHomework( HomeworkDraftMessage( title = "Title Any", description = "Description Any", @@ -101,7 +101,7 @@ class WorkspaceApiTest( @Test @Suppress("FunctionMaxLength") fun cantSubmitSolutionAfterDeadline(): Unit = runBlocking { - homework = teacher.homework.homeworkPost( + homework = teacher.homework.postHomework( HomeworkDraftMessage( title = "Expired Homework", description = "Description", From 517aeb95a8711a77121137d2de8d36b360ce24f7 Mon Sep 17 00:00:00 2001 From: Victor Smirnov <53015676+vityaman@users.noreply.github.com> Date: Sat, 25 May 2024 08:36:20 +0300 Subject: [PATCH 3/5] #121 Make domain exceptions sealed (#129) --- .../app/spring/api/http/error/DomainExceptionCodes.kt | 9 ++++----- .../app/spring/security/SpringJwtContextRepository.kt | 2 +- .../{security => }/exception/AuthenticationException.kt | 2 +- .../{security => }/exception/AuthorizationException.kt | 2 +- .../lms/botalka/core/exception/DomainException.kt | 2 +- .../lms/botalka/core/exception/SecurityException.kt | 4 ++++ .../core/exception/ServiceUnavailableException.kt | 7 +++++++ .../core/external/yandex/YandexUnavailableException.kt | 4 ++-- .../botalka/core/security/exception/SecurityException.kt | 6 ------ .../botalka/core/security/persmission/AuthorizedUser.kt | 2 +- 10 files changed, 22 insertions(+), 18 deletions(-) rename botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/{security => }/exception/AuthenticationException.kt (67%) rename botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/{security => }/exception/AuthorizationException.kt (95%) create mode 100644 botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/SecurityException.kt create mode 100644 botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/ServiceUnavailableException.kt delete mode 100644 botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/security/exception/SecurityException.kt diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/error/DomainExceptionCodes.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/error/DomainExceptionCodes.kt index dc3b5cb..18cf99b 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/error/DomainExceptionCodes.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/error/DomainExceptionCodes.kt @@ -4,14 +4,14 @@ import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import ru.vityaman.lms.botalka.app.spring.api.http.server.GeneralErrorMessage import ru.vityaman.lms.botalka.core.exception.AlreadyAskedPromotionException +import ru.vityaman.lms.botalka.core.exception.AuthenticationException +import ru.vityaman.lms.botalka.core.exception.AuthorizationException import ru.vityaman.lms.botalka.core.exception.DeadlinePassedException import ru.vityaman.lms.botalka.core.exception.DomainException import ru.vityaman.lms.botalka.core.exception.InvalidValueException import ru.vityaman.lms.botalka.core.exception.NotFoundException import ru.vityaman.lms.botalka.core.exception.PromotionRequestResolvedException -import ru.vityaman.lms.botalka.core.external.yandex.YandexUnavailableException -import ru.vityaman.lms.botalka.core.security.exception.AuthenticationException -import ru.vityaman.lms.botalka.core.security.exception.AuthorizationException +import ru.vityaman.lms.botalka.core.exception.ServiceUnavailableException val DomainException.httpCode: HttpStatus get() = when (this) { @@ -22,8 +22,7 @@ val DomainException.httpCode: HttpStatus is DeadlinePassedException -> HttpStatus.BAD_REQUEST is AuthenticationException -> HttpStatus.UNAUTHORIZED is AuthorizationException -> HttpStatus.FORBIDDEN - is YandexUnavailableException -> HttpStatus.SERVICE_UNAVAILABLE - else -> TODO("Unexpected domain exception $this") + is ServiceUnavailableException -> HttpStatus.SERVICE_UNAVAILABLE } fun DomainException.toResponseEntity() = diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/security/SpringJwtContextRepository.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/security/SpringJwtContextRepository.kt index 0cce93c..08d1dc1 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/security/SpringJwtContextRepository.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/app/spring/security/SpringJwtContextRepository.kt @@ -12,8 +12,8 @@ import org.springframework.stereotype.Component import org.springframework.web.server.ServerWebExchange import reactor.core.publisher.Mono import ru.vityaman.lms.botalka.app.spring.api.http.error.DomainExceptionMarshalling +import ru.vityaman.lms.botalka.core.exception.AuthenticationException import ru.vityaman.lms.botalka.core.exception.DomainException -import ru.vityaman.lms.botalka.core.security.exception.AuthenticationException @Component class SpringJwtContextRepository( diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/security/exception/AuthenticationException.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/AuthenticationException.kt similarity index 67% rename from botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/security/exception/AuthenticationException.kt rename to botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/AuthenticationException.kt index 4ef4865..d3713bb 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/security/exception/AuthenticationException.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/AuthenticationException.kt @@ -1,4 +1,4 @@ -package ru.vityaman.lms.botalka.core.security.exception +package ru.vityaman.lms.botalka.core.exception class AuthenticationException(message: String, cause: Throwable? = null) : SecurityException(message, cause) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/security/exception/AuthorizationException.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/AuthorizationException.kt similarity index 95% rename from botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/security/exception/AuthorizationException.kt rename to botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/AuthorizationException.kt index 2823ba1..3f65b29 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/security/exception/AuthorizationException.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/AuthorizationException.kt @@ -1,4 +1,4 @@ -package ru.vityaman.lms.botalka.core.security.exception +package ru.vityaman.lms.botalka.core.exception import ru.vityaman.lms.botalka.core.model.User import ru.vityaman.lms.botalka.core.security.persmission.Permission diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/DomainException.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/DomainException.kt index b0c7d7e..7d2e3f4 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/DomainException.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/DomainException.kt @@ -1,4 +1,4 @@ package ru.vityaman.lms.botalka.core.exception -open class DomainException(message: String, cause: Throwable? = null) : +sealed class DomainException(message: String, cause: Throwable? = null) : Exception(message, cause) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/SecurityException.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/SecurityException.kt new file mode 100644 index 0000000..67ae1d3 --- /dev/null +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/SecurityException.kt @@ -0,0 +1,4 @@ +package ru.vityaman.lms.botalka.core.exception + +sealed class SecurityException(message: String, cause: Throwable? = null) : + DomainException(message, cause) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/ServiceUnavailableException.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/ServiceUnavailableException.kt new file mode 100644 index 0000000..80ac531 --- /dev/null +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/exception/ServiceUnavailableException.kt @@ -0,0 +1,7 @@ +package ru.vityaman.lms.botalka.core.exception + +open class ServiceUnavailableException( + message: String, + cause: Throwable? = null, +) : + DomainException(message, cause) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/external/yandex/YandexUnavailableException.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/external/yandex/YandexUnavailableException.kt index 4112ae0..0caa05c 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/external/yandex/YandexUnavailableException.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/external/yandex/YandexUnavailableException.kt @@ -1,9 +1,9 @@ package ru.vityaman.lms.botalka.core.external.yandex -import ru.vityaman.lms.botalka.core.exception.DomainException +import ru.vityaman.lms.botalka.core.exception.ServiceUnavailableException class YandexUnavailableException( string: String = "Yandex is unavailable", cause: Throwable? = null, ) : - DomainException(string, cause) + ServiceUnavailableException(string, cause) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/security/exception/SecurityException.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/security/exception/SecurityException.kt deleted file mode 100644 index e96d297..0000000 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/security/exception/SecurityException.kt +++ /dev/null @@ -1,6 +0,0 @@ -package ru.vityaman.lms.botalka.core.security.exception - -import ru.vityaman.lms.botalka.core.exception.DomainException - -open class SecurityException(message: String, cause: Throwable? = null) : - DomainException(message, cause) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/security/persmission/AuthorizedUser.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/security/persmission/AuthorizedUser.kt index 7e48bcd..108e60d 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/security/persmission/AuthorizedUser.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/core/security/persmission/AuthorizedUser.kt @@ -1,7 +1,7 @@ package ru.vityaman.lms.botalka.core.security.persmission +import ru.vityaman.lms.botalka.core.exception.AuthorizationException import ru.vityaman.lms.botalka.core.model.User -import ru.vityaman.lms.botalka.core.security.exception.AuthorizationException class AuthorizedUser( private val authority: Authority, From 1663c9b3909787ba05660d5e0cdcd3a86c48e132 Mon Sep 17 00:00:00 2001 From: Victor Smirnov <53015676+vityaman@users.noreply.github.com> Date: Sat, 25 May 2024 08:38:48 +0300 Subject: [PATCH 4/5] #128 Check EnumBiMap for exhaustion (#130) --- .../ru/vityaman/lms/botalka/commons/BiMap.kt | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/commons/BiMap.kt b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/commons/BiMap.kt index b19c2ef..3ad53bf 100644 --- a/botalka/src/main/kotlin/ru/vityaman/lms/botalka/commons/BiMap.kt +++ b/botalka/src/main/kotlin/ru/vityaman/lms/botalka/commons/BiMap.kt @@ -1,7 +1,9 @@ package ru.vityaman.lms.botalka.commons import java.util.EnumMap +import kotlin.enums.enumEntries +@OptIn(ExperimentalStdlibApi::class) interface BiMap { fun toRight(value: T): U fun toLeft(value: U): T @@ -9,18 +11,24 @@ interface BiMap { companion object { inline fun , reified U : Enum> from( vararg pairs: Pair, - ): BiMap = - object : BiMap { - private val rhs = pairs - .associateTo(EnumMap(T::class.java)) { (l, r) -> l to r } - - private val lhs = pairs - .associateTo(EnumMap(U::class.java)) { (l, r) -> r to l } + ): BiMap = object : BiMap { + private val rhs = pairs + .associateTo(EnumMap(T::class.java)) { (l, r) -> l to r } + + private val lhs = pairs + .associateTo(EnumMap(U::class.java)) { (l, r) -> r to l } + + init { + val left = pairs.map { it.first }.toSet() + val right = pairs.map { it.second }.toSet() + require(left.size == right.size) + require(enumEntries().size == left.size) + } - override fun toRight(value: T): U = rhs[value]!! + override fun toRight(value: T): U = rhs[value]!! - override fun toLeft(value: U): T = lhs[value]!! - } + override fun toLeft(value: U): T = lhs[value]!! + } @JvmName("BiMapLeftToRight") operator fun BiMap.invoke(value: T): U = From dfb9b0e7311e192f2fd6a977964c4367ab1f6df3 Mon Sep 17 00:00:00 2001 From: vityaman Date: Sat, 25 May 2024 08:59:12 +0300 Subject: [PATCH 5/5] #123 Fix compilation --- .../botalka/app/spring/api/http/endpoint/UserApiTest.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/UserApiTest.kt b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/UserApiTest.kt index 425ef30..e45d2e4 100644 --- a/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/UserApiTest.kt +++ b/botalka/src/test/kotlin/ru/vityaman/lms/botalka/app/spring/api/http/endpoint/UserApiTest.kt @@ -38,7 +38,7 @@ class UserApiTest : BotalkaTestSuite() { draft.user, async { Api.ofNewbie().user - .userPost(draft) + .postUser(draft) .awaitSingle() .user }, @@ -53,7 +53,7 @@ class UserApiTest : BotalkaTestSuite() { }.onEach { expected -> launch { val actual = admin.user - .userIdGet(expected.id) + .getUserById(expected.id) .awaitSingle() expected.id shouldBe actual.id expected.alias shouldBe actual.alias @@ -65,7 +65,7 @@ class UserApiTest : BotalkaTestSuite() { @Test fun userNotFound(): Unit = runBlocking { assertThrows { - admin.user.userIdGet(666).awaitSingle() + admin.user.getUserById(666).awaitSingle() } } @@ -76,7 +76,7 @@ class UserApiTest : BotalkaTestSuite() { repeat(2) { launch { val draft = UserDraftMessage("vanechka") - Api.ofNewbie().user.userPost( + Api.ofNewbie().user.postUser( PostUserRequestMessage( user = draft, credential = Auth2ViaCodeMessage(