Skip to content

Commit

Permalink
Merge pull request #199 from swm-standard/rin/swm-167
Browse files Browse the repository at this point in the history
Refactor: transformQuestion 리팩토링
  • Loading branch information
adorableco authored Aug 30, 2024
2 parents 7cbc06c + 9afe616 commit 6412d61
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 41 deletions.
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ dependencies {
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.11.5")
implementation("org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0-RC")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:1.9.0-RC")
implementation("org.springframework.boot:spring-boot-starter-webflux")

// querydsl
implementation("com.querydsl:querydsl-jpa:5.0.0:jakarta")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,11 @@ class QuestionController(
@Operation(summary = "transformQuestion", description = "문제 변환")
@SecurityRequirement(name = "bearer Auth")
@PostMapping("question-transform")
fun transformQuestion(
suspend fun transformQuestion(
@RequestPart image: MultipartFile?,
@RequestPart imageCoordinates: List<List<Int>>? = null,
): BaseResponse<TransformQuestionResponse> {

val imageUrl = image?.let { s3Service.uploadChatGptImage(it) }
val response: TransformQuestionResponse = questionService.transformQuestion(imageUrl!!, imageCoordinates)

Expand Down
81 changes: 41 additions & 40 deletions src/main/kotlin/com/swm_standard/phote/service/QuestionService.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.swm_standard.phote.service

import com.fasterxml.jackson.databind.ObjectMapper
import com.swm_standard.phote.common.exception.ChatGptErrorException
import com.swm_standard.phote.common.exception.NotFoundException
import com.swm_standard.phote.dto.CreateQuestionRequest
Expand All @@ -16,20 +17,20 @@ import com.swm_standard.phote.entity.Tag
import com.swm_standard.phote.repository.MemberRepository
import com.swm_standard.phote.repository.QuestionRepository
import com.swm_standard.phote.repository.TagRepository
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.withContext
import org.springframework.beans.factory.annotation.Value
import org.springframework.http.HttpEntity
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpMethod
import org.springframework.http.MediaType
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import org.springframework.util.LinkedMultiValueMap
import org.springframework.util.MultiValueMap
import org.springframework.web.client.RestTemplate
import org.springframework.web.reactive.function.BodyInserters
import org.springframework.web.reactive.function.client.WebClient
import org.springframework.web.reactive.function.client.awaitBodyOrNull
import java.time.LocalDateTime
import java.util.UUID

Expand Down Expand Up @@ -122,28 +123,51 @@ class QuestionService(
return DeleteQuestionResponse(id, LocalDateTime.now())
}

fun transformQuestion(
suspend fun transformQuestion(
imageUrl: String,
imageCoordinates: List<List<Int>>?,
): TransformQuestionResponse {

val (transformedImageUrl, chatGPTResponse) = runBlocking {
val transformedImageUrl = CoroutineScope(Dispatchers.IO).async {

// 문제 그림 추출
val transformedImageUrlDeferred = CoroutineScope(Dispatchers.IO).async {
imageCoordinates?.let { transformImage(imageUrl, it) }
}.await()
imageCoordinates?.let { transformImage(imageUrl, it) }
}.await()

val chatGPTResponseSplit = CoroutineScope(Dispatchers.IO).async {
// openAI로 메시지 전송
val chatGPTResponseDeferred = CoroutineScope(Dispatchers.IO).async {
val request = ChatGPTRequest(model, imageUrl)
template.postForObject(url, request, ChatGPTResponse::class.java)
}.await()
val request = ChatGPTRequest(model, imageUrl)
val chatGPTResponse = template.postForObject(url, request, ChatGPTResponse::class.java)

Pair(transformedImageUrlDeferred, chatGPTResponseDeferred)
}
// openAI로부터 메시지 수신
splitChatGPTResponse(chatGPTResponse)
}.await()

// 문제 문항과 객관식을 분리해서 dto에 저장
return TransformQuestionResponse(chatGPTResponseSplit[0], chatGPTResponseSplit.drop(1), transformedImageUrl)
}

suspend fun transformImage(imageUrl: String, imageCoordinates: List<List<Int>>?): String? {
val webClient = WebClient.builder()
.baseUrl(lambdaUrl)
.defaultHeader(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded;charset=utf-8")
.build()

val body: MultiValueMap<String, String> = LinkedMultiValueMap()
body.add("url", imageUrl)
body.add("coor", ObjectMapper().writeValueAsString(imageCoordinates))

val lambdaResponse: String? =
webClient.post()
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromFormData(body))
.retrieve()
.awaitBodyOrNull<String>()

// openAI로부터 메시지 수신
return lambdaResponse?.split("\"")?.get(1)
}

fun splitChatGPTResponse(chatGPTResponse: ChatGPTResponse?): List<String> {
val split: List<String> =
chatGPTResponse!!
.choices[0]
Expand All @@ -153,29 +177,6 @@ class QuestionService(
if (split[0] == "") {
throw ChatGptErrorException(fieldName = "chatGPT")
}

// 문제 문항과 객관식을 분리해서 dto에 저장
return TransformQuestionResponse(split[0], split.drop(1), transformedImageUrl)
}

suspend fun transformImage(imageUrl: String, imageCoordinates: List<List<Int>>?): String? {
val headers = HttpHeaders()
headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8")

val body: MultiValueMap<String, Any> = LinkedMultiValueMap()
body.add("url", imageUrl)
body.add("coor", imageCoordinates)

val transformImageRequest = HttpEntity(body, headers)
val lambdaResponse =
withContext(Dispatchers.IO) {
RestTemplate().exchange(
lambdaUrl,
HttpMethod.POST,
transformImageRequest,
String::class.java,
)
}
return lambdaResponse.body?.split("\"")?.get(1)
return split
}
}

0 comments on commit 6412d61

Please sign in to comment.