Skip to content

Commit

Permalink
add UseCases for web communications [FoKE-Developers#73]
Browse files Browse the repository at this point in the history
- 서버와 통신하기 위한 usecase들을 추가
    - **CreateAccountUseCase**: 계정 생성 (`phase4` 구현)
    - **SignInUseCase**: 로그인 및 세션 생성
    - **GetCurrentUserInformationUseCase**: 현재 로그인된 세센 계정 정보
    - **UploadFileUseCase**: 파일을 pre-signed url을 통해 업로드
- https://4cuts.store/docs 내용 기반
  • Loading branch information
DokySp authored and ing03201 committed Oct 10, 2024
1 parent f807b8c commit 3123d86
Show file tree
Hide file tree
Showing 13 changed files with 133 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ interface WebClientApi {
@Body body: AccountRegisterRequest
): Result<AccountRegisterResponse>

@GET("api/account/register")
@GET("api/account/signin")
suspend fun accountSignin(
@Query("email") email: String,
@Query("password") password: String
Expand All @@ -37,7 +37,7 @@ interface WebClientApi {
@GET("api/s3/presigned-url")
suspend fun s3PresignedUrl(
@HeaderMap headers: HashMap<String, String>,
@Query("key") key: String,
@Query("filename") filename: String,
@Query("ContentLength") contentLength: String, // max: 20971520
): Result<S3PresignedUrlResponse>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ class WebDataSource @Inject constructor(
return Result.failure(Exception("unknown error"))
}

suspend fun s3PreSignedUrl(key: String, file: File): Result<S3PresignedUrlResponse> {
suspend fun s3PreSignedUrl(filename: String, file: File): Result<S3PresignedUrlResponse> {
val contentLength = file.length()
if (contentLength > AppPolicy.WEB_FILE_MAX_CONTENT_LENGTH) {
return Result.failure(Exception("file size is over limit"))
}
return webClientApi.s3PresignedUrl(
headers = headers,
key = key,
filename = filename,
contentLength = file.length().toString()
)
}
Expand All @@ -57,6 +57,6 @@ class WebDataSource @Inject constructor(
}

private fun setToken(token: String) {
headers["token"] = token
headers["Authorization"] = "Bearer $token"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.foke.together.data.repository

import com.foke.together.domain.interactor.entity.AccountData
import com.foke.together.domain.output.AccountRepositoryInterface
import javax.inject.Inject

class AccountRepository @Inject constructor(
) : AccountRepositoryInterface {
private var accountData: AccountData? = null

override suspend fun setAccountInfo(data: AccountData) {
accountData = data
}

override suspend fun getAccountInfo(): Result<AccountData> {
return accountData?.run {
Result.success(this)
} ?: run {
Result.failure(Exception("account data is null"))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ class RemoteRepository @Inject constructor(
return Result.failure(Exception("unknown error"))
}

override suspend fun getUploadUrl(key: String, file: File): Result<String> {
webDataSource.s3PreSignedUrl(key, file)
override suspend fun getUploadUrl(filename: String, file: File): Result<String> {
webDataSource.s3PreSignedUrl(filename, file)
.onSuccess {
return Result.success(it.presignedUrl)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.foke.together.data.repository.di

import com.foke.together.data.repository.AccountRepository
import com.foke.together.data.repository.AppPreferencesRepository
import com.foke.together.data.repository.RemoteRepository
import com.foke.together.domain.output.AccountRepositoryInterface
import com.foke.together.domain.output.AppPreferenceInterface
import com.foke.together.domain.output.RemoteRepositoryInterface
import dagger.Binds
Expand All @@ -20,4 +22,8 @@ abstract class RepositoryModule {
@Singleton
@Binds
abstract fun bindRemoteRepository(remoteRepository: RemoteRepository): RemoteRepositoryInterface

@Singleton
@Binds
abstract fun bindAccountRepository(accountRepository: AccountRepository): AccountRepositoryInterface
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ package com.foke.together.domain.interactor.entity
data class AccountData (
val email: String,
val password: String,
val name: String?
val name: String? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.foke.together.domain.interactor.web

import com.foke.together.domain.output.RemoteRepositoryInterface
import javax.inject.Inject

class CreateAccountUseCase @Inject constructor(
private val remoteRepository: RemoteRepositoryInterface
) {
operator fun invoke(id: String, password: String): Result<Unit> {
// TODO: implement in sprint4
return Result.failure(Exception("not implemented"))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.foke.together.domain.interactor.web

import com.foke.together.domain.interactor.entity.AccountData
import com.foke.together.domain.output.AccountRepositoryInterface
import com.foke.together.domain.output.RemoteRepositoryInterface
import javax.inject.Inject

class GetCurrentUserInformationUseCase @Inject constructor(
private val remoteRepository: RemoteRepositoryInterface,
private val accountRepository: AccountRepositoryInterface
) {
suspend operator fun invoke(): Result<AccountData> =
accountRepository.getAccountInfo()
.onFailure {
remoteRepository.getAccountStatus()
.onSuccess {
accountRepository.setAccountInfo(it)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.foke.together.domain.interactor.web

import com.foke.together.domain.interactor.entity.AccountData
import com.foke.together.domain.output.AccountRepositoryInterface
import com.foke.together.domain.output.RemoteRepositoryInterface
import javax.inject.Inject

class SignInUseCase @Inject constructor(
private val remoteRepository: RemoteRepositoryInterface,
private val accountRepository: AccountRepositoryInterface,
private val getCurrentUserInformationUseCase: GetCurrentUserInformationUseCase
) {
suspend operator fun invoke(id: String, password: String): Result<Unit> {
return remoteRepository.signIn(AccountData(id, password))
.onSuccess {
getCurrentUserInformationUseCase()
.onSuccess { accountData ->
accountRepository.setAccountInfo(AccountData(
email = accountData.email,
password = "",
name = accountData.name
))
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.foke.together.domain.interactor.web

import com.foke.together.domain.output.RemoteRepositoryInterface
import com.foke.together.util.AppLog
import java.io.File
import javax.inject.Inject

// Download url
// https://4cuts.store/download/{user_name}/{key}
class UploadFileUseCase @Inject constructor(
private val remoteRepository: RemoteRepositoryInterface
) {
suspend operator fun invoke(key: String, file: File): Result<Unit> {
remoteRepository.getUploadUrl("$key.${file.extension}", file)
.onSuccess { preSignedUrl ->
AppLog.e("UploadFileUseCase", "invoke", "preSignedUrl: $preSignedUrl")
remoteRepository.uploadFile(preSignedUrl, file)
.onFailure {
AppLog.e("UploadFileUseCase", "invoke", "upload failed")
return Result.failure(Exception("cannot upload file: $it"))
}
}
.onFailure {
return Result.failure(Exception("cannot get pre-signed url: $it"))
}
return Result.failure(Exception("Unknown error"))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.foke.together.domain.output

import com.foke.together.domain.interactor.entity.AccountData

interface AccountRepositoryInterface {
suspend fun setAccountInfo(data: AccountData)
suspend fun getAccountInfo(): Result<AccountData>
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ interface RemoteRepositoryInterface {
suspend fun registerAccount(data: AccountData): Result<Unit>
suspend fun signIn(data: AccountData): Result<Unit>
suspend fun getAccountStatus(): Result<AccountData>
suspend fun getUploadUrl(key: String, file: File): Result<String>
suspend fun getUploadUrl(filename: String, file: File): Result<String>
suspend fun uploadFile(preSignedUrl: String, file: File): Result<Unit>
}
2 changes: 1 addition & 1 deletion util/src/main/java/com/foke/together/util/AppPolicy.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ object AppPolicy {
const val DEFAULT_EXTERNAL_CAMERA_IP = "0.0.0.0"

// network
const val WEB_SERVER_URL = "http://4cuts.store/"
const val WEB_SERVER_URL = "https://4cuts.store/"
const val WEB_CONNECT_TIMEOUT = 10L
const val WEB_READ_TIMEOUT = 10L
const val WEB_WRITE_TIMEOUT = 10L
Expand Down

0 comments on commit 3123d86

Please sign in to comment.