feat(i18n): AWS 언어 감지와 분할 번역 공급자를 추가한다
This commit is contained in:
+27
@@ -0,0 +1,27 @@
|
||||
package kr.co.vividnext.sodalive.i18n.translation
|
||||
|
||||
import org.springframework.stereotype.Component
|
||||
import software.amazon.awssdk.services.comprehend.ComprehendClient
|
||||
import software.amazon.awssdk.services.comprehend.model.DetectDominantLanguageRequest
|
||||
|
||||
@Component
|
||||
class AwsLanguageDetectionProvider(private val client: ComprehendClient) : LanguageDetectionProvider {
|
||||
override val providerId = LanguageProviderId.AWS
|
||||
|
||||
override fun detect(query: String): String? {
|
||||
if (query.isBlank()) return null
|
||||
|
||||
return try {
|
||||
// shortcut: 감지는 앞 100000 UTF-8 바이트만 판정하므로 전체 본문과 결과가 다를 수 있음, 전체 본문 기준 품질이 요구되면 별도 감지 정책 승인 후 업그레이드
|
||||
val text = takeTextPrefixByCodePoint(query, MAX_REQUEST_TEXT_BYTES, ::utf8CodePointSize)
|
||||
val request = DetectDominantLanguageRequest.builder().text(text).build()
|
||||
client.detectDominantLanguage(request).languages().firstOrNull()?.languageCode()?.takeIf { it.isNotBlank() }
|
||||
} catch (_: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val MAX_REQUEST_TEXT_BYTES = 100000
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package kr.co.vividnext.sodalive.i18n.translation
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials
|
||||
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider
|
||||
import software.amazon.awssdk.regions.Region
|
||||
import software.amazon.awssdk.services.comprehend.ComprehendClient
|
||||
import software.amazon.awssdk.services.translate.TranslateClient
|
||||
|
||||
@Configuration
|
||||
class AwsLanguageProviderConfiguration(
|
||||
@Value("\${cloud.aws.credentials.access-key}") accessKey: String,
|
||||
@Value("\${cloud.aws.credentials.secret-key}") secretKey: String,
|
||||
@Value("\${cloud.aws.region.static}") region: String
|
||||
) {
|
||||
private val credentialsProvider = StaticCredentialsProvider.create(AwsBasicCredentials.create(accessKey, secretKey))
|
||||
private val region = Region.of(region)
|
||||
|
||||
@Bean(destroyMethod = "close")
|
||||
fun comprehendClient(): ComprehendClient = ComprehendClient.builder()
|
||||
.credentialsProvider(credentialsProvider)
|
||||
.region(region)
|
||||
.build()
|
||||
|
||||
@Bean(destroyMethod = "close")
|
||||
fun translateClient(): TranslateClient = TranslateClient.builder()
|
||||
.credentialsProvider(credentialsProvider)
|
||||
.region(region)
|
||||
.build()
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package kr.co.vividnext.sodalive.i18n.translation
|
||||
|
||||
import org.springframework.stereotype.Service
|
||||
import software.amazon.awssdk.services.translate.TranslateClient
|
||||
import software.amazon.awssdk.services.translate.model.TranslateTextRequest
|
||||
|
||||
@Service
|
||||
class AwsTranslationService(private val client: TranslateClient) : TranslationProvider {
|
||||
override val providerId = LanguageProviderId.AWS
|
||||
override val providerVersion = "translate-2017-07-01"
|
||||
|
||||
override fun translate(request: TranslateRequest): TranslateResult {
|
||||
if (request.texts.isEmpty() || request.sourceLanguage == request.targetLanguage) {
|
||||
return TranslateResult(emptyList())
|
||||
}
|
||||
if (
|
||||
!TranslationLanguages.isSupported(request.sourceLanguage) ||
|
||||
!TranslationLanguages.isSupported(request.targetLanguage)
|
||||
) {
|
||||
return TranslateResult(emptyList())
|
||||
}
|
||||
|
||||
val translatedTexts = mutableListOf<String>()
|
||||
try {
|
||||
for (text in request.texts) {
|
||||
val translatedText = StringBuilder()
|
||||
for (chunk in splitTextByCodePoint(text, MAX_REQUEST_TEXT_BYTES, ::utf8CodePointSize)) {
|
||||
val sdkRequest = TranslateTextRequest.builder()
|
||||
.sourceLanguageCode(request.sourceLanguage)
|
||||
.targetLanguageCode(request.targetLanguage)
|
||||
.text(chunk)
|
||||
.build()
|
||||
val translated = client.translateText(sdkRequest)?.translatedText()
|
||||
if (translated.isNullOrBlank()) return TranslateResult(emptyList())
|
||||
translatedText.append(translated)
|
||||
}
|
||||
translatedTexts.add(translatedText.toString())
|
||||
}
|
||||
} catch (_: Exception) {
|
||||
return TranslateResult(emptyList())
|
||||
}
|
||||
return TranslateResult(translatedTexts)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val MAX_REQUEST_TEXT_BYTES = 10000
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user