Skip to content

Commit

Permalink
Release 3.6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
weiqiangliu committed Dec 23, 2022
1 parent b1df584 commit f33b124
Show file tree
Hide file tree
Showing 23 changed files with 340 additions and 7,474 deletions.
2 changes: 1 addition & 1 deletion SensorsAnalyticsSDK/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<groupId>com.sensorsdata.analytics.javasdk</groupId>
<name>SensorsAnalyticsSDK</name>
<artifactId>SensorsAnalyticsSDK</artifactId>
<version>3.5.2</version>
<version>3.6.0</version>
<description>The official Java SDK of Sensors Analytics</description>
<url>http://sensorsdata.cn</url>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
import static com.sensorsdata.analytics.javasdk.SensorsConst.BIND_ID_ACTION_TYPE;
import static com.sensorsdata.analytics.javasdk.SensorsConst.ITEM_DELETE_ACTION_TYPE;
import static com.sensorsdata.analytics.javasdk.SensorsConst.ITEM_SET_ACTION_TYPE;
import static com.sensorsdata.analytics.javasdk.SensorsConst.LIB;
import static com.sensorsdata.analytics.javasdk.SensorsConst.LIB_SYSTEM_ATTR;
import static com.sensorsdata.analytics.javasdk.SensorsConst.LIB_VERSION_SYSTEM_ATTR;
import static com.sensorsdata.analytics.javasdk.SensorsConst.PROFILE_APPEND_ACTION_TYPE;
import static com.sensorsdata.analytics.javasdk.SensorsConst.PROFILE_DELETE_ACTION_TYPE;
import static com.sensorsdata.analytics.javasdk.SensorsConst.PROFILE_INCREMENT_ACTION_TYPE;
import static com.sensorsdata.analytics.javasdk.SensorsConst.PROFILE_SET_ACTION_TYPE;
import static com.sensorsdata.analytics.javasdk.SensorsConst.PROFILE_SET_ONCE_ACTION_TYPE;
import static com.sensorsdata.analytics.javasdk.SensorsConst.PROFILE_UNSET_ACTION_TYPE;
import static com.sensorsdata.analytics.javasdk.SensorsConst.PROJECT_SYSTEM_ATTR;
import static com.sensorsdata.analytics.javasdk.SensorsConst.SDK_VERSION;
import static com.sensorsdata.analytics.javasdk.SensorsConst.SIGN_UP_SYSTEM_ATTR;
import static com.sensorsdata.analytics.javasdk.SensorsConst.TRACK_ACTION_TYPE;
import static com.sensorsdata.analytics.javasdk.SensorsConst.TRACK_SIGN_UP_ACTION_TYPE;
Expand Down Expand Up @@ -41,6 +45,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* Sensors Analytics SDK
Expand All @@ -54,7 +59,26 @@ public class SensorsAnalytics implements ISensorsAnalytics {
private static final String EVENT_NAME = "event name";
private static final String ORIGINAL_DISTINCT_ID = "Original Distinct Id";

private final Map<String, Object> superProperties = new ConcurrentHashMap<>();

void setSuperProperties(Map<String, Object> superProperties) {
for (Map.Entry<String, Object> entry : superProperties.entrySet()) {
if (SensorsAnalyticsUtil.KEY_PATTERN.matcher(entry.getKey()).matches() &&
!"$track_id".equals(entry.getKey())) {
this.superProperties.put(entry.getKey(), entry.getValue());
}
}
}

void clearSuperProper() {
this.superProperties.clear();
this.superProperties.put(LIB_SYSTEM_ATTR, LIB);
this.superProperties.put(LIB_VERSION_SYSTEM_ATTR, SDK_VERSION);
log.info("Call clearSuperProperties method.");
}

public SensorsAnalytics(final Consumer consumer) {
clearSuperProper();
worker = new SensorsAnalyticsWorker(consumer);
}

Expand All @@ -65,23 +89,23 @@ public void setEnableTimeFree(@NonNull boolean enableTimeFree) {

@Override
public void registerSuperProperties(@NonNull SuperPropertiesRecord propertiesRecord) {
worker.setSuperProperties(propertiesRecord.getPropertyMap());
setSuperProperties(propertiesRecord.getPropertyMap());
}

@Override
public void registerSuperProperties(@NonNull Map<String, Object> superPropertiesMap) {
worker.setSuperProperties(superPropertiesMap);
setSuperProperties(superPropertiesMap);
}

@Override
public void clearSuperProperties() {
worker.clearSuperProperties();
clearSuperProper();
}

@Override
public void track(@NonNull EventRecord eventRecord) throws InvalidArgumentException {
addEvent(eventRecord.getDistinctId(), eventRecord.getIsLoginId(), null, TRACK_ACTION_TYPE,
eventRecord.getEventName(), eventRecord.getPropertyMap());
eventRecord.getPropertyMap().putAll(putAllSuperPro(eventRecord.getPropertyMap(), superProperties));
worker.doAddData(new SensorsData(eventRecord, TRACK_ACTION_TYPE));
}

@Override
Expand Down Expand Up @@ -296,6 +320,10 @@ public void unbind(@NonNull String key, @NonNull String value) throws InvalidArg
@Override
public void trackById(@NonNull SensorsAnalyticsIdentity analyticsIdentity, @NonNull String eventName,
Map<String, Object> properties) throws InvalidArgumentException {
if (properties == null) {
properties = new HashMap<>();
}
properties.putAll(superProperties);
IDMEventRecord eventRecord = IDMEventRecord.starter()
.identityMap(analyticsIdentity.getIdentityMap())
.setEventName(eventName)
Expand Down Expand Up @@ -407,6 +435,7 @@ public void profileDeleteById(@NonNull String key, @NonNull String value) throws

@Override
public void trackById(@NonNull IDMEventRecord idmEventRecord) throws InvalidArgumentException {
idmEventRecord.getPropertyMap().putAll(putAllSuperPro(idmEventRecord.getPropertyMap(), superProperties));
worker.doAddData(new SensorsData(idmEventRecord));
}

Expand Down Expand Up @@ -457,11 +486,13 @@ public void profileUnsetById(@NonNull IDMUserRecord idmUserRecord) throws Invali

@Override
public void track(@NonNull UserEventSchema userEventSchema) throws InvalidArgumentException {
userEventSchema.getPropertyMap().putAll(putAllSuperPro(userEventSchema.getPropertyMap(), superProperties));
worker.doSchemaData(new SensorsSchemaData(userEventSchema, TRACK_ACTION_TYPE));
}

@Override
public void track(@NonNull ItemEventSchema itemEventSchema) throws InvalidArgumentException {
itemEventSchema.getProperties().putAll(putAllSuperPro(itemEventSchema.getProperties(), superProperties));
worker.doSchemaData(new SensorsSchemaData(itemEventSchema, TRACK_ACTION_TYPE));
}

Expand All @@ -473,6 +504,7 @@ public void bind(@NonNull IdentitySchema identitySchema) throws InvalidArgumentE
UserEventSchema userEventSchema = UserEventSchema.init()
.setEventName(BIND_ID)
.identityMap(identitySchema.getIdMap())
.addProperties(superProperties)
.start();
worker.doSchemaData(new SensorsSchemaData(userEventSchema, BIND_ID_ACTION_TYPE));
}
Expand All @@ -485,6 +517,7 @@ public void unbind(@NonNull IdentitySchema identitySchema) throws InvalidArgumen
UserEventSchema userEventSchema = UserEventSchema.init()
.setEventName(UNBIND_ID)
.identityMap(identitySchema.getIdMap())
.addProperties(superProperties)
.start();
worker.doSchemaData(new SensorsSchemaData(userEventSchema, UNBIND_ID_ACTION_TYPE));
}
Expand Down Expand Up @@ -598,7 +631,7 @@ private void addEvent(String distinctId, boolean isLoginId, String originDistinc
.setEventName(eventName)
.setDistinctId(distinctId)
.isLoginId(isLoginId)
.addProperties(properties)
.addProperties(putAllSuperPro(properties, superProperties))
.build();
SensorsData sensorsData = new SensorsData(eventRecord, actionType);
sensorsData.setOriginalId(originDistinctId);
Expand Down Expand Up @@ -629,6 +662,7 @@ private void addEventIdentity(Map<String, String> identityMap, String actionType
IDMEventRecord idmEventRecord = IDMEventRecord.starter()
.setEventName(eventName)
.identityMap(identityMap)
.addProperties(superProperties)
.build();
worker.doAddData(new SensorsData(idmEventRecord, actionType));
}
Expand All @@ -642,4 +676,16 @@ private void assertIdentityMap(String actionType, Map<String, String> identityMa
}
}

private Map<String, Object> putAllSuperPro(Map<String, Object> pro, Map<String, Object> superPro) {
if (pro == null) {
pro = new HashMap<>();
}
for (Map.Entry<String, Object> entry : superPro.entrySet()) {
if (!pro.containsKey(entry.getKey())) {
pro.put(entry.getKey(), entry.getValue());
}
}
return pro;
}

}
Original file line number Diff line number Diff line change
@@ -1,43 +1,24 @@
package com.sensorsdata.analytics.javasdk;

