Skip to content

Commit

Permalink
Update User & Subscription operation executors to set the tokens
Browse files Browse the repository at this point in the history
Motivation: the executors call the respective backend services who's result will include the token value. We then hold in memory via `setRywToken`
  • Loading branch information
Rodrigo Gomez Palacio committed Sep 24, 2024
1 parent c7a29a7 commit 9509689
Show file tree
Hide file tree
Showing 4 changed files with 1,131 additions and 969 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import com.onesignal.common.DeviceUtils
import com.onesignal.common.NetworkUtils
import com.onesignal.common.OneSignalUtils
import com.onesignal.common.RootToolsInternalMethods
import com.onesignal.common.consistency.enums.IamFetchRywTokenKey
import com.onesignal.common.consistency.models.IConsistencyManager
import com.onesignal.common.exceptions.BackendException
import com.onesignal.common.modeling.ModelChangeTags
import com.onesignal.core.internal.application.IApplicationService
Expand Down Expand Up @@ -39,6 +41,7 @@ internal class SubscriptionOperationExecutor(
private val _configModelStore: ConfigModelStore,
private val _buildUserService: IRebuildUserService,
private val _newRecordState: NewRecordsState,
private val _consistencyManager: IConsistencyManager,
) : IOperationExecutor {
override val operations: List<String>
get() = listOf(CREATE_SUBSCRIPTION, UPDATE_SUBSCRIPTION, DELETE_SUBSCRIPTION, TRANSFER_SUBSCRIPTION)
Expand Down Expand Up @@ -101,14 +104,19 @@ internal class SubscriptionOperationExecutor(
AndroidUtils.getAppVersion(_applicationService.appContext),
)

val backendSubscriptionId =
val result =
_subscriptionBackend.createSubscription(
createOperation.appId,
IdentityConstants.ONESIGNAL_ID,
createOperation.onesignalId,
subscription,
) ?: return ExecutionResponse(ExecutionResult.SUCCESS)

val backendSubscriptionId = result.first
val rywToken = result.second

_consistencyManager.setRywToken(createOperation.onesignalId, IamFetchRywTokenKey.SUBSCRIPTION, rywToken)

// update the subscription model with the new ID, if it's still active.
val subscriptionModel = _subscriptionModelStore.get(createOperation.subscriptionId)
subscriptionModel?.setStringProperty(
Expand Down Expand Up @@ -175,7 +183,8 @@ internal class SubscriptionOperationExecutor(
AndroidUtils.getAppVersion(_applicationService.appContext),
)

_subscriptionBackend.updateSubscription(lastOperation.appId, lastOperation.subscriptionId, subscription)
val rywToken = _subscriptionBackend.updateSubscription(lastOperation.appId, lastOperation.subscriptionId, subscription)
_consistencyManager.setRywToken(startingOperation.onesignalId, IamFetchRywTokenKey.SUBSCRIPTION, rywToken)
} catch (ex: BackendException) {
val responseType = NetworkUtils.getResponseStatusType(ex.statusCode)

Expand Down Expand Up @@ -216,6 +225,7 @@ internal class SubscriptionOperationExecutor(
return ExecutionResponse(ExecutionResult.SUCCESS)
}

// TODO: whenever the end-user changes users, we need to add the read-your-write token here, currently no code to handle the re-fetch IAMs
private suspend fun transferSubscription(startingOperation: TransferSubscriptionOperation): ExecutionResponse {
try {
_subscriptionBackend.transferSubscription(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.onesignal.user.internal.operations.impl.executors

import com.onesignal.common.NetworkUtils
import com.onesignal.common.consistency.enums.IamFetchRywTokenKey
import com.onesignal.common.consistency.models.IConsistencyManager
import com.onesignal.common.exceptions.BackendException
import com.onesignal.common.modeling.ModelChangeTags
import com.onesignal.core.internal.operations.ExecutionResponse
Expand Down Expand Up @@ -31,12 +33,13 @@ internal class UpdateUserOperationExecutor(
private val _propertiesModelStore: PropertiesModelStore,
private val _buildUserService: IRebuildUserService,
private val _newRecordState: NewRecordsState,
private val _consistencyManager: IConsistencyManager,
) : IOperationExecutor {
override val operations: List<String>
get() = listOf(SET_TAG, DELETE_TAG, SET_PROPERTY, TRACK_SESSION_START, TRACK_SESSION_END, TRACK_PURCHASE)

override suspend fun execute(ops: List<Operation>): ExecutionResponse {
Logging.log(LogLevel.DEBUG, "UpdateUserOperationExecutor(operation: $ops)")
override suspend fun execute(operations: List<Operation>): ExecutionResponse {
Logging.log(LogLevel.DEBUG, "UpdateUserOperationExecutor(operation: $operations)")

var appId: String? = null
var onesignalId: String? = null
Expand All @@ -45,7 +48,7 @@ internal class UpdateUserOperationExecutor(
var deltasObject = PropertiesDeltasObject()
var refreshDeviceMetadata = false

for (operation in ops) {
for (operation in operations) {
when (operation) {
is SetTagOperation -> {
if (appId == null) {
Expand Down Expand Up @@ -83,7 +86,8 @@ internal class UpdateUserOperationExecutor(
// that exist in this group.
val sessionCount = if (deltasObject.sessionCount != null) deltasObject.sessionCount!! + 1 else 1

deltasObject = PropertiesDeltasObject(deltasObject.sessionTime, sessionCount, deltasObject.amountSpent, deltasObject.purchases)
deltasObject =
PropertiesDeltasObject(deltasObject.sessionTime, sessionCount, deltasObject.amountSpent, deltasObject.purchases)
refreshDeviceMetadata = true
}
is TrackSessionEndOperation -> {
Expand All @@ -94,9 +98,15 @@ internal class UpdateUserOperationExecutor(

// The session time we pass up is the total session time across all `TrackSessionEndOperation`
// operations that exist in this group.
val sessionTime = if (deltasObject.sessionTime != null) deltasObject.sessionTime!! + operation.sessionTime else operation.sessionTime
val sessionTime =
if (deltasObject.sessionTime != null) {
deltasObject.sessionTime!! + operation.sessionTime
} else {
operation.sessionTime
}

deltasObject = PropertiesDeltasObject(sessionTime, deltasObject.sessionCount, deltasObject.amountSpent, deltasObject.purchases)
deltasObject =
PropertiesDeltasObject(sessionTime, deltasObject.sessionCount, deltasObject.amountSpent, deltasObject.purchases)
}
is TrackPurchaseOperation -> {
if (appId == null) {
Expand All @@ -107,7 +117,12 @@ internal class UpdateUserOperationExecutor(
// The amount spent we pass up is the total amount spent across all `TrackPurchaseOperation`
// operations that exist in this group, while the purchases is the union of all
// `TrackPurchaseOperation` operations that exist in this group.
val amountSpent = if (deltasObject.amountSpent != null) deltasObject.amountSpent!! + operation.amountSpent else operation.amountSpent
val amountSpent =
if (deltasObject.amountSpent != null) {
deltasObject.amountSpent!! + operation.amountSpent
} else {
operation.amountSpent
}
val purchasesArray = if (deltasObject.purchases != null) deltasObject.purchases!!.toMutableList() else mutableListOf()

for (purchase in operation.purchases) {
Expand All @@ -122,18 +137,21 @@ internal class UpdateUserOperationExecutor(

if (appId != null && onesignalId != null) {
try {
_userBackend.updateUser(
appId,
IdentityConstants.ONESIGNAL_ID,
onesignalId,
propertiesObject,
refreshDeviceMetadata,
deltasObject,
)
val rywToken =
_userBackend.updateUser(
appId,
IdentityConstants.ONESIGNAL_ID,
onesignalId,
propertiesObject,
refreshDeviceMetadata,
deltasObject,
)

_consistencyManager.setRywToken(onesignalId, IamFetchRywTokenKey.USER, rywToken)

if (_identityModelStore.model.onesignalId == onesignalId) {
// go through and make sure any properties are in the correct model state
for (operation in ops) {
for (operation in operations) {
when (operation) {
is SetTagOperation ->
_propertiesModelStore.model.tags.setStringProperty(
Expand Down
Loading

0 comments on commit 9509689

Please sign in to comment.