-
Notifications
You must be signed in to change notification settings - Fork 2
ev-service 마이그레이션 #308
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
ev-service 마이그레이션 #308
Changes from 16 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
82b9922
ev-service 마이그레이션
asp345 dfbd1c8
/v1/users/me/lectures/latest 마이그레이션
asp345 1e6d62d
dto 분리
asp345 7301714
service 분리 및 최근 과목 수정
asp345 f4465d7
handle empty body
asp345 0f00915
fix endpoint
asp345 774bfa4
응답의 user_id 사용자 정보로 교체
asp345 9a392cd
throw errors from ev
asp345 e14d853
add headers
asp345 4013766
suppress unchecked cast warning
asp345 563f222
webclient 오류 그대로 넘겨주기
asp345 04a15fd
serialize error body
asp345 c1e07a3
Merge remote-tracking branch 'origin/develop' into feature/ev-service
asp345 94709ce
에러 핸들링 수정
asp345 b0faccf
url 변환 수정
asp345 077fd3b
use DI for objectMapper
asp345 ca95dd6
remove snake case
asp345 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| package com.wafflestudio.snu4t.handler | ||
|
|
||
| import com.wafflestudio.snu4t.evaluation.service.EvService | ||
| import com.wafflestudio.snu4t.middleware.SnuttRestApiDefaultMiddleware | ||
| import kotlinx.coroutines.reactor.awaitSingleOrNull | ||
| import org.springframework.http.HttpMethod | ||
| import org.springframework.stereotype.Component | ||
| import org.springframework.web.reactive.function.server.ServerRequest | ||
| import org.springframework.web.reactive.function.server.bodyToMono | ||
|
|
||
| @Component | ||
| class EvServiceHandler( | ||
| private val evService: EvService, | ||
| snuttRestApiDefaultMiddleware: SnuttRestApiDefaultMiddleware, | ||
| ) : ServiceHandler(snuttRestApiDefaultMiddleware) { | ||
| suspend fun handleGet(req: ServerRequest) = | ||
| handle(req) { | ||
| val body = req.bodyToMono<String>().awaitSingleOrNull() ?: "" | ||
| evService.handleRouting(req.userId, req.pathVariable("requestPath"), req.queryParams(), body, HttpMethod.GET) | ||
| } | ||
|
|
||
| suspend fun handlePost(req: ServerRequest) = | ||
| handle(req) { | ||
| val body = req.bodyToMono<String>().awaitSingleOrNull() ?: "" | ||
| evService.handleRouting(req.userId, req.pathVariable("requestPath"), req.queryParams(), body, HttpMethod.POST) | ||
| } | ||
|
|
||
| suspend fun handleDelete(req: ServerRequest) = | ||
| handle(req) { | ||
| val body = req.bodyToMono<String>().awaitSingleOrNull() ?: "" | ||
| evService.handleRouting(req.userId, req.pathVariable("requestPath"), req.queryParams(), body, HttpMethod.DELETE) | ||
| } | ||
|
|
||
| suspend fun handlePatch(req: ServerRequest) = | ||
| handle(req) { | ||
| val body = req.bodyToMono<String>().awaitSingleOrNull() ?: "" | ||
| evService.handleRouting(req.userId, req.pathVariable("requestPath"), req.queryParams(), body, HttpMethod.PATCH) | ||
| } | ||
|
|
||
| suspend fun getMyLatestLectures(req: ServerRequest) = | ||
| handle(req) { | ||
| evService.getMyLatestLectures(req.userId, req.queryParams()) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
core/src/main/kotlin/common/exception/EvServiceProxyException.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| package com.wafflestudio.snu4t.common.exception | ||
|
|
||
| import org.springframework.http.HttpStatusCode | ||
|
|
||
| class EvServiceProxyException( | ||
| val statusCode: HttpStatusCode, | ||
| val errorBody: Map<String, Any?>, | ||
| ) : RuntimeException() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| package com.wafflestudio.snu4t.evaluation.dto | ||
|
|
||
| import com.fasterxml.jackson.annotation.JsonProperty | ||
| import com.wafflestudio.snu4t.common.enum.Semester | ||
| import com.wafflestudio.snu4t.timetables.data.TimetableLecture | ||
|
|
||
| data class EvLectureInfoDto( | ||
| val year: Int, | ||
| val semester: Int, | ||
| val instructor: String?, | ||
| @JsonProperty("course_number") | ||
| val courseNumber: String?, | ||
| ) | ||
|
|
||
| fun EvLectureInfoDto( | ||
| timetableLecture: TimetableLecture, | ||
| year: Int, | ||
| semester: Semester, | ||
| ): EvLectureInfoDto = | ||
| EvLectureInfoDto( | ||
| year = year, | ||
| semester = semester.value, | ||
| instructor = timetableLecture.instructor, | ||
| courseNumber = timetableLecture.courseNumber, | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.wafflestudio.snu4t.evaluation.dto | ||
|
|
||
| import com.wafflestudio.snu4t.users.data.User | ||
|
|
||
| data class EvUserDto( | ||
| val id: String?, | ||
| val email: String?, | ||
| val local_id: String?, | ||
| ) | ||
|
|
||
| fun EvUserDto(user: User) = | ||
| EvUserDto( | ||
| id = user.id, | ||
| email = user.email, | ||
| local_id = user.credential.localId, | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| package com.wafflestudio.snu4t.evaluation.service | ||
|
|
||
| import com.fasterxml.jackson.databind.ObjectMapper | ||
| import com.wafflestudio.snu4t.common.exception.EvServiceProxyException | ||
| import com.wafflestudio.snu4t.common.util.buildMultiValueMap | ||
| import com.wafflestudio.snu4t.config.SnuttEvWebClient | ||
| import com.wafflestudio.snu4t.coursebook.service.CoursebookService | ||
| import com.wafflestudio.snu4t.evaluation.dto.EvLectureInfoDto | ||
| import com.wafflestudio.snu4t.evaluation.dto.EvUserDto | ||
| import com.wafflestudio.snu4t.timetables.service.TimetableService | ||
| import com.wafflestudio.snu4t.users.service.UserService | ||
| import kotlinx.coroutines.flow.toList | ||
| import kotlinx.coroutines.reactor.awaitSingle | ||
| import org.springframework.http.HttpHeaders | ||
| import org.springframework.http.HttpMethod | ||
| import org.springframework.http.HttpStatusCode | ||
| import org.springframework.http.MediaType | ||
| import org.springframework.stereotype.Service | ||
| import org.springframework.util.MultiValueMap | ||
| import org.springframework.web.reactive.function.BodyInserters | ||
| import org.springframework.web.reactive.function.client.bodyToMono | ||
| import reactor.core.publisher.Mono | ||
|
|
||
| @Service | ||
| class EvService( | ||
| private val snuttEvWebClient: SnuttEvWebClient, | ||
| private val timetableService: TimetableService, | ||
| private val coursebookService: CoursebookService, | ||
| private val userService: UserService, | ||
| private val objectMapper: ObjectMapper, | ||
| ) { | ||
| suspend fun handleRouting( | ||
| userId: String, | ||
| requestPath: String, | ||
| requestQueryParams: MultiValueMap<String, String> = buildMultiValueMap(mapOf()), | ||
| originalBody: String, | ||
| method: HttpMethod, | ||
| ): Map<String, Any?> { | ||
| val result: MutableMap<String, Any?> = | ||
| snuttEvWebClient.method(method) | ||
| .uri { builder -> builder.path(requestPath).queryParams(requestQueryParams).build() } | ||
| .header("Snutt-User-Id", userId) | ||
| .header(HttpHeaders.CONTENT_ENCODING, "UTF-8") | ||
| .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) | ||
| .body(BodyInserters.fromValue(originalBody)) | ||
| .retrieve() | ||
| .onStatus(HttpStatusCode::isError) { response -> | ||
| response.bodyToMono<Map<String, Any?>>() | ||
| .flatMap { errorBody -> | ||
| Mono.error(EvServiceProxyException(response.statusCode(), errorBody)) | ||
| } | ||
| } | ||
| .bodyToMono<MutableMap<String, Any?>>() | ||
| .awaitSingle() | ||
| return updateUserInfo(result) | ||
| } | ||
|
|
||
| suspend fun getMyLatestLectures( | ||
| userId: String, | ||
| requestQueryParams: MultiValueMap<String, String> = buildMultiValueMap(mapOf()), | ||
| ): Map<String, Any?> { | ||
| val recentLectures: List<EvLectureInfoDto> = | ||
| coursebookService.getLastTwoCourseBooksBeforeCurrent().flatMap { coursebook -> | ||
| timetableService.getTimetablesBySemester(userId, coursebook.year, coursebook.semester) | ||
| .toList() | ||
| .flatMap { timetable -> | ||
| timetable.lectures.map { lecture -> | ||
| EvLectureInfoDto( | ||
| lecture, | ||
| coursebook.year, | ||
| coursebook.semester, | ||
| ) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| val lectureInfoParam = objectMapper.writeValueAsString(recentLectures) | ||
| return snuttEvWebClient.get() | ||
| .uri { builder -> | ||
| builder | ||
| .path("/v1/users/me/lectures/latest") | ||
| .queryParam("snutt_lecture_info", "{lectureInfoParam}") | ||
| .queryParams(requestQueryParams) | ||
| .build(lectureInfoParam) | ||
| } | ||
| .header("Snutt-User-Id", userId) | ||
| .header(HttpHeaders.CONTENT_ENCODING, "UTF-8") | ||
| .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) | ||
| .retrieve() | ||
| .onStatus(HttpStatusCode::isError) { response -> | ||
| response.bodyToMono<Map<String, Any?>>() | ||
| .flatMap { errorBody -> | ||
| Mono.error(EvServiceProxyException(response.statusCode(), errorBody)) | ||
| } | ||
| } | ||
| .bodyToMono<MutableMap<String, Any?>>() | ||
| .awaitSingle() | ||
| } | ||
|
|
||
| @Suppress("UNCHECKED_CAST") | ||
| private suspend fun updateUserInfo(data: MutableMap<String, Any?>): MutableMap<String, Any?> { | ||
| val updatedMap: MutableMap<String, Any?> = mutableMapOf() | ||
| for ((k, v) in data.entries) { | ||
| if (k == "user_id") { | ||
| val userDto = runCatching { EvUserDto(userService.getUser(v as String)) }.getOrNull() | ||
| updatedMap["user"] = userDto | ||
| } else { | ||
| when (v) { | ||
| is List<*> -> updatedMap[k] = v.map { updateUserInfo(it as MutableMap<String, Any?>) } | ||
| is MutableMap<*, *> -> updatedMap[k] = updateUserInfo(v as MutableMap<String, Any?>) | ||
| else -> updatedMap[k] = v | ||
| } | ||
| } | ||
| } | ||
| return updatedMap | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네이밍 통일하시죠 JsonProperty로 json에만 스네이크케이스면 좋겠습니다.