import static com.sensorsdata.analytics.javasdk.SensorsConst.APP_VERSION_SYSTEM_ATTR;
import static com.sensorsdata.analytics.javasdk.SensorsConst.BIND_ID_ACTION_TYPE;
import static com.sensorsdata.analytics.javasdk.SensorsConst.LIB;
import static com.sensorsdata.analytics.javasdk.SensorsConst.LIB_SYSTEM_ATTR;
import static com.sensorsdata.analytics.javasdk.SensorsConst.LIB_VERSION_SYSTEM_ATTR;
import static com.sensorsdata.analytics.javasdk.SensorsConst.LOGIN_SYSTEM_ATTR;
import static com.sensorsdata.analytics.javasdk.SensorsConst.PROJECT_SYSTEM_ATTR;
import static com.sensorsdata.analytics.javasdk.SensorsConst.SDK_VERSION;
import static com.sensorsdata.analytics.javasdk.SensorsConst.TIME_SYSTEM_ATTR;
import static com.sensorsdata.analytics.javasdk.SensorsConst.TOKEN_SYSTEM_ATTR;
import static com.sensorsdata.analytics.javasdk.SensorsConst.TRACK_ACTION_TYPE;
import static com.sensorsdata.analytics.javasdk.SensorsConst.TRACK_SIGN_UP_ACTION_TYPE;
import static com.sensorsdata.analytics.javasdk.SensorsConst.UNBIND_ID_ACTION_TYPE;

