Skip to content

Commit

Permalink
add RoomServiceFetcher to join different regions
Browse files Browse the repository at this point in the history
  • Loading branch information
aderan committed Sep 18, 2023
1 parent 806d833 commit 31f15e2
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 22 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ dependencies {
}

implementation 'io.agora.rtc:full-sdk:3.7.1'
implementation 'com.github.agorabuilder:rtm-sdk:1.4.1'
implementation 'com.github.agorabuilder:rtm-sdk:1.4.10'

// Exoplayer
def exoplayer_version = "2.14.1"
Expand Down
15 changes: 9 additions & 6 deletions app/src/main/java/io/agora/flat/data/AppEnv.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class AppEnv @Inject constructor(@ApplicationContext context: Context) {
private val store: SharedPreferences = context.getSharedPreferences("flat_env", Context.MODE_PRIVATE)

companion object {
const val ENV_PROD = "prod"
const val ENV_DEV = "dev"
const val ENV_CN_PROD = "cn_prod"
const val ENV_CN_DEV = "cn_dev"

const val ENV_SG_PROD = "sg_prod"
const val ENV_SG_DEV = "sg_dev"
Expand All @@ -27,7 +27,7 @@ class AppEnv @Inject constructor(@ApplicationContext context: Context) {
val envMap = mutableMapOf<String, EnvItem>()

init {
envMap[ENV_DEV] = EnvItem(
envMap[ENV_CN_DEV] = EnvItem(
agoraAppId = "a185de0a777f4c159e302abcc0f03b64",
serviceUrl = "https://flat-api-dev.whiteboard.agora.io",
githubClientId = "9821657775fbc74773f1",
Expand All @@ -48,7 +48,7 @@ class AppEnv @Inject constructor(@ApplicationContext context: Context) {
loginConfig = LoginConfig(google = false)
)

envMap[ENV_PROD] = EnvItem(
envMap[ENV_CN_PROD] = EnvItem(
agoraAppId = "931b86d6781e49a2a255db4ce6e8e804",
serviceUrl = "https://flat-api.whiteboard.agora.io",
githubClientId = "71a29285a437998bdfe0",
Expand Down Expand Up @@ -107,14 +107,17 @@ class AppEnv @Inject constructor(@ApplicationContext context: Context) {
}

fun getEnv(): String {
return store.getString(STORE_KEY_ENV, ENV_PROD)!!
return store.getString(STORE_KEY_ENV, ENV_CN_PROD)!!
}

fun getEnvServiceUrl(env: String): String {
return envMap[env]?.serviceUrl ?: envMap[ENV_CN_PROD]!!.serviceUrl
}

private val currentEnvItem = envMap[getEnv()]!!

val flatServiceUrl get() = currentEnvItem.serviceUrl


val githubClientID = run {
currentEnvItem.githubClientId
}
Expand Down
70 changes: 70 additions & 0 deletions app/src/main/java/io/agora/flat/data/RoomServiceFetcher.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package io.agora.flat.data

import io.agora.flat.di.NetworkModule
import io.agora.flat.http.api.RoomService
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import javax.inject.Inject
import javax.inject.Singleton

/**
* Fetch room service by uuid
*
* For joining rooms between different regions
*/
@Singleton
class RoomServiceFetcher @Inject constructor(
@NetworkModule.NormalOkHttpClient private val client: OkHttpClient,
private val appEnv: AppEnv
) {
companion object {
val regions = listOf(
"CN",
"SG",
)

val codeMap = mapOf(
"1" to "CN",
"2" to "SG",
)

fun fetchEnv(uuid: String, currentEnv: String): String {
var (region, envType) = currentEnv.split("_")

// short invite code
if (uuid.length == 11) {
val code = uuid[0] + ""
codeMap[code]?.let { region = it }
}

// long uuid
if (uuid.length > 15) {
val firstTwo = uuid.substring(0, 2)
regions.find { it == firstTwo.uppercase() }?.let { region = it }
}

return "${region}_$envType".lowercase()
}
}

private val cache = mutableMapOf<String, RoomService>()

fun fetch(uuid: String): RoomService {
val env = fetchEnv(uuid, appEnv.getEnv())
val envServiceUrl = appEnv.getEnvServiceUrl(env)

return cache[env] ?: createRoomService(envServiceUrl).also {
cache[env] = it
}
}

private fun createRoomService(serviceUrl: String): RoomService {
return Retrofit.Builder()
.baseUrl(serviceUrl)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(RoomService::class.java)
}
}
46 changes: 31 additions & 15 deletions app/src/main/java/io/agora/flat/data/repository/RoomRepository.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
package io.agora.flat.data.repository

import io.agora.flat.data.Result
import io.agora.flat.data.model.*
import io.agora.flat.data.RoomServiceFetcher
import io.agora.flat.data.model.CancelRoomReq
import io.agora.flat.data.model.JoinRoomReq
import io.agora.flat.data.model.NetworkRoomUser
import io.agora.flat.data.model.PureRoomReq
import io.agora.flat.data.model.RespNoData
import io.agora.flat.data.model.RoomCreateReq
import io.agora.flat.data.model.RoomCreateRespData
import io.agora.flat.data.model.RoomDetailOrdinary
import io.agora.flat.data.model.RoomDetailOrdinaryReq
import io.agora.flat.data.model.RoomDetailPeriodic
import io.agora.flat.data.model.RoomDetailPeriodicReq
import io.agora.flat.data.model.RoomInfo
import io.agora.flat.data.model.RoomPlayInfo
import io.agora.flat.data.model.RoomType
import io.agora.flat.data.model.RoomUsersReq
import io.agora.flat.data.toResult
import io.agora.flat.http.api.RoomService
import kotlinx.coroutines.Dispatchers
Expand All @@ -12,7 +27,12 @@ import javax.inject.Singleton
@Singleton
class RoomRepository @Inject constructor(
private val roomService: RoomService,
private val roomServiceFetcher: RoomServiceFetcher
) {
private fun fetchService(uuid: String): RoomService {
return roomServiceFetcher.fetch(uuid)
}

suspend fun getRoomListAll(page: Int): Result<List<RoomInfo>> {
return withContext(Dispatchers.IO) {
roomService.getRoomAll(page).toResult()
Expand All @@ -27,8 +47,7 @@ class RoomRepository @Inject constructor(

suspend fun getOrdinaryRoomInfo(roomUUID: String): Result<RoomDetailOrdinary> {
return withContext(Dispatchers.IO) {
roomService.getOrdinaryRoomInfo(RoomDetailOrdinaryReq(roomUUID = roomUUID))
.toResult()
fetchService(roomUUID).getOrdinaryRoomInfo(RoomDetailOrdinaryReq(roomUUID = roomUUID)).toResult()
}
}

Expand All @@ -40,34 +59,31 @@ class RoomRepository @Inject constructor(

suspend fun cancelOrdinary(roomUUID: String): Result<RespNoData> {
return withContext(Dispatchers.IO) {
roomService.cancelOrdinary(CancelRoomReq(roomUUID = roomUUID))
.toResult()
fetchService(roomUUID).cancelOrdinary(CancelRoomReq(roomUUID = roomUUID)).toResult()
}
}

suspend fun cancelPeriodic(periodicUUID: String): Result<RespNoData> {
return withContext(Dispatchers.IO) {
roomService.cancelPeriodic(CancelRoomReq(periodicUUID = periodicUUID))
.toResult()
roomService.cancelPeriodic(CancelRoomReq(periodicUUID = periodicUUID)).toResult()
}
}

suspend fun cancelPeriodicSubRoom(roomUUID: String, periodicUUID: String): Result<RespNoData> {
return withContext(Dispatchers.IO) {
roomService.cancelPeriodicSubRoom(CancelRoomReq(roomUUID, periodicUUID))
.toResult()
roomService.cancelPeriodicSubRoom(CancelRoomReq(roomUUID, periodicUUID)).toResult()
}
}

suspend fun joinRoom(uuid: String): Result<RoomPlayInfo> {
suspend fun joinRoom(roomUUID: String): Result<RoomPlayInfo> {
return withContext(Dispatchers.IO) {
roomService.joinRoom(JoinRoomReq(uuid)).toResult()
fetchService(roomUUID).joinRoom(JoinRoomReq(roomUUID)).toResult()
}
}

suspend fun getRoomUsers(roomUUID: String, usersUUID: List<String>?): Result<Map<String, NetworkRoomUser>> {
return withContext(Dispatchers.IO) {
roomService.getRoomUsers(RoomUsersReq(roomUUID, usersUUID)).toResult()
fetchService(roomUUID).getRoomUsers(RoomUsersReq(roomUUID, usersUUID)).toResult()
}
}

Expand All @@ -79,19 +95,19 @@ class RoomRepository @Inject constructor(

suspend fun startRoomClass(roomUUID: String): Result<RespNoData> {
return withContext(Dispatchers.IO) {
roomService.startRoomClass(PureRoomReq(roomUUID)).toResult()
fetchService(roomUUID).startRoomClass(PureRoomReq(roomUUID)).toResult()
}
}

suspend fun pauseRoomClass(roomUUID: String): Result<RespNoData> {
return withContext(Dispatchers.IO) {
roomService.pauseRoomClass(PureRoomReq(roomUUID)).toResult()
fetchService(roomUUID).pauseRoomClass(PureRoomReq(roomUUID)).toResult()
}
}

suspend fun stopRoomClass(roomUUID: String): Result<RespNoData> {
return withContext(Dispatchers.IO) {
roomService.stopRoomClass(PureRoomReq(roomUUID)).toResult()
fetchService(roomUUID).stopRoomClass(PureRoomReq(roomUUID)).toResult()
}
}
}
47 changes: 47 additions & 0 deletions app/src/test/java/io/agora/flat/data/RoomServiceFetcherTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package io.agora.flat.data

import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test

class RoomServiceFetcherTest {

@Before
fun setUp() {
}

@After
fun tearDown() {
}

data class FetchEnvCase(
val uuid: String,
val env: String,
val expected: String,
)

@Test
fun test_fetch_env() {
val cases = listOf(
// sg invite code
FetchEnvCase("22884465997", "cn_dev", "sg_dev"),

// cn invite code
FetchEnvCase("12122312333", "sg_prod", "cn_prod"),

// old invite code
FetchEnvCase("2231213331", "cn_prod", "cn_prod"),

// sg uuid
FetchEnvCase("SG-73e84969-1850-44db-ae01-7e46192cb01c", "cn_prod", "sg_prod"),

// cn uuid
FetchEnvCase("CN-73e84969-1850-44db-ae01-7e46192cb01c", "sg_dev", "cn_dev")
)

cases.forEach { it ->
assertEquals(it.expected, RoomServiceFetcher.fetchEnv(it.uuid, it.env))
}
}
}

0 comments on commit 31f15e2

Please sign in to comment.