-
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
ev-service 마이그레이션 #308
Changes from 12 commits
82b9922
dfbd1c8
1e6d62d
7301714
f4465d7
0f00915
774bfa4
9a392cd
e14d853
4013766
563f222
04a15fd
c1e07a3
94709ce
b0faccf
077fd3b
ca95dd6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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()) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package com.wafflestudio.snu4t.common.exception | ||
|
|
||
| import com.fasterxml.jackson.databind.ObjectMapper | ||
| import org.springframework.http.HttpStatusCode | ||
|
|
||
| class ProxyException( | ||
| val statusCode: HttpStatusCode, | ||
| val errorBody: Map<String, Any?>, | ||
| ) : RuntimeException(ObjectMapper().writeValueAsString(errorBody)) | ||
|
||
| 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, | ||
| ) |
| 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, | ||
| ) | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,128 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package com.wafflestudio.snu4t.evaluation.service | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.fasterxml.jackson.databind.ObjectMapper | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.fasterxml.jackson.databind.PropertyNamingStrategies | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.wafflestudio.snu4t.common.exception.ProxyException | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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.Dispatchers | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import kotlinx.coroutines.flow.toList | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import kotlinx.coroutines.reactor.awaitSingle | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import kotlinx.coroutines.withContext | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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 org.springframework.web.util.UriComponentsBuilder | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import reactor.core.publisher.Mono | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.net.URLEncoder | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Service | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| class EvService( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private val snuttEvWebClient: SnuttEvWebClient, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private val timetableService: TimetableService, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private val coursebookService: CoursebookService, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private val userService: UserService, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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(ProxyException(response.statusCode(), errorBody)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .bodyToMono<MutableMap<String, Any?>>() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .awaitSingle() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return updateUserInfo(result) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| suspend fun getMyLatestLectures( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| userId: String, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| requestQueryParams: MultiValueMap<String, String>? = null, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ): 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 encodedJson = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| withContext(Dispatchers.IO) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| URLEncoder.encode( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ObjectMapper().setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE).writeValueAsString(recentLectures), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "UTF-8", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return snuttEvWebClient.get() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .uri { builder -> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| UriComponentsBuilder.fromUri(builder.build()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .path("/v1/users/me/lectures/latest") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .queryParam("snutt_lecture_info", encodedJson) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .queryParams(requestQueryParams) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .build(true).toUri() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val encodedJson = | |
| withContext(Dispatchers.IO) { | |
| URLEncoder.encode( | |
| ObjectMapper().setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE).writeValueAsString(recentLectures), | |
| "UTF-8", | |
| ) | |
| } | |
| return snuttEvWebClient.get() | |
| .uri { builder -> | |
| UriComponentsBuilder.fromUri(builder.build()) | |
| .path("/v1/users/me/lectures/latest") | |
| .queryParam("snutt_lecture_info", encodedJson) | |
| .queryParams(requestQueryParams) | |
| .build(true).toUri() | |
| } | |
| val lectureInfoParam = ObjectMapper().setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE).writeValueAsString(recentLectures) | |
| return snuttEvWebClient.get() | |
| .uri { builder -> | |
| builder | |
| .path("/v1/users/me/lectures/latest") | |
| .queryParam("snutt_lecture_info", "{lectureInfoParam}") | |
| .queryParams(requestQueryParams) | |
| .build(lectureInfoParam) | |
| } |
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.
기존 when 이 있는데 depth가 더 들어가서 한눈에 안들어오네요
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.
그냥 이렇게 하면 안되나요
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.
errorBody가 Any 타입으로만 바뀝니다.