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

feat: Identity API response caching #513

Open
wants to merge 12 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -6,6 +6,7 @@ import android.os.Looper
import com.mparticle.MParticle
import com.mparticle.MParticle.IdentityType
import com.mparticle.internal.ConfigManager
import com.mparticle.internal.Logger
import com.mparticle.networking.Matcher
import com.mparticle.testutils.AndroidUtils
import com.mparticle.testutils.BaseCleanStartedEachTest
Expand Down Expand Up @@ -96,8 +97,9 @@ class IdentityApiTest : BaseCleanStartedEachTest() {
val user2Called = AndroidUtils.Mutable(false)
val user3Called = AndroidUtils.Mutable(false)
val latch: CountDownLatch = MPLatch(3)

MParticle.getInstance()!!.Identity().addIdentityStateListener { user, previousUser ->
if (user != null && user.id == mpid1) {
if (user != null && user.id == mStartingMpid) {
user1Called.value = true
latch.countDown()
}
Expand All @@ -111,26 +113,27 @@ class IdentityApiTest : BaseCleanStartedEachTest() {

// test that change actually took place
result.addSuccessListener { identityApiResult ->
Assert.assertEquals(identityApiResult.user.id, mpid1)
Assert.assertEquals(identityApiResult.previousUser!!.id, mStartingMpid.toLong())
Assert.assertEquals(identityApiResult.user.id, mStartingMpid)
// After Adding Identity caching, it uses previous response
// Assert.assertEquals(identityApiResult.previousUser!!.id, mStartingMpid.toLong())
Mansi-mParticle marked this conversation as resolved.
Show resolved Hide resolved
}
com.mparticle.internal.AccessUtils.awaitUploadHandler()
request = IdentityApiRequest.withEmptyUser().build()
result = MParticle.getInstance()!!.Identity().identify(request)
result.addSuccessListener { identityApiResult ->
Assert.assertEquals(identityApiResult.user.id, mpid2)
Assert.assertEquals(identityApiResult.user.id, mStartingMpid)
Assert.assertEquals(
identityApiResult.user.id,
MParticle.getInstance()!!
.Identity().currentUser!!.id
)
Assert.assertEquals(identityApiResult.previousUser!!.id, mpid1)
// Assert.assertEquals(identityApiResult.previousUser!!.id, mpid1)
latch.countDown()
user3Called.value = true
}
latch.await()
Assert.assertTrue(user1Called.value)
Assert.assertTrue(user2Called.value)
// Assert.assertTrue(user1Called.value)
Assert.assertTrue(user3Called.value)
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.junit.Assert
import org.junit.Before
import org.junit.Test
import java.io.IOException
import java.lang.reflect.Field
import java.lang.reflect.Method
import java.util.concurrent.CountDownLatch

Expand Down Expand Up @@ -88,6 +89,67 @@ class MParticleIdentityClientImplTest : BaseCleanStartedEachTest() {
Assert.assertTrue(called.value)
}

@Test
@Throws(Exception::class)
fun testLoginWithTwoSameUsers() {
// clear existing catch
clearIdentityCache()
val latch: CountDownLatch = MPLatch(2)
val handler = Handler(Looper.getMainLooper())
handler.postDelayed({ Assert.fail("Process not complete") }, (10 * 1000).toLong())
val called = AndroidUtils.Mutable(false)
val identityRequest = IdentityApiRequest.withEmptyUser()
.email("[email protected]")
.customerId("TestUser777777")
.build()
// Login with First User
Thread {
MParticle.getInstance()?.Identity()?.login(identityRequest)?.addSuccessListener {
latch.countDown()
}
// Login With same User
MParticle.getInstance()?.Identity()?.login(identityRequest)?.addSuccessListener {
val currentLoginRequestCount = mServer.Requests().login.size
Assert.assertEquals(1, currentLoginRequestCount)
called.value = true
latch.countDown()
}
latch.await()
Assert.assertTrue(called.value)
}.start()
}

@Test
@Throws(Exception::class)
fun testLoginWithTwoSameUsers_withLogout() {
// clear existing catch
clearIdentityCache()
val latch: CountDownLatch = MPLatch(3)
val handler = Handler(Looper.getMainLooper())
handler.postDelayed({ Assert.fail("Process not complete") }, (10 * 1000).toLong())
val called = AndroidUtils.Mutable(false)
val identityRequest = IdentityApiRequest.withEmptyUser()
.email("[email protected]")
.customerId("TestUser777777")
.build()
// Login with First User
MParticle.getInstance()?.Identity()?.login(identityRequest)?.addSuccessListener {
latch.countDown()
}
MParticle.getInstance()?.Identity()?.logout()?.addSuccessListener {
latch.countDown()
}
// Login With same User
MParticle.getInstance()?.Identity()?.login(identityRequest)?.addSuccessListener {
val currentLoginRequestCount = mServer.Requests().login.size
Assert.assertEquals(2, currentLoginRequestCount)
called.value = true
latch.countDown()
}
latch.await()
Assert.assertTrue(called.value)
}

@Test
@Throws(Exception::class)
fun testLoginAndIdentitySameUser() {
Expand Down Expand Up @@ -118,6 +180,82 @@ class MParticleIdentityClientImplTest : BaseCleanStartedEachTest() {
Assert.assertTrue(called.value)
}

@Test
@Throws(Exception::class)
fun testTwoIdentitySameUser_WithModify() {
// clear existing catch
clearIdentityCache()
val latch: CountDownLatch = MPLatch(3)
val handler = Handler(Looper.getMainLooper())
handler.postDelayed({ Assert.fail("Process not complete") }, (10 * 1000).toLong())
val called = AndroidUtils.Mutable(false)
val identityRequest = IdentityApiRequest.withEmptyUser()
.email("[email protected]")
.customerId("TestUser777777")
.build()
val identityRequestModify = IdentityApiRequest.withEmptyUser()
.email("[email protected]")
.customerId("TestUser777777")
.build()

// Identity with First User
MParticle.getInstance()?.Identity()?.identify(identityRequest)?.addSuccessListener {
latch.countDown()
}
MParticle.getInstance()?.Identity()?.modify(identityRequestModify)?.addSuccessListener {
latch.countDown()
}
// Identity With same User
MParticle.getInstance()?.Identity()?.identify(identityRequest)?.addSuccessListener {
val currentIdentityRequestCount = mServer.Requests().identify.size
Assert.assertEquals(3, currentIdentityRequestCount)
called.value = true
latch.countDown()
}
latch.await()
Assert.assertTrue(called.value)
}

@Test
@Throws(Exception::class)
fun testLoginWithTwoSameUsers_WithTimeout() {
// clear existing catch
val mParticleIdentityClient = MParticleIdentityClientImpl(
mContext,
mConfigManager,
MParticle.OperatingSystem.ANDROID
)
clearIdentityCache()
val latch: CountDownLatch = MPLatch(2)
val handler = Handler(Looper.getMainLooper())
handler.postDelayed({ Assert.fail("Process not complete") }, (10 * 1000).toLong())
val called = AndroidUtils.Mutable(false)
val identityRequest = IdentityApiRequest.withEmptyUser()
.email("[email protected]")
.customerId("TestUser777777")
.build()
// Login with First User
Thread {
MParticle.getInstance()?.Identity()?.login(identityRequest)?.addSuccessListener {
latch.countDown()
}

val field: Field =
MParticleIdentityClientImpl::class.java.getDeclaredField("identityCacheTime")
field.isAccessible = true
field.set(mParticleIdentityClient, 0L)
// Login With same User
MParticle.getInstance()?.Identity()?.login(identityRequest)?.addSuccessListener {
val currentLoginRequestCount = mServer.Requests().login.size
Assert.assertEquals(2, currentLoginRequestCount)
called.value = true
latch.countDown()
}
latch.await()
Assert.assertTrue(called.value)
}.start()
}

@Test
@Throws(Exception::class)
fun testIdentifyMessage() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public class MParticleIdentityClientImpl extends MParticleBaseClientImpl impleme
public final String IDENTIFY_CALL = "identify";
final String IDENTITY_HEADER_TIMEOUT = "X-MP-Max-Age";
static Long maxAgeTimeForIdentityCache = 0L;
static Long identityCacheTime = 0L;
Long identityCacheTime = 0L;
HashMap<String, IdentityHttpResponse> identityCacheArray = new HashMap<>();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

identityCacheArray should be called identityCacheMap


public MParticleIdentityClientImpl(Context context, ConfigManager configManager, MParticle.OperatingSystem operatingSystem) {
Expand All @@ -87,7 +87,7 @@ public IdentityHttpResponse login(IdentityApiRequest request) throws JSONExcepti
if (existsResponse != null) {
return existsResponse;
}
Long maxAgeTime=0L;
Long maxAgeTime=86400L;
Mansi-mParticle marked this conversation as resolved.
Show resolved Hide resolved
Logger.verbose("Identity login request: " + jsonObject.toString());
MPConnection connection = getPostConnection(LOGIN_PATH, jsonObject.toString());
String url = connection.getURL().toString();
Expand Down Expand Up @@ -127,7 +127,7 @@ public IdentityHttpResponse identify(IdentityApiRequest request) throws JSONExce
return existsResponse;
}
JSONObject jsonObject = getStateJson(request);
Long maxAgeTime=0L;
Long maxAgeTime=86400L;
Logger.verbose("Identity identify request: \n" + jsonObject.toString());
MPConnection connection = getPostConnection(IDENTIFY_PATH, jsonObject.toString());
String url = connection.getURL().toString();
Expand Down Expand Up @@ -202,7 +202,7 @@ private IdentityHttpResponse checkIfExists(IdentityApiRequest request, String ca
identityCacheArray = mConfigManager.fetchIdentityCache();
}
if ((((System.currentTimeMillis() - identityCacheTime) / 1000) <= maxAgeTimeForIdentityCache) && identityCacheArray.containsKey(key)) {
return identityCacheArray.get(key);
return identityCacheArray.get(key);
} else {
return null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,8 @@ public void onRequest(Response response, MPConnectionTestImpl connection) {
IdentityRequest.IdentityRequestBody request = new IdentityRequest(connection).getBody();
response.responseCode = 200;
response.responseBody = getIdentityResponse(request.previousMpid != null && request.previousMpid != 0 ? request.previousMpid : ran.nextLong(), ran.nextBoolean());
response.setHeader("X-MP-Max-Age", "86400");

} catch (Exception ex) {
throw new RuntimeException(ex);
}
Expand Down
14 changes: 14 additions & 0 deletions testutils/src/main/java/com/mparticle/networking/Response.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package com.mparticle.networking;

import java.util.HashMap;
import java.util.Map;

class Response {

int responseCode = 200;
String responseBody = "";
long delay;
Map<String, String> headers = new HashMap<>();


Response() {
}
Expand All @@ -25,4 +30,13 @@ void setRequest(MPConnectionTestImpl connection) {
onRequestCallback.onRequest(this, connection);
}
}

void setHeader(String key, String value) {
headers.put(key, value);
}

String getHeader(String key) {
return headers.get(key);
}

}
Loading