diff --git a/app/src/main/java/com/naviapp/manager/RetryableUserDataUploadWorker.kt b/app/src/main/java/com/naviapp/manager/RetryableUserDataUploadWorker.kt index 1d883dcc48..45450c9906 100644 --- a/app/src/main/java/com/naviapp/manager/RetryableUserDataUploadWorker.kt +++ b/app/src/main/java/com/naviapp/manager/RetryableUserDataUploadWorker.kt @@ -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) { sendEventTracker(eventName, mapOf("ingestionList" to list.toString())) } diff --git a/app/src/main/java/com/naviapp/manager/repositories/UserDataRepository.kt b/app/src/main/java/com/naviapp/manager/repositories/UserDataRepository.kt index 6c730c545d..6be1d41538 100644 --- a/app/src/main/java/com/naviapp/manager/repositories/UserDataRepository.kt +++ b/app/src/main/java/com/naviapp/manager/repositories/UserDataRepository.kt @@ -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)) diff --git a/app/src/main/java/com/naviapp/manager/usecase/UserDataUploadWorkerUseCase.kt b/app/src/main/java/com/naviapp/manager/usecase/UserDataUploadWorkerUseCase.kt index ac79580161..a00a6b9cc2 100644 --- a/app/src/main/java/com/naviapp/manager/usecase/UserDataUploadWorkerUseCase.kt +++ b/app/src/main/java/com/naviapp/manager/usecase/UserDataUploadWorkerUseCase.kt @@ -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 = diff --git a/app/src/main/java/com/naviapp/network/retrofit/RetrofitService.kt b/app/src/main/java/com/naviapp/network/retrofit/RetrofitService.kt index 76ce46fc4f..65ab647414 100644 --- a/app/src/main/java/com/naviapp/network/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/naviapp/network/retrofit/RetrofitService.kt @@ -1577,6 +1577,12 @@ interface RetrofitService { @Body preSignedUrlRequest: PreSignedUrlRequest ): Response> + @GET("/customer-device/customer/me/pre-signed-url/v2") + suspend fun getPreSignedUrlListV2( + @Header("X-Target") header: String, + @QueryMap queryMap: Map + ): Response> + @GET("/requests/{requestId}") suspend fun getSigningData( @Path("requestId") requestId: String diff --git a/app/src/main/java/com/naviapp/utils/Constants.kt b/app/src/main/java/com/naviapp/utils/Constants.kt index 464d3fa0ca..e32f91b45b 100644 --- a/app/src/main/java/com/naviapp/utils/Constants.kt +++ b/app/src/main/java/com/naviapp/utils/Constants.kt @@ -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" diff --git a/navi-common/src/main/java/com/navi/common/model/NetworkInfo.kt b/navi-common/src/main/java/com/navi/common/model/NetworkInfo.kt index 2c48b31004..8bd968de1d 100644 --- a/navi-common/src/main/java/com/navi/common/model/NetworkInfo.kt +++ b/navi-common/src/main/java/com/navi/common/model/NetworkInfo.kt @@ -34,5 +34,6 @@ enum class ModuleName { KYC_GATEWAY, // For KYC API OPL, // For OPL HL, - KRUZ_PROXY + KRUZ_PROXY, + CDS // for device data }