import com.sensorsdata.analytics.javasdk.bean.SensorsAnalyticsIdentity;
import com.sensorsdata.analytics.javasdk.consumer.Consumer;
import com.sensorsdata.analytics.javasdk.util.SensorsAnalyticsUtil;

import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
class SensorsAnalyticsWorker {

private final Consumer consumer;

private final Map<String, Object> superProperties = new ConcurrentHashMap<>();

private boolean enableTimeFree = false;
private boolean timeFree = false;

public SensorsAnalyticsWorker(Consumer consumer) {
this.consumer = consumer;
clearSuperProperties();
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
Expand All @@ -47,51 +28,13 @@ public void run() {
}));
}

void setEnableTimeFree(boolean enableTimeFree) {
log.info("Call setEnableTimeFree method with param:{}", enableTimeFree);
this.enableTimeFree = enableTimeFree;
}

void setSuperProperties(Map<String, Object> superProperties) {
this.superProperties.putAll(superProperties);
}

void clearSuperProperties() {
this.superProperties.clear();
this.superProperties.put(LIB_SYSTEM_ATTR, LIB);
this.superProperties.put(LIB_VERSION_SYSTEM_ATTR, SDK_VERSION);
log.info("Call clearSuperProperties method.");
}

void doAddEvent(String distinctId, boolean isLoginId, String originDistinctId, String actionType, String eventName,
Map<String, Object> properties) {
this.consumer.send(
generateEventMap(distinctId, isLoginId, originDistinctId, null, actionType, eventName, properties));
}



