Fix recursive calls to getAuthToken
This commit is contained in:
@@ -23,7 +23,7 @@ class AuthDataSourceImpl @Inject constructor(
|
|||||||
|
|
||||||
override suspend fun authenticate(username: String, password: String): String {
|
override suspend fun authenticate(username: String, password: String): String {
|
||||||
Timber.v("authenticate() called with: username = $username, password = $password")
|
Timber.v("authenticate() called with: username = $username, password = $password")
|
||||||
val authService = authServiceFactory.provideService()
|
val authService = authServiceFactory.provideService(needAuth = false)
|
||||||
val response = sendRequest(authService, username, password)
|
val response = sendRequest(authService, username, password)
|
||||||
val accessToken = parseToken(response)
|
val accessToken = parseToken(response)
|
||||||
Timber.v("authenticate() returned: $accessToken")
|
Timber.v("authenticate() returned: $accessToken")
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
package gq.kirmanak.mealient.data.network
|
|
||||||
|
|
||||||
import okhttp3.Interceptor
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import timber.log.Timber
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
class OkHttpBuilder @Inject constructor(
|
|
||||||
// Use @JvmSuppressWildcards because otherwise dagger can't inject it (https://stackoverflow.com/a/43149382)
|
|
||||||
private val authenticationInterceptor: AuthenticationInterceptor,
|
|
||||||
private val interceptors: Set<@JvmSuppressWildcards Interceptor>,
|
|
||||||
) {
|
|
||||||
|
|
||||||
fun buildOkHttp(): OkHttpClient {
|
|
||||||
Timber.v("buildOkHttp() called")
|
|
||||||
return OkHttpClient.Builder().apply {
|
|
||||||
addInterceptor(authenticationInterceptor)
|
|
||||||
for (interceptor in interceptors) addNetworkInterceptor(interceptor)
|
|
||||||
}.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package gq.kirmanak.mealient.data.network
|
package gq.kirmanak.mealient.data.network
|
||||||
|
|
||||||
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
|
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
|
||||||
|
import gq.kirmanak.mealient.di.AUTH_OK_HTTP
|
||||||
|
import gq.kirmanak.mealient.di.NO_AUTH_OK_HTTP
|
||||||
import kotlinx.serialization.ExperimentalSerializationApi
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
@@ -8,22 +10,25 @@ import okhttp3.OkHttpClient
|
|||||||
import retrofit2.Retrofit
|
import retrofit2.Retrofit
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Named
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class RetrofitBuilder @Inject constructor(
|
class RetrofitBuilder @Inject constructor(
|
||||||
private val okHttpClient: OkHttpClient,
|
@Named(AUTH_OK_HTTP) private val authOkHttpClient: OkHttpClient,
|
||||||
|
@Named(NO_AUTH_OK_HTTP) private val noAuthOkHttpClient: OkHttpClient,
|
||||||
private val json: Json
|
private val json: Json
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@OptIn(ExperimentalSerializationApi::class)
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
fun buildRetrofit(baseUrl: String): Retrofit {
|
fun buildRetrofit(baseUrl: String, needAuth: Boolean): Retrofit {
|
||||||
Timber.v("buildRetrofit() called with: baseUrl = $baseUrl")
|
Timber.v("buildRetrofit() called with: baseUrl = $baseUrl")
|
||||||
val contentType = "application/json".toMediaType()
|
val contentType = "application/json".toMediaType()
|
||||||
val converterFactory = json.asConverterFactory(contentType)
|
val converterFactory = json.asConverterFactory(contentType)
|
||||||
|
val client = if (needAuth) authOkHttpClient else noAuthOkHttpClient
|
||||||
return Retrofit.Builder()
|
return Retrofit.Builder()
|
||||||
.baseUrl(baseUrl)
|
.baseUrl(baseUrl)
|
||||||
.client(okHttpClient)
|
.client(client)
|
||||||
.addConverterFactory(converterFactory)
|
.addConverterFactory(converterFactory)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,21 +13,28 @@ class RetrofitServiceFactory<T>(
|
|||||||
private val baseURLStorage: BaseURLStorage,
|
private val baseURLStorage: BaseURLStorage,
|
||||||
) : ServiceFactory<T> {
|
) : ServiceFactory<T> {
|
||||||
|
|
||||||
private val cache: MutableMap<String, T> = mutableMapOf()
|
private val cache: MutableMap<ServiceParams, T> = mutableMapOf()
|
||||||
|
|
||||||
override suspend fun provideService(baseUrl: String?): T = runCatchingExceptCancel {
|
override suspend fun provideService(
|
||||||
|
baseUrl: String?,
|
||||||
|
needAuth: Boolean,
|
||||||
|
): T = runCatchingExceptCancel {
|
||||||
Timber.v("provideService() called with: baseUrl = $baseUrl, class = ${serviceClass.simpleName}")
|
Timber.v("provideService() called with: baseUrl = $baseUrl, class = ${serviceClass.simpleName}")
|
||||||
val url = baseUrl ?: baseURLStorage.requireBaseURL()
|
val url = baseUrl ?: baseURLStorage.requireBaseURL()
|
||||||
synchronized(cache) { cache[url] ?: createService(url, serviceClass) }
|
val params = ServiceParams(url, needAuth)
|
||||||
|
synchronized(cache) { cache[params] ?: createService(params, serviceClass) }
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
Timber.e(it, "provideService: can't provide service for $baseUrl")
|
Timber.e(it, "provideService: can't provide service for $baseUrl")
|
||||||
throw NetworkError.MalformedUrl(it)
|
throw NetworkError.MalformedUrl(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createService(url: String, serviceClass: Class<T>): T {
|
private fun createService(serviceParams: ServiceParams, serviceClass: Class<T>): T {
|
||||||
Timber.v("createService() called with: url = $url, serviceClass = ${serviceClass.simpleName}")
|
Timber.v("createService() called with: serviceParams = $serviceParams, serviceClass = ${serviceClass.simpleName}")
|
||||||
val service = retrofitBuilder.buildRetrofit(url).create(serviceClass)
|
val (url, needAuth) = serviceParams
|
||||||
cache[url] = service
|
val service = retrofitBuilder.buildRetrofit(url, needAuth).create(serviceClass)
|
||||||
|
cache[serviceParams] = service
|
||||||
return service
|
return service
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class ServiceParams(val baseUrl: String, val needAuth: Boolean)
|
||||||
}
|
}
|
||||||
@@ -2,5 +2,5 @@ package gq.kirmanak.mealient.data.network
|
|||||||
|
|
||||||
interface ServiceFactory<T> {
|
interface ServiceFactory<T> {
|
||||||
|
|
||||||
suspend fun provideService(baseUrl: String? = null): T
|
suspend fun provideService(baseUrl: String? = null, needAuth: Boolean = true): T
|
||||||
}
|
}
|
||||||
@@ -4,19 +4,41 @@ import dagger.Module
|
|||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
import gq.kirmanak.mealient.data.network.OkHttpBuilder
|
import gq.kirmanak.mealient.data.network.AuthenticationInterceptor
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
import okhttp3.Interceptor
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
|
import javax.inject.Named
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
const val AUTH_OK_HTTP = "auth"
|
||||||
|
const val NO_AUTH_OK_HTTP = "noauth"
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
@InstallIn(SingletonComponent::class)
|
@InstallIn(SingletonComponent::class)
|
||||||
object NetworkModule {
|
object NetworkModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun createOkHttp(okHttpBuilder: OkHttpBuilder): OkHttpClient =
|
@Named(AUTH_OK_HTTP)
|
||||||
okHttpBuilder.buildOkHttp()
|
fun createAuthOkHttp(
|
||||||
|
// Use @JvmSuppressWildcards because otherwise dagger can't inject it (https://stackoverflow.com/a/43149382)
|
||||||
|
interceptors: Set<@JvmSuppressWildcards Interceptor>,
|
||||||
|
authenticationInterceptor: AuthenticationInterceptor,
|
||||||
|
): OkHttpClient = OkHttpClient.Builder()
|
||||||
|
.addInterceptor(authenticationInterceptor)
|
||||||
|
.apply { for (interceptor in interceptors) addNetworkInterceptor(interceptor) }
|
||||||
|
.build()
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Named(NO_AUTH_OK_HTTP)
|
||||||
|
fun createNoAuthOkHttp(
|
||||||
|
// Use @JvmSuppressWildcards because otherwise dagger can't inject it (https://stackoverflow.com/a/43149382)
|
||||||
|
interceptors: Set<@JvmSuppressWildcards Interceptor>,
|
||||||
|
): OkHttpClient = OkHttpClient.Builder()
|
||||||
|
.apply { for (interceptor in interceptors) addNetworkInterceptor(interceptor) }
|
||||||
|
.build()
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
|
|||||||
@@ -5,15 +5,17 @@ import com.squareup.picasso.OkHttp3Downloader
|
|||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import gq.kirmanak.mealient.BuildConfig
|
import gq.kirmanak.mealient.BuildConfig
|
||||||
|
import gq.kirmanak.mealient.di.AUTH_OK_HTTP
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Named
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class PicassoBuilder @Inject constructor(
|
class PicassoBuilder @Inject constructor(
|
||||||
@ApplicationContext private val context: Context,
|
@ApplicationContext private val context: Context,
|
||||||
private val okHttpClient: OkHttpClient
|
@Named(AUTH_OK_HTTP) private val okHttpClient: OkHttpClient
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun buildPicasso(): Picasso {
|
fun buildPicasso(): Picasso {
|
||||||
|
|||||||
Reference in New Issue
Block a user