Skip to content
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

[IDLE-466] 웹소켓 연결 및 해제, 데이터 파이프 라인 연결, 에러가 났을 경우 Crashlytics로 로깅하도록 구현 #146

Merged
merged 4 commits into from
Nov 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ dependencies {
implementation(projects.core.data)
implementation(projects.core.domain)
implementation(projects.presentation)
implementation(projects.core.analytics)

implementation(libs.firebase.messaging)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.idle.analytics.helper
package com.idle.analytics.businessmetric

import com.amplitude.android.Amplitude
import com.amplitude.core.events.BaseEvent
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.idle.analytics.helper
package com.idle.analytics.businessmetric

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.idle.analytics.helper
package com.idle.analytics.businessmetric

import android.util.Log
import com.idle.analytics.AnalyticsEvent
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.idle.analytics.helper
package com.idle.analytics.businessmetric

import androidx.compose.runtime.staticCompositionLocalOf

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.idle.analytics.helper
package com.idle.analytics.businessmetric

import com.idle.analytics.AnalyticsEvent

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ package com.idle.analytics.di
import android.content.Context
import com.amplitude.android.Amplitude
import com.amplitude.android.Configuration
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.idle.analytics.BuildConfig
import com.idle.analytics.helper.AmplitudeAnalyticsHelper
import com.idle.analytics.helper.AnalyticsHelper
import com.idle.analytics.helper.DebugAnalyticsHelper
import com.idle.analytics.businessmetric.AmplitudeAnalyticsHelper
import com.idle.analytics.businessmetric.AnalyticsHelper
import com.idle.analytics.businessmetric.DebugAnalyticsHelper
import com.idle.analytics.error.CrashlyticsErrorLoggingHelper
import com.idle.analytics.error.DebugErrorLoggingHelper
import com.idle.analytics.error.ErrorLoggingHelper
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand All @@ -19,6 +23,10 @@ import javax.inject.Singleton
@InstallIn(SingletonComponent::class)
object AnalyticsModule {

@Provides
@Singleton
fun provideFirebaseCrashlytics(): FirebaseCrashlytics = FirebaseCrashlytics.getInstance()

@Provides
@Singleton
fun providesAmplitude(@ApplicationContext context: Context): Amplitude = Amplitude(
Expand All @@ -30,34 +38,59 @@ object AnalyticsModule {

@Provides
@Singleton
@DebugLogger
@DebugHelper
fun provideDebugAnalyticsHelper(): AnalyticsHelper = DebugAnalyticsHelper()

@Provides
@Singleton
@ReleaseLogger
fun provideReleaseAnalyticsHelper(
amplitude: Amplitude
): AnalyticsHelper = AmplitudeAnalyticsHelper(amplitude)
@ReleaseHelper
fun provideReleaseAnalyticsHelper(amplitude: Amplitude): AnalyticsHelper =
AmplitudeAnalyticsHelper(amplitude)

@Provides
@Singleton
fun provideAnalyticsHelper(
@DebugLogger debugHelper: AnalyticsHelper,
@ReleaseLogger releaseHelper: AnalyticsHelper
@DebugHelper debugHelper: AnalyticsHelper,
@ReleaseHelper releaseHelper: AnalyticsHelper
): AnalyticsHelper {
return if (BuildConfig.BUILD_TYPE == "RELEASE") {
releaseHelper
} else {
debugHelper
}
return if (BuildConfig.BUILD_TYPE == "RELEASE") releaseHelper
else debugHelper
}

@Provides
@Singleton
@DebugErrorHelper
fun provideDebugErrorLoggingHelper(): ErrorLoggingHelper = DebugErrorLoggingHelper()

@Provides
@Singleton
@ReleaseErrorHelper
fun provideReleaseErrorLoggingHelper(firebaseCrashlytics: FirebaseCrashlytics): ErrorLoggingHelper =
CrashlyticsErrorLoggingHelper(firebaseCrashlytics)

@Provides
@Singleton
fun provideErrorLoggingHelper(
@DebugErrorHelper debugErrorHelper: ErrorLoggingHelper,
@ReleaseErrorHelper releaseErrorHelper: ErrorLoggingHelper,
): ErrorLoggingHelper {
return if (BuildConfig.BUILD_TYPE == "RELEASE") releaseErrorHelper
else debugErrorHelper
}
}

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class DebugLogger
annotation class DebugHelper

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class ReleaseHelper

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class DebugErrorHelper

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class ReleaseLogger
annotation class ReleaseErrorHelper
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.idle.analytics.error

import com.google.firebase.crashlytics.FirebaseCrashlytics
import javax.inject.Inject

class CrashlyticsErrorLoggingHelper @Inject constructor(
private val firebaseCrashlytics: FirebaseCrashlytics,
) : ErrorLoggingHelper {
override fun logError(exception: Throwable) {
firebaseCrashlytics.recordException(exception)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.idle.analytics.error

import android.util.Log
import javax.inject.Inject

class DebugErrorLoggingHelper @Inject constructor() : ErrorLoggingHelper {
override fun logError(exception: Throwable) {
Log.e("DebugErrorLoggingHelper", exception.stackTraceToString())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.idle.analytics.error

interface ErrorLoggingHelper {
fun logError(exception: Throwable)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import com.idle.analytics.helper.AnalyticsHelper
import com.idle.analytics.businessmetric.AnalyticsHelper
import javax.inject.Inject

typealias Inflate<T> = (LayoutInflater, ViewGroup?, Boolean) -> T
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import com.idle.analytics.helper.AnalyticsHelper
import com.idle.analytics.helper.LocalAnalyticsHelper
import com.idle.analytics.businessmetric.AnalyticsHelper
import com.idle.analytics.businessmetric.LocalAnalyticsHelper
import com.idle.binding.base.BaseViewModel
import javax.inject.Inject

Expand Down
8 changes: 8 additions & 0 deletions core/data/src/main/java/com/idle/data/di/DataModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package com.idle.data.di
import com.idle.data.repository.auth.AuthRepositoryImpl
import com.idle.data.repository.auth.TokenManagerImpl
import com.idle.data.repository.auth.TokenRepositoryImpl
import com.idle.data.repository.chatting.ChattingRepositoryImpl
import com.idle.data.repository.config.ConfigRepositoryImpl
import com.idle.data.repository.jobposting.JobPostingRepositoryImpl
import com.idle.data.repository.notification.NotificationRepositoryImpl
import com.idle.data.repository.profile.ProfileRepositoryImpl
import com.idle.domain.repositorry.auth.AuthRepository
import com.idle.domain.repositorry.auth.TokenRepository
import com.idle.domain.repositorry.chatting.ChattingRepository
import com.idle.domain.repositorry.config.ConfigRepository
import com.idle.domain.repositorry.jobposting.JobPostingRepository
import com.idle.domain.repositorry.notification.NotificationRepository
Expand Down Expand Up @@ -59,6 +61,12 @@ abstract class DataModule {
notificationRepositoryImpl: NotificationRepositoryImpl,
): NotificationRepository

@Binds
@Singleton
abstract fun bindsChattingRepository(
chattingRepositoryImpl: ChattingRepositoryImpl,
): ChattingRepository

@Binds
@Singleton
abstract fun bindsTokenProvider(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.idle.data.repository.chatting

import com.idle.domain.model.chatting.ChatMessage
import com.idle.domain.repositorry.chatting.ChattingRepository
import com.idle.network.source.websocket.WebSocketDataSource
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
import javax.inject.Inject

class ChattingRepositoryImpl @Inject constructor(
private val webSocketDataSource: WebSocketDataSource,
) : ChattingRepository {
override suspend fun connectWebSocket(): Result<Unit> = webSocketDataSource.connectWebSocket()

override suspend fun disconnectWebSocket(): Result<Unit> =
webSocketDataSource.disconnectWebSocket()

override fun subscribeChatMessage(): Flow<ChatMessage> =
webSocketDataSource.getChatMessageFlow()
.filterNotNull()
.map { it.toVO() }
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ class ProfileRepositoryImpl @Inject constructor(
}

WorkerProfile(
workerId = properties["workerId"]
?: throw IllegalArgumentException("Missing workerId"),
workerName = properties["workerName"]
?: throw IllegalArgumentException("Missing workerName"),
age = properties["age"]?.toInt() ?: throw NumberFormatException("Invalid age format"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class ProfileRepositoryImplTest {
)

private val workerProfile = WorkerProfile(
workerId = "test",
workerName = "Test Worker",
age = 30,
gender = Gender.MAN,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,31 @@ data class ChatMessage(
val senderType: SenderType,
val contents: List<Content>,
val createdAt: LocalDateTime,
)
) {
fun printPlainContents(): String = contents.joinToString { it.value }
}

data class Content(
val type: ContentType,
val value: String,
)

enum class SenderType {
USER,
USER, UNKNOWN;

companion object {
fun create(value: String?): SenderType {
return SenderType.entries.firstOrNull { it.name == value } ?: UNKNOWN
}
}
}

enum class ContentType {
TEXT, IMAGE;
TEXT, IMAGE, UNKNOWN;

companion object {
fun create(value: String?): ContentType {
return ContentType.entries.firstOrNull { it.name == value } ?: UNKNOWN
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ data class ChatRoom(
val lastMessage: String,
val lastSentAt: LocalDateTime,
val unReadMessageCount: Int,
val profileImageUrl: String,
val profileImageUrl: String?,
)
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class ErrorHandlerHelper @Inject constructor() {
class ErrorHandler @Inject constructor() {
private val _errorEvent = MutableSharedFlow<Throwable>(extraBufferCapacity = 1)
val errorEvent = _errorEvent.asSharedFlow()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.idle.domain.model.profile
import com.idle.domain.model.auth.Gender

data class WorkerProfile(
val workerId: String,
val workerName: String,
val age: Int,
val gender: Gender,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.idle.domain.repositorry.chatting

import com.idle.domain.model.chatting.ChatMessage
import kotlinx.coroutines.flow.Flow

interface ChattingRepository {
suspend fun connectWebSocket(): Result<Unit>
suspend fun disconnectWebSocket(): Result<Unit>
fun subscribeChatMessage(): Flow<ChatMessage>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.idle.domain.usecase.chatting

import com.idle.domain.repositorry.chatting.ChattingRepository
import javax.inject.Inject

class ConnectWebSocketUseCase @Inject constructor(
private val chattingRepository: ChattingRepository,
) {
suspend operator fun invoke(): Result<Unit> = chattingRepository.connectWebSocket()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.idle.domain.usecase.chatting

import com.idle.domain.repositorry.chatting.ChattingRepository
import javax.inject.Inject

class DisconnectWebSocketUseCase @Inject constructor(
private val chattingRepository: ChattingRepository,
) {
suspend operator fun invoke() = chattingRepository.disconnectWebSocket()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.idle.domain.usecase.chatting

import com.idle.domain.model.chatting.ChatMessage
import com.idle.domain.repositorry.chatting.ChattingRepository
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject

class SubscribeChatMessageUseCase @Inject constructor(
private val chattingRepository: ChattingRepository,
) {
operator fun invoke(): Flow<ChatMessage> = chattingRepository.subscribeChatMessage()
}
11 changes: 10 additions & 1 deletion core/network/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,23 @@ android {
"CARE_BASE_URL",
"\"${properties["CARE_DEV_BASE_URL"]}\"",
)
buildConfigField(
"String",
"CARE_WEBSOCKET_URL",
"\"${properties["CARE_DEV_WEBSOCKET_URL"]}\"",
)
}
release {
buildConfigField(
"String",
"CARE_BASE_URL",
"\"${properties["CARE_PROD_BASE_URL"]}\"",
)

buildConfigField(
"String",
"CARE_WEBSOCKET_URL",
"\"${properties["CARE_PROD_WEBSOCKET_URL"]}\"",
)
}
}

Expand Down
Loading