void doAddData(@NonNull SensorsData sensorsData) {
//enable history data import
if (enableTimeFree) {
sensorsData.getProperties().put("time_free", true);
}
//check properties
final Map<String, Object> properties = sensorsData.getProperties();
//check common properties contains $app_version
if (this.superProperties.containsKey(APP_VERSION_SYSTEM_ATTR)) {
sensorsData.getLib().put(APP_VERSION_SYSTEM_ATTR, (String) this.superProperties.get(APP_VERSION_SYSTEM_ATTR));
}
// 只有 track 和 track_signup 事件才需要设置公共属性
if (sensorsData.getType().startsWith(TRACK_ACTION_TYPE)) {
for (Map.Entry<String, Object> entry : superProperties.entrySet()) {
if (!properties.containsKey(entry.getKey())) {
properties.put(entry.getKey(), entry.getValue());
}
}
Map<String, Object> data = SensorsData.generateData(sensorsData);
if (timeFree && (TRACK_ACTION_TYPE.equals(sensorsData.getType()))
|| TRACK_SIGN_UP_ACTION_TYPE.equals(sensorsData.getType())) {
data.put("time_free", true);
}
//event or profile
this.consumer.send(SensorsData.generateData(sensorsData));
this.consumer.send(data);
}

void flush() {
Expand All @@ -102,104 +45,17 @@ void shutdown() {
this.consumer.close();
}

/**
* 非 IDM 模式下 identity 一定为 null
*
* @param distinctId 登录 ID
* @param isLoginId 是否登录ID
* @param originDistinctId 匿名ID
* @param identity ID-Mapping 身份标识
* @param actionType 行为类型
* @param eventName 事件名
* @param properties 属性
* @return Map<String, Object>
*/
private Map<String, Object> generateEventMap(String distinctId, Boolean isLoginId, String originDistinctId,
Map<String, String> identity, String actionType, String eventName, Map<String, Object> properties) {
Map<String, Object> eventMap = new HashMap<>();
eventMap.put("_track_id", SensorsAnalyticsUtil.getTrackId(properties, distinctId));
eventMap.put("type", actionType);
eventMap.put("lib", getLibProperties());
//开启历史数据导入
if (enableTimeFree) {
eventMap.put("time_free", true);
}
HashMap<String, Object> eventProperties = new HashMap<>();
//普通模式
if (identity == null) {
eventMap.put("distinct_id", distinctId);
if (isLoginId) {
eventProperties.put(LOGIN_SYSTEM_ATTR, true);
}
} else {// id-mapping 模式
eventMap.put("identities", identity);
if (distinctId != null) {
eventMap.put("distinct_id", distinctId);
eventProperties.put(LOGIN_SYSTEM_ATTR, false);
} else {
if (identity.containsKey(SensorsAnalyticsIdentity.LOGIN_ID)) {
eventProperties.put(LOGIN_SYSTEM_ATTR, true);
eventMap.put("distinct_id", identity.get(SensorsAnalyticsIdentity.LOGIN_ID));
} else {
eventProperties.put(LOGIN_SYSTEM_ATTR, false);
String firstKey = identity.keySet().iterator().next();
eventMap.put("distinct_id", String.format("%s+%s", firstKey, identity.get(firstKey)));
}
}
}
//检查自定义属性
if (properties != null && !properties.isEmpty()) {
for (Map.Entry<String, Object> entry : properties.entrySet()) {
switch (entry.getKey()) {
case TIME_SYSTEM_ATTR:
eventMap.put("time", ((Date) entry.getValue()).getTime());
break;
case PROJECT_SYSTEM_ATTR:
eventMap.put("project", entry.getValue());
break;
case TOKEN_SYSTEM_ATTR:
eventMap.put("token", entry.getValue());
break;
default:
eventProperties.put(entry.getKey(), entry.getValue());
break;
}
}
}
//操作类型
if (actionType != null) {
switch (actionType) {
case TRACK_SIGN_UP_ACTION_TYPE:
eventMap.put("original_id", originDistinctId);
case TRACK_ACTION_TYPE:
case BIND_ID_ACTION_TYPE:
case UNBIND_ID_ACTION_TYPE:
eventMap.put("event", eventName);
eventProperties.putAll(superProperties);
break;
}
}
//最终校验是否有 time 属性
if (!eventMap.containsKey("time")) {
eventMap.put("time", System.currentTimeMillis());
}
eventMap.put("properties", eventProperties);
return eventMap;
}

private Map<String, String> getLibProperties() {
Map<String, String> libInfo = SensorsAnalyticsUtil.generateLibInfo();
if (this.superProperties.containsKey(APP_VERSION_SYSTEM_ATTR)) {
libInfo.put(APP_VERSION_SYSTEM_ATTR, (String) this.superProperties.get(APP_VERSION_SYSTEM_ATTR));
public void doSchemaData(@NonNull SensorsSchemaData schemaData) {
Map<String, Object> sensorsData = schemaData.generateData();
if (timeFree && (TRACK_ACTION_TYPE.equals(schemaData.getType()))
|| TRACK_SIGN_UP_ACTION_TYPE.equals(schemaData.getType())) {
sensorsData.put("time_free", true);
}
return libInfo;
this.consumer.send(sensorsData);
}

public void doSchemaData(@NonNull SensorsSchemaData schemaData) {
// 开启历史数据导入,兼容之前接口逻辑
if (enableTimeFree && schemaData.isEventSchemaData()) {
schemaData.getProperties().put("time_free", true);
}
this.consumer.send(schemaData.generateData());
public void setEnableTimeFree(boolean enableTimeFree) {
this.timeFree = enableTimeFree;
}
}
Loading

0 comments on commit f33b124

Please sign in to comment.