Skip to content

Commit

Permalink
Changes for identity cache
Browse files Browse the repository at this point in the history
  • Loading branch information
markvdouw committed Jan 5, 2024
1 parent f5a405e commit dbee5d0
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 23 deletions.
64 changes: 48 additions & 16 deletions android-core/src/main/java/com/mparticle/identity/IdentityApi.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.mparticle.identity;

import static com.mparticle.identity.MParticleIdentityClientImpl.IDENTITY_TIMEOUT;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
Expand Down Expand Up @@ -50,13 +48,18 @@ public class IdentityApi {
MessageManager mMessageManager;
KitManager mKitManager;
private Internal mInternal = new Internal();
private long timeoutSeconds = 0L;

MParticleUserDelegate mUserDelegate;
private MParticleIdentityClient mApiClient;

Set<IdentityStateListener> identityStateListeners = new HashSet<IdentityStateListener>();
private static Object lock = new Object();

public static final String LOGIN_CALL = "login";
public static final String IDENTIFY_CALL = "identify";
public static final String LOGOUT_CALL = "logout";

protected IdentityApi() {
}

Expand Down Expand Up @@ -169,6 +172,7 @@ public MParticleTask<IdentityApiResult> logout() {
*/
@NonNull
public MParticleTask<IdentityApiResult> logout(@Nullable final IdentityApiRequest logoutRequest) {
resetCache();
return makeIdentityRequest(logoutRequest, new IdentityNetworkRequestRunnable() {
@Override
public IdentityHttpResponse request(IdentityApiRequest request) throws Exception {
Expand All @@ -179,7 +183,7 @@ public IdentityHttpResponse request(IdentityApiRequest request) throws Exception
public void onPostExecute(IdentityApiResult result) {
mKitManager.onLogoutCompleted(result.getUser(), logoutRequest);
}
}, false);
}, false, LOGOUT_CALL);
}

/**
Expand Down Expand Up @@ -207,14 +211,17 @@ public MParticleTask<IdentityApiResult> login(@Nullable final IdentityApiRequest
return makeIdentityRequest(loginRequest, new IdentityNetworkRequestRunnable() {
@Override
public IdentityHttpResponse request(IdentityApiRequest request) throws Exception {
return getApiClient().login(request);
IdentityHttpResponse response = getApiClient().login(request);
timeoutSeconds = response.getTimeout();
Logger.debug("TIMEOUT - IDENTITY TIMEOUT SET (SEC): "+ timeoutSeconds);
return response;
}

@Override
public void onPostExecute(IdentityApiResult result) {
mKitManager.onLoginCompleted(result.getUser(), loginRequest);
}
}, true);
}, true, LOGIN_CALL);
}

/**
Expand All @@ -230,14 +237,17 @@ public MParticleTask<IdentityApiResult> identify(@Nullable final IdentityApiRequ
return makeIdentityRequest(identifyRequest, new IdentityNetworkRequestRunnable() {
@Override
public IdentityHttpResponse request(IdentityApiRequest request) throws Exception {
return getApiClient().identify(request);
IdentityHttpResponse response = getApiClient().identify(request);
timeoutSeconds = response.getTimeout();
Logger.debug("TIMEOUT - IDENTITY TIMEOUT SET (SEC): "+ timeoutSeconds);
return response;
}

@Override
public void onPostExecute(IdentityApiResult result) {
mKitManager.onIdentifyCompleted(result.getUser(), identifyRequest);
}
}, true);
}, true, IDENTIFY_CALL);
}

/**
Expand All @@ -256,6 +266,7 @@ public BaseIdentityTask modify(@NonNull final IdentityApiRequest updateRequest)
if (updateRequest.mpid == null) {
updateRequest.mpid = mConfigManager.getMpid();
}

if (Constants.TEMPORARY_MPID.equals(updateRequest.mpid)) {
String message = "modify() requires a non-zero MPID, please make sure a MParticleUser is present before making a modify request.";
if (devMode) {
Expand All @@ -270,10 +281,12 @@ public BaseIdentityTask modify(@NonNull final IdentityApiRequest updateRequest)
@Override
public void run() {
try {
resetCache();
final IdentityHttpResponse result = getApiClient().modify(updateRequest);
if (!result.isSuccessful()) {
task.setFailed(result);
} else {
timeoutSeconds = result.getTimeout();
MParticleUserDelegate.setUserIdentities(mUserDelegate, updateRequest.getUserIdentities(), updateRequest.mpid);
task.setSuccessful(new IdentityApiResult(MParticleUserImpl.getInstance(mContext, updateRequest.mpid, mUserDelegate), null));
new Handler(Looper.getMainLooper()).post(new Runnable() {
Expand Down Expand Up @@ -352,17 +365,25 @@ private void reset() {
}
}

private boolean shouldMakeRequest(IdentityApiRequest identityRequest, boolean acceptCachedResponse) {
private boolean shouldMakeRequest(IdentityApiRequest identityRequest, boolean acceptCachedResponse, long lastIdentityCall) {
if (!acceptCachedResponse) {
Logger.debug("TIMEOUT - SHOULD MAKE REQUEST: TRUE");
return true;
}
long lastIdentityCall = 0l;// TODO get from prefs
boolean hasTimedOut = lastIdentityCall < System.currentTimeMillis() - IDENTITY_TIMEOUT; //TODO Check if the timeout should be dynamic based on server header
MParticleUser user = getUser(identityRequest.mpid);
if (hasTimedOut || isRequestDifferent(user, identityRequest)) {
return true;
boolean hasTimedOut = lastIdentityCall==-1L || (lastIdentityCall + (timeoutSeconds * 1000) > System.currentTimeMillis()) ;
Logger.debug("TIMEOUT - REQUEST TIMED OUT: " + hasTimedOut);
if (identityRequest != null && identityRequest.mpid != null) {
MParticleUser user = getUser(identityRequest.mpid);
if (hasTimedOut || isRequestDifferent(user, identityRequest)) {
Logger.debug("TIMEOUT - SHOULD MAKE REQUEST: TRUE");
return true;
} else {
Logger.debug("TIMEOUT - SHOULD MAKE REQUEST: FALSE");
return false;
}
} else {
return false;
Logger.debug("TIMEOUT - SHOULD MAKE REQUEST: TRUE");
return true;
}
}

Expand All @@ -379,19 +400,27 @@ private boolean areIdentitiesDifferent(MParticleUser user, IdentityApiRequest id
if (user != null) {
Map<MParticle.IdentityType, String> userIdentities = user.getUserIdentities() != null ? user.getUserIdentities() : new HashMap<>();
Map<MParticle.IdentityType, String> requestUserIdentities = identityApiRequest.getUserIdentities() != null ? identityApiRequest.getUserIdentities() : new HashMap<>();
Logger.debug("TIMEOUT - USER IDENTITIES: " +userIdentities);
Logger.debug("TIMEOUT - REQUEST USER IDENTITIES: " +requestUserIdentities);
Logger.debug("TIMEOUT - RESULT DIFFERENT: " + !userIdentities.equals(requestUserIdentities));
return !userIdentities.equals(requestUserIdentities);
} else {
return true;
}
}

private BaseIdentityTask makeIdentityRequest(IdentityApiRequest request, final IdentityNetworkRequestRunnable networkRequest, boolean acceptCachedResponse) {
private void resetCache() {
mConfigManager.resetIdentityTypeCall();
}

private BaseIdentityTask makeIdentityRequest(IdentityApiRequest request, final IdentityNetworkRequestRunnable networkRequest, boolean acceptCachedResponse, String call) {
long lastIdentityCallTime = mConfigManager.getLastIdentityTypeCall(call);
if (request == null) {
request = IdentityApiRequest.withEmptyUser().build();
}
final BaseIdentityTask task = new BaseIdentityTask();
final IdentityApiRequest identityApiRequest = request;
if (!shouldMakeRequest(identityApiRequest, acceptCachedResponse)) {
if (!shouldMakeRequest(identityApiRequest, acceptCachedResponse, lastIdentityCallTime)) {
//Set both current and prev user as the current one, no request was done.
task.setSuccessful(new IdentityApiResult(getUser(identityApiRequest.mpid), getCurrentUser()));
Logger.debug("Identity -Returning current user from cache");
Expand Down Expand Up @@ -419,6 +448,9 @@ public void run() {
ConfigManager.setIdentityRequestInProgress(false);
mUserDelegate.setUser(mContext, startingMpid, newMpid, identityApiRequest.getUserIdentities(), identityApiRequest.getUserAliasHandler(), isLoggedIn);
final MParticleUser previousUser = startingMpid != newMpid ? getUser(startingMpid) : null;
if (acceptCachedResponse) {
mConfigManager.setLastIdentityTypeCall(call);
}
task.setSuccessful(new IdentityApiResult(MParticleUserImpl.getInstance(mContext, newMpid, mUserDelegate), previousUser));
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public final class IdentityHttpResponse {
private String context;
private int httpCode;
private boolean loggedIn;
private long timeout = 0L;

@NonNull
public static final String MPID = "mpid";
Expand Down Expand Up @@ -50,8 +51,9 @@ public IdentityHttpResponse(int code, @NonNull String errorString) {
this.errors.add(new Error(UNKNOWN, errorString));
}

public IdentityHttpResponse(int httpCode, @Nullable JSONObject jsonObject) throws JSONException {
public IdentityHttpResponse(int httpCode, @Nullable JSONObject jsonObject, long identityTimeout) throws JSONException {
this.httpCode = httpCode;
this.timeout = identityTimeout;
if (!MPUtility.isEmpty(jsonObject)) {
if (jsonObject.has(MPID)) {
this.mpId = Long.valueOf(jsonObject.getString(MPID));
Expand Down Expand Up @@ -92,6 +94,10 @@ public long getMpId() {
return mpId;
}

public long getTimeout() {
return 30L;
}

@Nullable
public String getContext() {
return context;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public class MParticleIdentityClientImpl extends MParticleBaseClientImpl impleme
static final String DEVICE_APPLICATION_STAMP = "device_application_stamp";
static final String KNOWN_IDENTITIES = "known_identities";
static final String PREVIOUS_MPID = "previous_mpid";
static final String IDENTITY_HEADER_TIMEOUT = "X-MP-Max-Age";

static final String NEW_VALUE = "new_value";
static final String OLD_VALUE = "old_value";
Expand Down Expand Up @@ -81,10 +82,11 @@ public IdentityHttpResponse login(IdentityApiRequest request) throws JSONExcepti
String url = connection.getURL().toString();
InternalListenerManager.getListener().onNetworkRequestStarted(SdkListener.Endpoint.IDENTITY_LOGIN, url, jsonObject, request);
connection = makeUrlRequest(Endpoint.IDENTITY, connection, jsonObject.toString(), false);
String headerField = connection.getHeaderField(IDENTITY_HEADER_TIMEOUT);
int responseCode = connection.getResponseCode();
JSONObject response = MPUtility.getJsonResponse(connection);
InternalListenerManager.getListener().onNetworkRequestFinished(SdkListener.Endpoint.IDENTITY_LOGIN, url, response, responseCode);
return parseIdentityResponse(responseCode, response);
return parseIdentityResponse(responseCode, response, headerField);
}

public IdentityHttpResponse logout(IdentityApiRequest request) throws JSONException, IOException {
Expand All @@ -97,7 +99,7 @@ public IdentityHttpResponse logout(IdentityApiRequest request) throws JSONExcept
int responseCode = connection.getResponseCode();
JSONObject response = MPUtility.getJsonResponse(connection);
InternalListenerManager.getListener().onNetworkRequestFinished(SdkListener.Endpoint.IDENTITY_LOGOUT, url, response, responseCode);
return parseIdentityResponse(responseCode, response);
return parseIdentityResponse(responseCode, response, "0");
}

public IdentityHttpResponse identify(IdentityApiRequest request) throws JSONException, IOException {
Expand All @@ -107,10 +109,11 @@ public IdentityHttpResponse identify(IdentityApiRequest request) throws JSONExce
String url = connection.getURL().toString();
InternalListenerManager.getListener().onNetworkRequestStarted(SdkListener.Endpoint.IDENTITY_IDENTIFY, url, jsonObject, request);
connection = makeUrlRequest(Endpoint.IDENTITY, connection, jsonObject.toString(), false);
String headerField = connection.getHeaderField(IDENTITY_HEADER_TIMEOUT);
int responseCode = connection.getResponseCode();
JSONObject response = MPUtility.getJsonResponse(connection);
InternalListenerManager.getListener().onNetworkRequestFinished(SdkListener.Endpoint.IDENTITY_IDENTIFY, url, response, responseCode);
return parseIdentityResponse(responseCode, response);
return parseIdentityResponse(responseCode, response, headerField);
}

public IdentityHttpResponse modify(IdentityApiRequest request) throws JSONException, IOException {
Expand All @@ -125,9 +128,10 @@ public IdentityHttpResponse modify(IdentityApiRequest request) throws JSONExcept
InternalListenerManager.getListener().onNetworkRequestStarted(SdkListener.Endpoint.IDENTITY_MODIFY, url, jsonObject, request);
connection = makeUrlRequest(Endpoint.IDENTITY, connection, jsonObject.toString(), false);
int responseCode = connection.getResponseCode();
String headerField = connection.getHeaderField(IDENTITY_HEADER_TIMEOUT);
JSONObject response = MPUtility.getJsonResponse(connection);
InternalListenerManager.getListener().onNetworkRequestFinished(SdkListener.Endpoint.IDENTITY_MODIFY, url, response, responseCode);
return parseIdentityResponse(responseCode, response);
return parseIdentityResponse(responseCode, response, headerField);
}

private JSONObject getBaseJson() throws JSONException {
Expand Down Expand Up @@ -239,13 +243,18 @@ private JSONObject getChangeJson(IdentityApiRequest request) throws JSONExceptio
return jsonObject;
}

private IdentityHttpResponse parseIdentityResponse(int httpCode, JSONObject jsonObject) {
private IdentityHttpResponse parseIdentityResponse(int httpCode, JSONObject jsonObject, String identityTimeoutHeader) {
long timeoutHeader = 0L;
try {
Logger.verbose("Identity response code: " + httpCode);
if (jsonObject != null) {
Logger.verbose("Identity result: " + jsonObject.toString());
}
IdentityHttpResponse httpResponse = new IdentityHttpResponse(httpCode, jsonObject);
try {
timeoutHeader = Long.parseLong(identityTimeoutHeader);
} catch (Exception e) {
}
IdentityHttpResponse httpResponse = new IdentityHttpResponse(httpCode, jsonObject, timeoutHeader);
if (!MPUtility.isEmpty(httpResponse.getContext())) {
mConfigManager.setIdentityApiContext(httpResponse.getContext());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1244,6 +1244,22 @@ public int getIdentityConnectionTimeout() {
return sPreferences.getInt(Constants.PrefKeys.IDENTITY_CONNECTION_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT_SECONDS) * 1000;
}

public long getLastIdentityTypeCall(String call) {
return sPreferences.getLong(call, 0L);
}

public void resetIdentityTypeCall() {
SharedPreferences.Editor editor = sPreferences.edit();
editor.putLong(IdentityApi.LOGIN_CALL, -1);
editor.putLong(IdentityApi.IDENTIFY_CALL, -1);
editor.apply();
}

public void setLastIdentityTypeCall(String call) {
Logger.debug("TIMEOUT - SET LAST IDENTITY TIME CALL FOR " + call + " : " + System.currentTimeMillis());
sPreferences.edit().putLong(call, System.currentTimeMillis()).apply();
}

public int getConnectionTimeout() {
return DEFAULT_CONNECTION_TIMEOUT_SECONDS * 1000;
}
Expand Down

0 comments on commit dbee5d0

Please sign in to comment.