Skip to content

Commit

Permalink
[refactor]: gallery, 인증 도메인에 에러 핸들러 추가 (#397)
Browse files Browse the repository at this point in the history
  • Loading branch information
devxb authored Mar 7, 2024
2 parents e607a38 + 55d84f6 commit 5059c82
Show file tree
Hide file tree
Showing 34 changed files with 597 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,7 @@ public static void assertIsSurveyDoesNotExists(ResultActions resultActions) thro
}

public static void assertIsBookmarked(ResultActions resultActions) throws Exception {
resultActions.andExpectAll(
status().isOk(),
content().contentType(MediaType.APPLICATION_JSON),
jsonPath("$.target_id").isString(),
jsonPath("$.survey_id").isString(),
jsonPath("$.nickname").isString(),
jsonPath("$.position").doesNotExist(),
jsonPath("$.image_url").doesNotExist()
);
resultActions.andExpectAll(status().isOk());
}

}
3 changes: 2 additions & 1 deletion auth/auth-interceptor/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
dependencies {
implementation project(':auth:auth-application')

implementation project(':core:exception-handler')

implementation 'org.springframework.boot:spring-boot-starter-web'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package me.nalab.auth.interceptor;

import me.nalab.core.exception.handler.ErrorTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class AuthExceptionAdvice {

@ExceptionHandler(CannotValidTokenException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public ErrorTemplate handleCannotValidTokenException(CannotValidTokenException exception) {
return ErrorTemplate.of(exception.getMessage());
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package me.nalab.auth.interceptor;

public class CannotValidTokenException extends RuntimeException {

public CannotValidTokenException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,20 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons
if (!isExcludedURI(request)) {
String token = request.getHeader("Authorization");
throwIfCannotValidToken(token);
Long targetId = targetIdGetPort.getTargetId(token.split(" ")[1]);
Long targetId = getTargetId(token);
request.setAttribute("logined", targetId);
}
return true;
}

private Long getTargetId(String token) {
try {
return targetIdGetPort.getTargetId(token.split(" ")[1]);
} catch (Exception exception) {
throw new CannotValidTokenException(exception.getMessage());
}
}

private boolean isPreflight(HttpServletRequest request) {
return request.getMethod().equals("OPTIONS");
}
Expand Down Expand Up @@ -63,7 +71,7 @@ private boolean isExcludedURI(HttpServletRequest httpServletRequest) {

private void throwIfCannotValidToken(String token) {
if (token == null) {
throw new CannotValidMockTokenException();
throw new CannotValidTokenException("Null token");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ public class JwtDecryptInterceptorConfigurer implements WebMvcConfigurer {
"/v1/users",
"/v1/gallerys/previews",
"/v1/surveys/*/bookmarks",
"/v1/surveys/*/bookmarks/cancels",
"/v1/gallerys/logins",
"/v1/gallerys",
"/v1/surveys/bookmarks*",
};

@Override
Expand Down
7 changes: 0 additions & 7 deletions auth/auth-interceptor/src/main/java/module-info.java

This file was deleted.

3 changes: 2 additions & 1 deletion gallery/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ repositories {

dependencies {
implementation project(":core:data")
implementation project(":core:id-generator:id-core")
implementation project(":core:time")
implementation project(":core:exception-handler")
implementation project(":survey:survey-application")
implementation project(":core:id-generator:id-core")

implementation "org.springframework.boot:spring-boot-starter-web"
implementation "org.springframework.boot:spring-boot-starter-data-jpa"
Expand Down
6 changes: 3 additions & 3 deletions gallery/src/main/kotlin/me/nalab/gallery/app/GalleryGetApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ class GalleryGetApp(
}

private fun getPage(page: Int, count: Int, orderType: String): Pageable {
return when (orderType.lowercase()) {
"update" -> PageRequest.of(page, count, Sort.by("updateOrder").descending())
"job" -> PageRequest.of(page, count, Sort.by("survey.bookmarkedCount").descending())
return when (orderType.uppercase()) {
"UPDATE" -> PageRequest.of(page, count, Sort.by("updateOrder").descending())
"BOOKMARK" -> PageRequest.of(page, count, Sort.by("survey.bookmarkedCount").descending())
else -> throw IllegalArgumentException("orderType 은 update와 bookmark중 하나여야 합니다. 현재 orderType \"$orderType\"")
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package me.nalab.gallery.controller

import me.nalab.core.exception.handler.ErrorTemplate
import me.nalab.gallery.app.GalleryGetApp
import me.nalab.gallery.app.GalleryPreviewApp
import me.nalab.gallery.app.GalleryRegisterApp
Expand Down Expand Up @@ -40,12 +41,16 @@ class GalleryController(
@GetMapping
@ResponseStatus(HttpStatus.OK)
fun getGalleries(
@RequestParam(name = "job", defaultValue = "all") job: String,
@RequestParam(name = "job", defaultValue = "ALL") job: String,
@RequestParam(name = "page", defaultValue = "0") page: Int,
@RequestParam(name = "count", defaultValue = "5") count: Int,
@RequestParam(name = "order-type", defaultValue = "update") orderType: String
@RequestParam(name = "order-type", defaultValue = "UPDATE") orderType: String
): GalleriesDto {
return galleryGetApp.getGalleries(job, page, count, orderType)
}

@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(IllegalArgumentException::class)
fun handleIllegalArgumentException(exception: IllegalArgumentException): ErrorTemplate =
ErrorTemplate.of(exception.message ?: "잘못된 요청입니다.")
}
8 changes: 7 additions & 1 deletion gallery/src/main/kotlin/me/nalab/gallery/domain/Gallery.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,13 @@ class Gallery(

fun getBookmarkedCount(): Int = survey.bookmarkedCount

fun increaseBookmarkedCount() {
fun increaseBookmarkCount() {
survey.bookmarkedCount++
}

fun decreaseBookmarkCount() {
survey.bookmarkedCount--
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,17 @@ class GalleryService(

@Transactional
fun increaseBookmarkCount(targetId: Long) {
galleryRepository.findByTargetIdOrNull(targetId)?.increaseBookmarkedCount()
galleryRepository.findByTargetIdOrNull(targetId)?.increaseBookmarkCount()
}

@Transactional
fun decreaseBookmarkCount(targetId: Long) {
galleryRepository.findByTargetIdOrNull(targetId)?.decreaseBookmarkCount()
}

fun getGalleries(job: String, pageable: Pageable): Page<Gallery> {
val jobs = when (job) {
"all" -> Job.entries.toList()
val jobs = when (job.uppercase()) {
"ALL" -> Job.entries.toList()
else -> listOf(Job.valueOf(job.uppercase()))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,38 @@ class SurveyBookmarkedListener(
) : SurveyBookmarkListenPort {

@Async
override fun listenBookmarked(targetId: Long) {
override fun increaseBookmarked(targetId: Long) {
runCatching {
galleryService.increaseBookmarkCount(targetId)
}.recoverCatching {
when (it is OptimisticLockingFailureException) {
true -> {
waitJitter()
listenBookmarked(targetId)
increaseBookmarked(targetId)
}

false -> throw it
}
}
}

@Async
override fun decreaseBookmarked(targetId: Long) {
runCatching {
galleryService.decreaseBookmarkCount(targetId)
}.recoverCatching {
when (it is OptimisticLockingFailureException) {
true -> {
waitJitter()
decreaseBookmarked(targetId)
}

false -> throw it
}
}
}


private fun waitJitter() {
Thread.sleep(Random.nextLong(500, 1000))
}
Expand Down
5 changes: 0 additions & 5 deletions support/e2e/v1_10_get_logined_gallery.hurl
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,6 @@ Authorization: {{ token_type }} {{ auth_token }}

HTTP 200
[Asserts]
header "Content-type" == "application/json"

jsonpath "$.target_id" == {{ target_id }}
jsonpath "$.survey_id" == {{ survey_id }}
jsonpath "$.nickname" == "logined_gallery"

##########

Expand Down
116 changes: 116 additions & 0 deletions support/e2e/v1_11_cancel_bookmark_survey.hurl
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
POST http://nalab-server:8080/v1/oauth/default # Default provider를 통해서 로그인 진행
{
"nickname": "cancel_bookmark_survey",
"email": "cancel_bookmark_survey@123456"
}

HTTP 200
[Asserts]
header "Content-type" == "application/json"

jsonpath "$.access_token" exists
jsonpath "$.token_type" exists

[Captures]
token_type: jsonpath "$.token_type"
auth_token: jsonpath "$.access_token"

##########

POST http://nalab-server:8080/v1/surveys # 발급받은 토큰으로 survey를 생성한다.
Authorization: {{ token_type }} {{ auth_token }}
{
"question_count": 2,
"question": [
{
"type": "choice",
"form_type": "tendency",
"title": "저는 UI, UI, GUI 중에 어떤 분야를 가장 잘하는 것 같나요?",
"choices": [
{
"content": "UI",
"order": 1
},
{
"content": "UX",
"order": 2
},
{
"content": "GUI",
"order": 3
}
],
"max_selectable_count": 1,
"order": 1
},
{
"type": "short",
"form_type": "strength",
"title": "저는 UX, UI, GUI 중에 어떤 분야에 더 강점이 있나요?",
"order": 2
}
]
}

HTTP 201
[Asserts]
header "Content-type" == "application/json"

jsonpath "$.survey_id" exists

[Captures]
survey_id: jsonpath "$.survey_id"

##########

GET http://nalab-server:8080/v1/surveys/{{ survey_id }} # 생성된 survey를 조회한다.

HTTP 200
[Asserts]
header "Content-type" == "application/json"

jsonpath "$.survey_id" exists

jsonpath "$.target.id" exists
jsonpath "$.target.nickname" == "cancel_bookmark_survey"

jsonpath "$.question_count" == 2
jsonpath "$.question.[0].question_id" exists
jsonpath "$.question.[0].type" == "choice"
jsonpath "$.question.[0].form_type" == "tendency"
jsonpath "$.question.[0].title" == "저는 UI, UI, GUI 중에 어떤 분야를 가장 잘하는 것 같나요?"
jsonpath "$.question.[0].order" == 1
jsonpath "$.question.[0].max_selectable_count" == 1
jsonpath "$.question.[0].choices.[0].choice_id" exists
jsonpath "$.question.[0].choices.[0].content" == "UI"
jsonpath "$.question.[0].choices.[0].order" == 1
jsonpath "$.question.[0].choices.[1].choice_id" exists
jsonpath "$.question.[0].choices.[1].content" == "UX"
jsonpath "$.question.[0].choices.[1].order" == 2
jsonpath "$.question.[0].choices.[2].choice_id" exists
jsonpath "$.question.[0].choices.[2].content" == "GUI"
jsonpath "$.question.[0].choices.[2].order" == 3
jsonpath "$.question.[1].question_id" exists
jsonpath "$.question.[1].type" == "short"
jsonpath "$.question.[1].form_type" == "strength"
jsonpath "$.question.[1].title" == "저는 UX, UI, GUI 중에 어떤 분야에 더 강점이 있나요?"
jsonpath "$.question.[1].order" == 2

[Captures]
target_id: jsonpath "$.target.id"

##########

POST http://nalab-server:8080/v1/surveys/{{ survey_id }}/bookmarks
Authorization: {{ token_type }} {{ auth_token }}

HTTP 200
[Asserts]

##########

POST http://nalab-server:8080/v1/surveys/{{ survey_id }}/bookmarks/cancels
Authorization: {{ token_type }} {{ auth_token }}

HTTP 200
[Asserts]
Loading

0 comments on commit 5059c82

Please sign in to comment.