TP-60060 | add sync api call for data pre signed url (#10081)

This commit is contained in:
Abhinav Gupta
2024-03-25 15:23:20 +05:30
committed by GitHub
parent 5c61fd4412
commit c420662b60
6 changed files with 103 additions and 36 deletions

View File

@@ -18,11 +18,13 @@ import com.navi.common.useruploaddata.model.IngestionStatusBody
import com.navi.common.useruploaddata.model.IngestionType
import com.navi.common.utils.ApiPollScheduler
import com.navi.common.utils.deviceId
import com.navi.common.utils.isValidResponse
import com.naviapp.analytics.utils.NaviAnalytics
import com.naviapp.manager.model.UserDataUploadWorkerConfig
import com.naviapp.manager.repositories.UserDataRepository
import com.naviapp.manager.usecase.UserDataUploadWorkerUseCase
import com.naviapp.models.request.PreSignedUrlRequest
import com.naviapp.models.response.PreSignedUrlListResponse
import com.naviapp.utils.Constants
import com.naviapp.utils.Constants.DEFAULT
import com.naviapp.utils.Constants.FAILED
@@ -84,8 +86,38 @@ class RetryableUserDataUploadWorker(val context: Context, workerParams: WorkerPa
)
}
/**
* First, we attempt to fetch a sync API call for a pre-signed URL. If this API call returns an
* error, we then switch to an async flow.
*/
private suspend fun uploadUserData() {
sendEventTracker(UserDataUploadWorkerUseCase.PL_GET_PRE_SIGNED_URL_CALL_INITIATED)
val syncApiResponse =
repository.getPreSignedUrlV2(
Constants.SMS_CONTACT_APPS,
userDataUploadWorkerConfig.workerType
)
if (syncApiResponse.isValidResponse()) {
uploadDataToUrl(syncApiResponse.data, CoroutineScope(Dispatchers.IO)) {
handleAPIFailure(syncApiResponse.error ?: syncApiResponse.errors)
}
} else if (
syncApiResponse.statusCode in listOf(404, 429) || syncApiResponse.statusCode in 500..599
) {
uploadUserDataWithAsyncFlow()
} else {
handleAPIFailure(syncApiResponse.error ?: syncApiResponse.errors)
sendEventTracker(
UserDataUploadWorkerUseCase.PL_ERROR_IN_GETTING_PRESIGNED_URL_SYNC,
mapOf(
"error" to (syncApiResponse.error ?: syncApiResponse.errors).toString(),
"workerType" to userDataUploadWorkerConfig.workerType
)
)
}
}
private suspend fun RetryableUserDataUploadWorker.uploadUserDataWithAsyncFlow() {
val response =
repository.getPreSignedUrl(
PreSignedUrlRequest(
@@ -167,41 +199,9 @@ class RetryableUserDataUploadWorker(val context: Context, workerParams: WorkerPa
response.error == null &&
response.errors.isNullOrEmpty()
) {
val list =
extractTasks(
response.data?.details?.innerData,
scope,
userDataUploadWorkerConfig.workerType,
userDataUploadWorkerConfig.sourceScreenName
)
.awaitAll()
.filterNotNull()
apiPollScheduler?.stopApiPoll()
sendEventTracker(UserDataUploadWorkerUseCase.PL_DEV_USER_DATA_UPLOAD_FINISH)
if (list.isNotEmpty()) {
sendEventTracker(
UserDataUploadWorkerUseCase.on_data_upload_acknowledgement_initiated,
mapOf("ingestionList" to list.toString())
)
val dataIngestionResponse =
repository.postIngestionStatus(IngestionStatusBody(list))
if (dataIngestionResponse.isSuccess()) {
sendEventWithIndigestionList(
UserDataUploadWorkerUseCase.on_data_upload_acknowledgement_success,
list
)
} else {
handleAPIFailure(response.error ?: response.errors)
sendEventWithIndigestionList(
UserDataUploadWorkerUseCase.on_data_upload_acknowledgement_failure,
list
)
}
} else {
sendEventWithIndigestionList(
UserDataUploadWorkerUseCase.PL_Ingestion_Task_List_Empty,
list
)
uploadDataToUrl(response.data?.details?.innerData, scope) {
handleAPIFailure(response.error ?: response.errors)
}
} else if (response.data?.status.orEmpty() == FAILED) {
apiPollScheduler?.stopApiPoll()
@@ -214,6 +214,47 @@ class RetryableUserDataUploadWorker(val context: Context, workerParams: WorkerPa
}
}
private suspend fun uploadDataToUrl(
preSignedUrlListResponse: PreSignedUrlListResponse?,
scope: CoroutineScope,
handleApiFailure: (() -> Unit)? = null
) {
val list =
extractTasks(
preSignedUrlListResponse,
scope,
userDataUploadWorkerConfig.workerType,
userDataUploadWorkerConfig.sourceScreenName
)
.awaitAll()
.filterNotNull()
sendEventTracker(UserDataUploadWorkerUseCase.PL_DEV_USER_DATA_UPLOAD_FINISH)
if (list.isNotEmpty()) {
sendEventTracker(
UserDataUploadWorkerUseCase.on_data_upload_acknowledgement_initiated,
mapOf("ingestionList" to list.toString())
)
val dataIngestionResponse = repository.postIngestionStatus(IngestionStatusBody(list))
if (dataIngestionResponse.isSuccess()) {
sendEventWithIndigestionList(
UserDataUploadWorkerUseCase.on_data_upload_acknowledgement_success,
list
)
} else {
handleApiFailure?.invoke()
sendEventWithIndigestionList(
UserDataUploadWorkerUseCase.on_data_upload_acknowledgement_failure,
list
)
}
} else {
sendEventWithIndigestionList(
UserDataUploadWorkerUseCase.PL_Ingestion_Task_List_Empty,
list
)
}
}
private fun sendEventWithIndigestionList(eventName: String, list: List<IngestionStatus>) {
sendEventTracker(eventName, mapOf("ingestionList" to list.toString()))
}

View File

@@ -7,18 +7,21 @@
package com.naviapp.manager.repositories
import com.navi.common.utils.retrofitService as commonRetrofitService
import com.navi.analytics.utils.NaviTrackEvent
import com.navi.common.model.DeviceDetail
import com.navi.common.model.ModuleName
import com.navi.common.model.UserDataWrapper
import com.navi.common.model.UserSms
import com.navi.common.useruploaddata.model.IngestionStatusBody
import com.navi.common.utils.retrofitService as commonRetrofitService
import com.naviapp.models.UserContact
import com.naviapp.models.UserInstalledApp
import com.naviapp.models.request.PreSignedUrlRequest
import com.naviapp.network.retrofit.ResponseCallback
import com.naviapp.utils.Constants.DATA_INGESTION_TYPES
import com.naviapp.utils.Constants.STATE
import com.naviapp.utils.retrofitService
import com.naviapp.utils.superAppRetrofitService
import okhttp3.RequestBody
import retrofit2.Response
@@ -69,6 +72,18 @@ class UserDataRepository : ResponseCallback() {
suspend fun getPreSignedUrl(data: PreSignedUrlRequest) =
apiResponseCallback(retrofitService().getPreSignedUrl(data))
suspend fun getPreSignedUrlV2(
dataIngestionTypes: String,
workerType: String,
) =
apiResponseCallback(
superAppRetrofitService()
.getPreSignedUrlListV2(
ModuleName.CDS.name,
mapOf(DATA_INGESTION_TYPES to dataIngestionTypes, STATE to workerType)
)
)
suspend fun getSigningData(requestId: String) =
apiResponseCallback(retrofitService().getSigningData(requestId))

View File

@@ -206,6 +206,7 @@ class UserDataUploadWorkerUseCase @Inject constructor(@ApplicationContext val co
const val PL_DEV_USER_DATA_UPLOAD_FINISH = "PL_DEV_USER_DATA_UPLOAD_FINISH"
const val PL_DEV_USER_DATA_UPLOAD_FAILED = "PL_DEV_USER_DATA_UPLOAD_FAILED"
const val PL_ERROR_IN_GETTING_PRESIGNED_URL = "PL_ERROR_IN_GETTING_PRESIGNED_URL"
const val PL_ERROR_IN_GETTING_PRESIGNED_URL_SYNC = "PL_ERROR_IN_GETTING_PRESIGNED_URL_SYNC"
const val on_data_upload_retry_count_finished =
"on_data_upload_retry_count_finished"
const val on_data_upload_retry_on_api_failure =

View File

@@ -1577,6 +1577,12 @@ interface RetrofitService {
@Body preSignedUrlRequest: PreSignedUrlRequest
): Response<GenericResponse<UploadDataAsyncResponse>>
@GET("/customer-device/customer/me/pre-signed-url/v2")
suspend fun getPreSignedUrlListV2(
@Header("X-Target") header: String,
@QueryMap queryMap: Map<String, String>
): Response<GenericResponse<PreSignedUrlListResponse>>
@GET("/requests/{requestId}")
suspend fun getSigningData(
@Path("requestId") requestId: String

View File

@@ -449,6 +449,9 @@ object Constants {
const val NAVI_MQTT_PUSH_NOTIFICATION = "NaviMqttPushNotification"
const val SETUP_AUTO_DEBIT_SCREEN = "setup_auto_debit_screen"
const val CLIENT_MESSAGE_ID = "clientMessageId"
const val SMS_CONTACT_APPS = "SMS,CONTACTS,APPS"
const val DATA_INGESTION_TYPES = "dataIngestionTypes"
const val STATE = "state"
object Notification {
const val HIDE_NOTIFICATION_COUNT = "hideNotificationCount"

View File

@@ -34,5 +34,6 @@ enum class ModuleName {
KYC_GATEWAY, // For KYC API
OPL, // For OPL
HL,
KRUZ_PROXY
KRUZ_PROXY,
CDS // for device data
}