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

Refactor/adding data sources abstractions #87

Merged
merged 14 commits into from
Jan 11, 2025
Merged
Show file tree
Hide file tree
Changes from 13 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
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ import com.personalization.sdk.domain.usecases.preferences.GetPreferencesValueUs
import com.personalization.sdk.domain.usecases.preferences.SavePreferencesValueUseCase
import com.personalization.sdk.domain.usecases.userSettings.GetUserSettingsValueUseCase
import com.personalization.sdk.domain.usecases.userSettings.UpdateUserSettingsValueUseCase
import java.security.SecureRandom
import java.util.Date
import java.util.TimeZone
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.json.JSONObject
import java.security.SecureRandom
import java.util.Date
import java.util.TimeZone
import javax.inject.Inject

class RegisterManager @Inject constructor(
private val getPreferencesValueUseCase: GetPreferencesValueUseCase,
Expand Down Expand Up @@ -121,7 +121,7 @@ class RegisterManager @Inject constructor(
lastUpdate: Long
): Boolean {
return autoSendPushToken &&
(savedToken.isEmpty() || savedToken != newToken || (currentDate - lastUpdate >= ONE_WEEK_MILLISECONDS))
(savedToken.isEmpty() || savedToken != newToken || (currentDate - lastUpdate >= ONE_WEEK_MILLISECONDS))
}

private fun sendPushTokenToServer(token: String, currentDate: Long) {
Expand Down Expand Up @@ -223,7 +223,6 @@ class RegisterManager @Inject constructor(
}

private fun initializeSdk(seance: String?) {
updateUserSettingsValueUseCase.updateIsInitialized(value = true)
val finalSeance = seance ?: generateOrRetrieveSeance()
updateUserSettingsValueUseCase.updateSid(value = finalSeance)
executeQueueTasksUseCase.invoke()
Expand Down
31 changes: 2 additions & 29 deletions personalization-sdk/src/main/kotlin/com/personalization/SDK.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import org.json.JSONObject
open class SDK {

internal lateinit var context: Context
private lateinit var segment: String

private var onMessageListener: OnMessageListener? = null
private var search: Search = Search(JSONObject())
Expand Down Expand Up @@ -144,13 +143,11 @@ open class SDK {
context = context,
preferencesKey = preferencesKey
)
segment = getPreferencesValueUseCase.getSegment()

notificationHandler.initialize(context = context)

initUserSettingsUseCase.invoke(
shopId = shopId,
segment = segment,
stream = stream
)

Expand Down Expand Up @@ -246,14 +243,7 @@ open class SDK {
replaceWith = ReplaceWith("getSid(): String")
)
fun getSid(listener: Consumer<String?>) {
val thread = Thread {
listener.accept(getSid())
}
if (getUserSettingsValueUseCase.getIsInitialized()) {
thread.start()
} else {
addTaskToQueueUseCase.invoke(thread)
}
listener.accept(getSid())
}

/**
Expand Down Expand Up @@ -618,13 +608,6 @@ open class SDK {
* @param subscriptions
* @param listener
*/
/**
* Manage subscriptions
*
* @param email
* @param phone
* @param subscriptions
*/
fun manageSubscription(
email: String?,
phone: String?,
Expand Down Expand Up @@ -653,16 +636,6 @@ open class SDK {
* @param subscriptions
* @param listener
*/
/**
* Manage subscriptions
*
* @param email
* @param phone
* @param externalId
* @param loyaltyId
* @param telegramId
* @param subscriptions
*/
@JvmOverloads
fun manageSubscription(
email: String?,
Expand Down Expand Up @@ -702,7 +675,7 @@ open class SDK {
/**
* Returns the current segment for A/B testing
*/
fun getSegment(): String = instance.segment
fun getSegment(): String = getUserSettingsValueUseCase.getSegmentForABTesting()

/**
* Add user to a segment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,4 @@ interface SdkComponent {
fun inject(sdk: SDK)

fun inject(service: NotificationService)

}
Original file line number Diff line number Diff line change
@@ -1,47 +1,34 @@
package com.personalization.sdk.data.di

import com.personalization.sdk.data.repositories.network.NetworkDataSource
import com.personalization.sdk.data.repositories.notification.NotificationDataSource
import com.personalization.sdk.data.repositories.notification.NotificationDataSourceImpl
import com.personalization.sdk.data.repositories.preferences.PreferencesDataSource
import com.personalization.sdk.data.repositories.preferences.PreferencesDataSourceImpl
import com.personalization.sdk.data.repositories.recommendation.RecommendationDataSource
import com.personalization.sdk.data.repositories.userSettings.UserSettingsDataSource
import com.personalization.sdk.data.repositories.recommendation.RecommendationDataSourceImpl
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import javax.inject.Singleton

@Module
class DataSourcesModule {
interface DataSourcesModule {

@Provides
@Binds
@Singleton
fun providePreferencesDataSource() = PreferencesDataSource()
fun bindPreferencesDataSource(impl: PreferencesDataSourceImpl): PreferencesDataSource

@AssistedFactory
interface NetworkDataSourceFactory {
fun create(
baseUrl: String
): NetworkDataSource
}

@AssistedFactory
interface UserSettingsDataSourceFactory {
fun create(
@Assisted("shopId") shopId: String,
@Assisted("segment") segment: String,
@Assisted("stream") stream: String
): UserSettingsDataSource
}

@Provides
@Binds
@Singleton
fun provideRecommendationDataSource() = RecommendationDataSource()
fun bindRecommendationDataSource(impl: RecommendationDataSourceImpl): RecommendationDataSource

companion object {

@Provides
fun provideNotificationDataSource(
preferencesDataSource: PreferencesDataSource
) = NotificationDataSource(
preferencesDataSource = preferencesDataSource
)
@Provides
fun provideNotificationDataSource(
preferencesDataSource: PreferencesDataSource
): NotificationDataSource = NotificationDataSourceImpl(
preferencesDataSource = preferencesDataSource
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.personalization.sdk.data.models.params

object UserBasicParams {
const val SHOP_ID = "shop_id"
const val DID = "did"
const val SEANCE = "seance"
const val SID = "sid"
const val SEGMENT = "segment"
const val STREAM = "stream"
const val SOURCE_FROM = "from"
const val SOURCE_CODE = "code"
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@ package com.personalization.sdk.data.repositories.network
import android.net.Uri
import com.personalization.SDK
import com.personalization.api.OnApiCallbackListener
import com.personalization.sdk.data.di.DataSourcesModule
import com.personalization.sdk.data.models.params.UserBasicParams
import com.personalization.sdk.data.utils.QueryParamsUtils.addMultipleParams
import com.personalization.sdk.domain.models.NetworkMethod
import com.personalization.sdk.domain.models.NotificationSource
import com.personalization.sdk.domain.repositories.NetworkRepository
import com.personalization.sdk.domain.repositories.NotificationRepository
import com.personalization.sdk.domain.repositories.UserSettingsRepository
import com.personalization.utils.TimeUtils
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import org.json.JSONTokener
import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.IOException
Expand All @@ -20,27 +27,20 @@ import java.net.URL
import java.nio.charset.StandardCharsets
import java.util.Collections
import javax.inject.Inject
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import org.json.JSONTokener

class NetworkRepositoryImpl @Inject constructor(
private val networkDataSourceFactory: DataSourcesModule.NetworkDataSourceFactory,
private val userSettingsRepository: UserSettingsRepository,
private val notificationRepository: NotificationRepository
private val notificationRepository: NotificationRepository,
) : NetworkRepository {

private val queue: MutableList<Thread> = Collections.synchronizedList(ArrayList())
private lateinit var baseUrl: String

private var networkDataSource: NetworkDataSource? = null
private val queue: MutableList<Thread> = Collections.synchronizedList(ArrayList())

override fun initialize(
baseUrl: String
) {
networkDataSource = networkDataSourceFactory.create(
baseUrl = baseUrl
)
this.baseUrl = baseUrl
}

override fun post(
Expand Down Expand Up @@ -126,7 +126,7 @@ class NetworkRepositoryImpl @Inject constructor(
private fun sendAsync(sendFunction: () -> Unit) {
val thread = Thread(sendFunction)
if (userSettingsRepository.getDid()
.isNotEmpty() && userSettingsRepository.getIsInitialized()
.isNotEmpty()
) {
thread.start()
} else {
Expand Down Expand Up @@ -165,10 +165,10 @@ class NetworkRepositoryImpl @Inject constructor(
userSettingsRepository.updateSidLastActTime()

val notificationSource =
notificationRepository.getNotificationSource(NetworkDataSource.sourceTimeDuration)
notificationRepository.getNotificationSource(TimeUtils.TWO_DAYS.inWholeMilliseconds)

try {
val newParams = userSettingsRepository.addParams(
val newParams = addBasicQueryParams(
params = params,
notificationSource = notificationSource,
)
Expand All @@ -179,6 +179,26 @@ class NetworkRepositoryImpl @Inject constructor(
}
}

private fun addBasicQueryParams(
params: JSONObject,
notificationSource: NotificationSource?
): JSONObject {
addMultipleParams(
params = params,
paramsToAdd = mapOf(
UserBasicParams.SHOP_ID to userSettingsRepository.getShopId(),
UserBasicParams.DID to userSettingsRepository.getDid(),
UserBasicParams.SID to userSettingsRepository.getSid(),
UserBasicParams.SEANCE to userSettingsRepository.getSid(),
UserBasicParams.SEGMENT to userSettingsRepository.getSegmentForABTesting(),
UserBasicParams.STREAM to userSettingsRepository.getStream(),
UserBasicParams.SOURCE_FROM to notificationSource?.type,
UserBasicParams.SOURCE_CODE to notificationSource?.id
)
)
return params
}

private fun executeMethod(
networkMethod: NetworkMethod,
params: JSONObject,
Expand Down Expand Up @@ -230,9 +250,8 @@ class NetworkRepositoryImpl @Inject constructor(
networkMethod: NetworkMethod,
params: JSONObject
): Uri {
if (networkDataSource == null) throw Exception("Network not initialized.")

val builder = Uri.parse(networkDataSource!!.baseUrl + networkMethod.method).buildUpon()
val builder = Uri.parse(baseUrl + networkMethod.method).buildUpon()

val it = params.keys()
while (it.hasNext()) {
Expand All @@ -247,10 +266,9 @@ class NetworkRepositoryImpl @Inject constructor(
networkMethod: NetworkMethod,
buildUri: Uri
): URL {
if (networkDataSource == null) throw Exception("Network not initialized.")

return if (networkMethod is NetworkMethod.POST) {
URL(networkDataSource!!.baseUrl + networkMethod.method)
URL(baseUrl + networkMethod.method)
} else {
URL(buildUri.toString())
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,14 @@
package com.personalization.sdk.data.repositories.notification

import com.personalization.sdk.data.models.NotificationSourceDto
import com.personalization.sdk.data.repositories.preferences.PreferencesDataSource
import javax.inject.Inject

class NotificationDataSource @Inject constructor(
private val preferencesDataSource: PreferencesDataSource
) {
interface NotificationDataSource {

internal fun getNotificationSourceDto(): NotificationSourceDto {
return NotificationSourceDto(
type = getType(),
id = getId(),
time = getTime()
)
}
fun getNotificationSourceDto(): NotificationSourceDto

private fun getType(): String = preferencesDataSource.getValue(SOURCE_TYPE_KEY, DEFAULT_TYPE)
internal fun saveType(value: String) = preferencesDataSource.saveValue(SOURCE_TYPE_KEY, value)
fun saveType(value: String)

private fun getId(): String = preferencesDataSource.getValue(SOURCE_ID_KEY, DEFAULT_ID)
internal fun saveId(value: String) = preferencesDataSource.saveValue(SOURCE_ID_KEY, value)
fun saveId(value: String)

private fun getTime(): Long = preferencesDataSource.getValue(SOURCE_TIME_KEY, DEFAULT_TIME)
internal fun saveTime(value: Long) = preferencesDataSource.saveValue(SOURCE_TIME_KEY, value)

companion object {
private const val DEFAULT_TYPE: String = ""
private const val DEFAULT_ID: String = ""
private const val DEFAULT_TIME: Long = 0L

private const val SOURCE_TYPE_KEY: String = "source_type"
private const val SOURCE_ID_KEY: String = "source_id"
private const val SOURCE_TIME_KEY: String = "source_time"
}
fun saveTime(value: Long)
}
Loading
Loading