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: delete custom user attributes from subsequent events #48

Merged
merged 1 commit into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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 @@ -35,7 +35,8 @@ public class AnalyticsClient {
private static final Log LOG = LogFactory.getLog(AnalyticsClient.class);
private final ClickstreamContext context;
private final Map<String, Object> globalAttributes = new ConcurrentHashMap<>();
private JSONObject userAttributes;
private JSONObject simpleUserAttributes;
private JSONObject allUserAttributes;
private String userId;
private String userUniqueId;
private final EventRecorder eventRecorder;
Expand All @@ -51,7 +52,8 @@ public AnalyticsClient(@NonNull final ClickstreamContext context) {
eventRecorder = EventRecorder.newInstance(context);
userId = PreferencesUtil.getCurrentUserId(context.getSystem().getPreferences());
userUniqueId = PreferencesUtil.getCurrentUserUniqueId(context.getSystem().getPreferences());
userAttributes = PreferencesUtil.getUserAttribute(context.getSystem().getPreferences());
allUserAttributes = PreferencesUtil.getUserAttribute(context.getSystem().getPreferences());
simpleUserAttributes = getSimpleUserAttribute();
}

/**
Expand Down Expand Up @@ -99,7 +101,7 @@ public void deleteGlobalAttribute(String name) {
*/
public void addUserAttribute(String name, Object value) {
if (value != null) {
Event.EventError error = Event.checkUserAttribute(userAttributes.length(), name, value);
Event.EventError error = Event.checkUserAttribute(allUserAttributes.length(), name, value);
if (error != null) {
final AnalyticsEvent event = createEvent(Event.PresetEvent.CLICKSTREAM_ERROR);
event.addAttribute(Event.ReservedAttribute.ERROR_CODE, error.getErrorCode());
Expand All @@ -112,12 +114,12 @@ public void addUserAttribute(String name, Object value) {
JSONObject attribute = new JSONObject();
attribute.put("value", value);
attribute.put("set_timestamp", timeStamp);
userAttributes.put(name, attribute);
allUserAttributes.put(name, attribute);
} catch (JSONException exception) {
LOG.error("format user attribute, error message:" + exception.getMessage());
}
} else {
userAttributes.remove(name);
allUserAttributes.remove(name);
}
}

Expand All @@ -131,7 +133,7 @@ public void updateUserId(String userId) {
this.userId = userId;
PreferencesUtil.setCurrentUserId(context.getSystem().getPreferences(), userId);
if (!StringUtil.isNullOrEmpty(userId)) {
userAttributes = new JSONObject();
allUserAttributes = new JSONObject();
JSONObject userInfo = PreferencesUtil.getNewUserInfo(context.getSystem().getPreferences(), userId);
try {
userUniqueId = userInfo.getString("user_unique_id");
Expand All @@ -146,14 +148,15 @@ public void updateUserId(String userId) {
newUserId = null;
}
addUserAttribute(Event.ReservedAttribute.USER_ID, newUserId);
simpleUserAttributes = getSimpleUserAttribute();
}
}

/**
* update user attribute after user attribute changed.
*/
public void updateUserAttribute() {
PreferencesUtil.updateUserAttribute(context.getSystem().getPreferences(), userAttributes);
PreferencesUtil.updateUserAttribute(context.getSystem().getPreferences(), allUserAttributes);
}

/**
Expand Down Expand Up @@ -181,7 +184,10 @@ public AnalyticsEvent createEvent(String eventType) {

private AnalyticsEvent createAnalyticsEvent(String eventType) {
long timestamp = System.currentTimeMillis();
AnalyticsEvent event = new AnalyticsEvent(eventType, globalAttributes, userAttributes, timestamp, userUniqueId);
JSONObject eventUserAttribute =
eventType.equals(Event.PresetEvent.PROFILE_SET) ? allUserAttributes : simpleUserAttributes;
AnalyticsEvent event =
new AnalyticsEvent(eventType, globalAttributes, eventUserAttribute, timestamp, userUniqueId);
event.setDeviceId(this.context.getDeviceId());
event.setAppId(context.getClickstreamConfiguration().getAppId());
event.setSdkInfo(context.getSDKInfo());
Expand Down Expand Up @@ -235,4 +241,24 @@ public void setSession(Session session) {
public ClickstreamConfiguration getClickstreamConfiguration() {
return this.context.getClickstreamConfiguration();
}

/**
* get simple user attribute from allUserAttributes.
*
* @return userAttribute
*/
private JSONObject getSimpleUserAttribute() {
JSONObject userAttribute = new JSONObject();
try {
userAttribute.put(Event.ReservedAttribute.USER_FIRST_TOUCH_TIMESTAMP,
allUserAttributes.getString(Event.ReservedAttribute.USER_FIRST_TOUCH_TIMESTAMP));
if (allUserAttributes.has(Event.ReservedAttribute.USER_ID)) {
userAttribute.put(Event.ReservedAttribute.USER_ID,
allUserAttributes.getString(Event.ReservedAttribute.USER_ID));
}
} catch (final JSONException jsonException) {
LOG.error("Could not create Json object of simpleUserAttribute. error: " + jsonException.getMessage());
}
return userAttribute;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public class AnalyticsClientTest {

private AnalyticsClient analyticsClient;
private Map<String, Object> globalAttributes;
private JSONObject userAttributes;
private JSONObject allUserAttributes;
private String exceedLengthName = "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij";
private final String invalidName = "1_goods_expose";
private String exceedLengthValue = "";
Expand Down Expand Up @@ -78,7 +78,7 @@ public void setup() throws Exception {
analyticsClient = clickstreamManager.getAnalyticsClient();

globalAttributes = (Map<String, Object>) ReflectUtil.getFiled(analyticsClient, "globalAttributes");
userAttributes = (JSONObject) ReflectUtil.getFiled(analyticsClient, "userAttributes");
allUserAttributes = (JSONObject) ReflectUtil.getFiled(analyticsClient, "allUserAttributes");

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 21; i++) {
Expand Down Expand Up @@ -201,10 +201,10 @@ public void testAddGlobalAttributeSameNameMultiTimes() {
@Test
public void testAddUserAttributeWhenSuccess() throws JSONException {
analyticsClient.addUserAttribute("_user_age", 18);
Assert.assertTrue(userAttributes.has("_user_age"));
Assert.assertEquals(18, ((JSONObject) userAttributes.get("_user_age")).get("value"));
Assert.assertTrue(allUserAttributes.has("_user_age"));
Assert.assertEquals(18, ((JSONObject) allUserAttributes.get("_user_age")).get("value"));
Assert.assertTrue(System.currentTimeMillis() -
(Long) (((JSONObject) userAttributes.get("_user_age")).get("set_timestamp")) < 1000);
(Long) (((JSONObject) allUserAttributes.get("_user_age")).get("set_timestamp")) < 1000);
}

/**
Expand Down Expand Up @@ -266,8 +266,8 @@ public void testAddUserAttributeSameNameMultiTimes() throws JSONException {
mockAnalyticsClient.addUserAttribute("name", "value" + i);
}
verify(mockAnalyticsClient, never()).createEvent(anyString());
Assert.assertEquals(2, userAttributes.length());
Assert.assertEquals("value100", ((JSONObject) userAttributes.get("name")).get("value"));
Assert.assertEquals(2, allUserAttributes.length());
Assert.assertEquals("value100", ((JSONObject) allUserAttributes.get("name")).get("value"));
}

/**
Expand All @@ -287,9 +287,9 @@ public void testAddGlobalAttributeForNullValue() {
@Test
public void testAddUserAttributeForNullValue() {
analyticsClient.addUserAttribute("UserAge", 20);
Assert.assertTrue(userAttributes.has("UserAge"));
Assert.assertTrue(allUserAttributes.has("UserAge"));
analyticsClient.addUserAttribute("UserAge", null);
Assert.assertFalse(userAttributes.has("UserAge"));
Assert.assertFalse(allUserAttributes.has("UserAge"));
}

/**
Expand All @@ -316,10 +316,10 @@ public void testAddUserAttributeForNullValueWhenReachedMaxLength() {
for (int i = 0; i < 100; i++) {
analyticsClient.addUserAttribute("name" + i, "value" + i);
}
Assert.assertTrue(userAttributes.has("name0"));
Assert.assertTrue(allUserAttributes.has("name0"));
analyticsClient.addUserAttribute("name0", null);
Assert.assertFalse(userAttributes.has("name0"));
Assert.assertEquals(99, userAttributes.length());
Assert.assertFalse(allUserAttributes.has("name0"));
Assert.assertEquals(99, allUserAttributes.length());
}

/**
Expand All @@ -343,7 +343,7 @@ public void deleteNonExistingUserAttribute() {
analyticsClient.addUserAttribute("name" + i, "value" + i);
}
analyticsClient.addUserAttribute("name1000", null);
Assert.assertEquals(100, userAttributes.length());
Assert.assertEquals(100, allUserAttributes.length());
}

/**
Expand All @@ -365,7 +365,7 @@ public void testUserAttributeForStorage() throws Exception {
ClickstreamManagerFactory.create(context, AWSClickstreamPluginConfiguration
.builder().withAppId("demo-app").withEndpoint("http://example.com/collect").build());
JSONObject userAttributesFromStorage =
(JSONObject) ReflectUtil.getFiled(clickstreamManager.getAnalyticsClient(), "userAttributes");
(JSONObject) ReflectUtil.getFiled(clickstreamManager.getAnalyticsClient(), "allUserAttributes");
Assert.assertEquals(6, userAttributesFromStorage.length());
Assert.assertEquals("carl", ((JSONObject) userAttributesFromStorage.get("user_name")).getString("value"));
Assert.assertEquals("10837409", ((JSONObject) userAttributesFromStorage.get("_user_id")).getString("value"));
Expand All @@ -390,8 +390,8 @@ public void testInitialValueInAnalyticsClient() throws Exception {
Assert.assertEquals("", userId);
Assert.assertNotNull(userUniqueId);

userAttributes = (JSONObject) ReflectUtil.getFiled(analyticsClient, "userAttributes");
Assert.assertTrue(userAttributes.has(Event.ReservedAttribute.USER_FIRST_TOUCH_TIMESTAMP));
allUserAttributes = (JSONObject) ReflectUtil.getFiled(analyticsClient, "allUserAttributes");
Assert.assertTrue(allUserAttributes.has(Event.ReservedAttribute.USER_FIRST_TOUCH_TIMESTAMP));
}

/**
Expand All @@ -406,8 +406,8 @@ public void testUpdateSameUserIdTwice() throws Exception {
analyticsClient.updateUserId(userIdForA);
analyticsClient.addUserAttribute("user_age", 12);
analyticsClient.updateUserId(userIdForA);
userAttributes = (JSONObject) ReflectUtil.getFiled(analyticsClient, "userAttributes");
Assert.assertTrue(userAttributes.has("user_age"));
allUserAttributes = (JSONObject) ReflectUtil.getFiled(analyticsClient, "allUserAttributes");
Assert.assertTrue(allUserAttributes.has("user_age"));
Assert.assertEquals(userUniqueId, ReflectUtil.getFiled(analyticsClient, "userUniqueId"));
}

Expand All @@ -424,8 +424,8 @@ public void testUpdateDifferentUserId() throws Exception {
analyticsClient.updateUserId(userIdForA);
analyticsClient.addUserAttribute("user_age", 12);
analyticsClient.updateUserId(userIdForB);
userAttributes = (JSONObject) ReflectUtil.getFiled(analyticsClient, "userAttributes");
Assert.assertFalse(userAttributes.has("user_age"));
allUserAttributes = (JSONObject) ReflectUtil.getFiled(analyticsClient, "allUserAttributes");
Assert.assertFalse(allUserAttributes.has("user_age"));
Assert.assertNotEquals(userUniqueId, ReflectUtil.getFiled(analyticsClient, "userUniqueId"));
}

Expand All @@ -448,6 +448,26 @@ public void testChangeToOriginUserId() throws Exception {
Assert.assertEquals(userUniqueIdForB, ReflectUtil.getFiled(analyticsClient, "userUniqueId"));
}


/**
* test create event without custom user attributes.
*
* @throws JSONException the json exception
*/
@Test
public void testCreateEventWithoutCustomUserAttributes() throws JSONException {
analyticsClient.updateUserId("123");
analyticsClient.addUserAttribute("userName", "carl");
analyticsClient.addUserAttribute("userAge", 22);

AnalyticsEvent testEvent = analyticsClient.createEvent("testEvent");
JSONObject user = testEvent.toJSONObject().getJSONObject("user");
Assert.assertTrue(user.has(Event.ReservedAttribute.USER_ID));
Assert.assertTrue(user.has(Event.ReservedAttribute.USER_FIRST_TOUCH_TIMESTAMP));
Assert.assertFalse(user.has("userName"));
Assert.assertFalse(user.has("userAge"));
}

/**
* tearDown.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,21 +300,14 @@ public void testAddUserAttributes() throws Exception {
.add("_user_name", "carl")
.build();
ClickstreamAnalytics.addUserAttributes(clickstreamUserAttribute);
ClickstreamEvent event = ClickstreamEvent.builder()
.name("PasswordReset")
.add("Message", "SMS")
.add("Successful", true)
.add("ProcessDuration", 792)
.add("Number", 20.1)
.build();
ClickstreamAnalytics.recordEvent(event);
assertEquals(3, dbUtil.getTotalNumber());
assertEquals(2, dbUtil.getTotalNumber());

Cursor cursor = dbUtil.queryAllEvents();
cursor.moveToLast();
String eventString = cursor.getString(2);
JSONObject jsonObject = new JSONObject(eventString);
JSONObject attribute = jsonObject.getJSONObject("attributes");
String eventType = jsonObject.getString("event_type");
Assert.assertEquals(Event.PresetEvent.PROFILE_SET, eventType);
JSONObject user = jsonObject.getJSONObject("user");
Assert.assertEquals("13212", ((JSONObject) user.get(Event.ReservedAttribute.USER_ID)).getString("value"));
Assert.assertEquals(21, ((JSONObject) user.get("_user_age")).getInt("value"));
Expand All @@ -323,9 +316,6 @@ public void testAddUserAttributes() throws Exception {
Assert.assertTrue(((JSONObject) user.get("_user_name")).has("set_timestamp"));
Assert.assertEquals(timestamp, ((JSONObject) user.get("timestamp")).getLong("value"));

Assert.assertTrue(attribute.getBoolean("Successful"));
Assert.assertEquals("SMS", attribute.getString("Message"));

ClickstreamAnalytics.flushEvents();
Thread.sleep(1000);
assertEquals(0, dbUtil.getTotalNumber());
Expand All @@ -347,16 +337,8 @@ public void testModifyUserId() throws Exception {
.build();
ClickstreamAnalytics.setUserId("13212");
ClickstreamAnalytics.addUserAttributes(clickstreamUserAttribute);
ClickstreamEvent event = ClickstreamEvent.builder()
.name("PasswordReset")
.add("Message", "SMS")
.add("Successful", true)
.add("ProcessDuration", 792)
.add("Number", 20.1)
.build();
ClickstreamAnalytics.setUserId("12345");
ClickstreamAnalytics.recordEvent(event);
assertEquals(4, dbUtil.getTotalNumber());
assertEquals(3, dbUtil.getTotalNumber());

Cursor cursor = dbUtil.queryAllEvents();
cursor.moveToLast();
Expand Down Expand Up @@ -405,8 +387,8 @@ public void testSetUserIdNull() throws Exception {
JSONObject jsonObject = new JSONObject(eventString);
JSONObject user = jsonObject.getJSONObject("user");
Assert.assertFalse(user.has(Event.ReservedAttribute.USER_ID));
Assert.assertEquals(21, ((JSONObject) user.get("_user_age")).get("value"));
Assert.assertEquals("carl", ((JSONObject) user.get("_user_name")).get("value"));
Assert.assertFalse(user.has("_user_age"));
Assert.assertFalse(user.has("_user_name"));

ClickstreamAnalytics.flushEvents();
Thread.sleep(1000);
Expand Down Expand Up @@ -838,7 +820,8 @@ public void tearDown() throws Exception {
ClickstreamAnalytics.getClickStreamConfiguration().withCustomDns(null);
Map<String, Object> globalAttribute =
(Map<String, Object>) ReflectUtil.getFiled(analyticsClient, "globalAttributes");
ReflectUtil.modifyFiled(analyticsClient, "userAttributes", new JSONObject());
ReflectUtil.modifyFiled(analyticsClient, "simpleUserAttributes", new JSONObject());
ReflectUtil.modifyFiled(analyticsClient, "allUserAttributes", new JSONObject());
globalAttribute.clear();
}

Expand Down
Loading