Skip to content

feat(track): Introducing easier event tracking #250

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

Merged
merged 7 commits into from
Jan 15, 2019
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
35 changes: 6 additions & 29 deletions core-api/src/main/java/com/optimizely/ab/Optimizely.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import com.optimizely.ab.bucketing.DecisionService;
import com.optimizely.ab.bucketing.FeatureDecision;
import com.optimizely.ab.bucketing.UserProfileService;
import com.optimizely.ab.config.Attribute;
import com.optimizely.ab.config.EventType;
import com.optimizely.ab.config.Experiment;
import com.optimizely.ab.config.FeatureFlag;
Expand Down Expand Up @@ -309,36 +308,14 @@ public void track(@Nonnull String eventName,
logger.warn("Event tags is null when non-null was expected. Defaulting to an empty event tags map.");
}

List<Experiment> experimentsForEvent = projectConfig.getExperimentsForEventKey(eventName);
Map<Experiment, Variation> experimentVariationMap = new HashMap<Experiment, Variation>(experimentsForEvent.size());
for (Experiment experiment : experimentsForEvent) {
if (experiment.isRunning()) {
Variation variation = decisionService.getVariation(experiment, userId, copiedAttributes);
if (variation != null) {
experimentVariationMap.put(experiment, variation);
}
} else {
logger.info(
"Not tracking event \"{}\" for experiment \"{}\" because experiment has status \"Launched\".",
eventType.getKey(), experiment.getKey());
}
}

// create the conversion event request parameters, then dispatch
LogEvent conversionEvent = eventFactory.createConversionEvent(
projectConfig,
experimentVariationMap,
userId,
eventType.getId(),
eventType.getKey(),
copiedAttributes,
eventTags);

if (conversionEvent == null) {
logger.info("There are no valid experiments for event \"{}\" to track.", eventName);
logger.info("Not tracking event \"{}\" for user \"{}\".", eventName, userId);
return;
}
projectConfig,
userId,
eventType.getId(),
eventType.getKey(),
copiedAttributes,
eventTags);

logger.info("Tracking event \"{}\" for user \"{}\".", eventName, userId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,29 +104,12 @@ public LogEvent createImpressionEvent(@Nonnull ProjectConfig projectConfig,
}

public LogEvent createConversionEvent(@Nonnull ProjectConfig projectConfig,
@Nonnull Map<Experiment, Variation> experimentVariationMap,
Copy link
Contributor

@loganlinn loganlinn Jan 2, 2019

Choose a reason for hiding this comment

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

Not sure if we want to avoid breaking API changes in this PR, but if we do, we may want to overload this method rather than removing argument since this is technically public even though we probably don't encourage direct.

Edit: disregard. I was going off of this method+class being public, but it lives in internal package, which is good-enough warning of being a non-stable API in my opinion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍

@Nonnull String userId,
@Nonnull String eventId, // Why is this not used?
@Nonnull String eventName,
@Nonnull Map<String, ?> attributes,
@Nonnull Map<String, ?> eventTags) {

if (experimentVariationMap.isEmpty()) {
return null;
}

ArrayList<Decision> decisions = new ArrayList<Decision>(experimentVariationMap.size());
for (Map.Entry<Experiment, Variation> entry : experimentVariationMap.entrySet()) {
Decision decision = new Decision.Builder()
.setCampaignId(entry.getKey().getLayerId())
.setExperimentId(entry.getKey().getId())
.setVariationId(entry.getValue().getId())
.setIsCampaignHoldback(false)
.build();

decisions.add(decision);
}

EventType eventType = projectConfig.getEventNameMapping().get(eventName);

Event conversionEvent = new Event.Builder()
Expand All @@ -141,9 +124,8 @@ public LogEvent createConversionEvent(@Nonnull ProjectConfig projectConfig,
.build();

Snapshot snapshot = new Snapshot.Builder()
.setDecisions(decisions)
.setEvents(Collections.singletonList((conversionEvent)))
.build();
.setEvents(Collections.singletonList(conversionEvent))
.build();

Visitor visitor = new Visitor.Builder()
.setVisitorId(userId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public String getClientEngineValue() {
@JsonProperty("account_id")
String accountId;
List<Visitor> visitors;
@JsonProperty("enrich_decisions")
Boolean enrichDecisions;
@JsonProperty("anonymize_ip")
Boolean anonymizeIp;
@JsonProperty("client_name")
Expand All @@ -61,6 +63,7 @@ public EventBatch() {
private EventBatch(String clientName, String clientVersion, String accountId, List<Visitor> visitors, Boolean anonymizeIp, String projectId, String revision) {
this.accountId = accountId;
this.visitors = visitors;
this.enrichDecisions = true;
this.anonymizeIp = anonymizeIp;
this.clientName = clientName;
this.clientVersion = clientVersion;
Expand All @@ -84,6 +87,12 @@ public void setVisitors(List<Visitor> visitors) {
this.visitors = visitors;
}

public Boolean getEnrichDecisions() { return enrichDecisions; }

public void setEnrichDecisions(Boolean enrichDecisions) {
this.enrichDecisions = enrichDecisions;
}

public Boolean getAnonymizeIp() {
return anonymizeIp;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,11 @@ public boolean equals(Object o) {
Snapshot snapshot = (Snapshot) o;

if (activationTimestamp != null ?
!activationTimestamp.equals(snapshot.activationTimestamp) :
snapshot.activationTimestamp != null) return false;
if (!decisions.equals(snapshot.decisions)) return false;
!activationTimestamp.equals(snapshot.activationTimestamp) :
snapshot.activationTimestamp != null) return false;
if (decisions != null ?
!decisions.equals(snapshot.decisions) :
snapshot.decisions != null) return false;
return events.equals(snapshot.events);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ private JSONObject serializeEventBatch(EventBatch eventBatch) {
JSONObject jsonObject = new JSONObject();

jsonObject.put("account_id", eventBatch.getAccountId());
jsonObject.put("enrich_decisions", eventBatch.getEnrichDecisions());
jsonObject.put("visitors", serializeVisitors(eventBatch.getVisitors()));
if (eventBatch.getAnonymizeIp() != null) jsonObject.put("anonymize_ip", eventBatch.getAnonymizeIp());
if (eventBatch.getClientName() != null) jsonObject.put("client_name", eventBatch.getClientName());
Expand All @@ -50,7 +51,6 @@ private JSONObject serializeEventBatch(EventBatch eventBatch) {
if (eventBatch.getRevision() != null) jsonObject.put("revision", eventBatch.getRevision());

return jsonObject;

}

private JSONArray serializeVisitors(List<Visitor> visitors) {
Expand Down Expand Up @@ -90,7 +90,7 @@ private JSONArray serializeSnapshots(List<Snapshot> snapshots) {
private JSONObject serializeSnapshot(Snapshot snapshot) {
JSONObject jsonObject = new JSONObject();

jsonObject.put("decisions", serializeDecisions(snapshot.getDecisions()));
if (snapshot.getDecisions() != null) jsonObject.put("decisions", serializeDecisions(snapshot.getDecisions()));
jsonObject.put("events", serializeEvents(snapshot.getEvents()));

return jsonObject;
Expand Down
Loading