Skip to content

Commit 4ddf3c1

Browse files
Feature/v1/event end point (#164)
* initial implementation of new v3 event endpoint and unit tests * fix all the event builder V3 tests * cleanup lint errors * refactor, remove V2 only use V3. All unit tests passing * refactor to remove V3 reference and add license comments at the top * add license at top of file. * updated from Mike's comments. All headers for new files say 2018. * update license date * update to use snake case for event sending
1 parent 2728c67 commit 4ddf3c1

31 files changed

+1209
-1517
lines changed

core-api/src/main/java/com/optimizely/ab/Optimizely.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@
3737
import com.optimizely.ab.event.LogEvent;
3838
import com.optimizely.ab.event.internal.BuildVersionInfo;
3939
import com.optimizely.ab.event.internal.EventBuilder;
40-
import com.optimizely.ab.event.internal.EventBuilderV2;
41-
import com.optimizely.ab.event.internal.payload.Event.ClientEngine;
40+
import com.optimizely.ab.event.internal.payload.EventBatch.ClientEngine;
4241
import com.optimizely.ab.internal.EventTagUtils;
4342
import com.optimizely.ab.notification.NotificationBroadcaster;
4443
import com.optimizely.ab.notification.NotificationCenter;
@@ -948,7 +947,7 @@ public Optimizely build() throws ConfigParseException {
948947

949948

950949
if (eventBuilder == null) {
951-
eventBuilder = new EventBuilderV2(clientEngine, clientVersion);
950+
eventBuilder = new EventBuilder(clientEngine, clientVersion);
952951
}
953952

954953
if (errorHandler == null) {

core-api/src/main/java/com/optimizely/ab/event/internal/EventBuilder.java

+102-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
*
3-
* Copyright 2016-2017, Optimizely and contributors
3+
* Copyright 2016-2018, Optimizely and contributors
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -16,27 +16,122 @@
1616
*/
1717
package com.optimizely.ab.event.internal;
1818

19+
import com.optimizely.ab.annotations.VisibleForTesting;
20+
import com.optimizely.ab.bucketing.DecisionService;
21+
import com.optimizely.ab.config.EventType;
1922
import com.optimizely.ab.config.Experiment;
2023
import com.optimizely.ab.config.ProjectConfig;
2124
import com.optimizely.ab.config.Variation;
2225
import com.optimizely.ab.event.LogEvent;
23-
26+
import com.optimizely.ab.event.internal.payload.Attribute;
27+
import com.optimizely.ab.event.internal.payload.Decision;
28+
import com.optimizely.ab.event.internal.payload.EventBatch;
29+
import com.optimizely.ab.event.internal.payload.Event;
30+
import com.optimizely.ab.event.internal.payload.Snapshot;
31+
import com.optimizely.ab.event.internal.payload.Visitor;
32+
import com.optimizely.ab.event.internal.serializer.DefaultJsonSerializer;
33+
import com.optimizely.ab.event.internal.serializer.Serializer;
34+
import com.optimizely.ab.internal.EventTagUtils;
35+
import org.slf4j.Logger;
36+
import org.slf4j.LoggerFactory;
2437
import javax.annotation.Nonnull;
38+
import java.util.ArrayList;
39+
import java.util.Arrays;
40+
import java.util.Collections;
41+
import java.util.List;
2542
import java.util.Map;
43+
import java.util.UUID;
44+
45+
public class EventBuilder {
46+
private static final Logger logger = LoggerFactory.getLogger(EventBuilder.class);
47+
static final String ATTRIBUTE_KEY_FOR_BUCKETING_ATTRIBUTE = "optimizely_bucketing_id";
48+
static final String EVENT_ENDPOINT = "https://logx.optimizely.com/v1/events";
49+
static final String ACTIVATE_EVENT_KEY = "campaign_activated";
50+
51+
private Serializer serializer;
52+
@VisibleForTesting
53+
public final String clientVersion;
54+
@VisibleForTesting
55+
public final EventBatch.ClientEngine clientEngine;
56+
57+
public EventBuilder() {
58+
this(EventBatch.ClientEngine.JAVA_SDK, BuildVersionInfo.VERSION);
59+
}
60+
61+
public EventBuilder(EventBatch.ClientEngine clientEngine, String clientVersion) {
62+
this.clientEngine = clientEngine;
63+
this.clientVersion = clientVersion;
64+
this.serializer = DefaultJsonSerializer.getInstance();
65+
}
2666

27-
public abstract class EventBuilder {
2867

29-
public abstract LogEvent createImpressionEvent(@Nonnull ProjectConfig projectConfig,
68+
public LogEvent createImpressionEvent(@Nonnull ProjectConfig projectConfig,
3069
@Nonnull Experiment activatedExperiment,
3170
@Nonnull Variation variation,
3271
@Nonnull String userId,
33-
@Nonnull Map<String, String> attributes);
72+
@Nonnull Map<String, String> attributes) {
3473

35-
public abstract LogEvent createConversionEvent(@Nonnull ProjectConfig projectConfig,
74+
Decision decision = new Decision(activatedExperiment.getLayerId(), activatedExperiment.getId(),
75+
variation.getId(), false);
76+
Event impressionEvent = new Event(System.currentTimeMillis(),UUID.randomUUID().toString(), activatedExperiment.getLayerId(),
77+
ACTIVATE_EVENT_KEY, null, null, null, ACTIVATE_EVENT_KEY, null);
78+
Snapshot snapshot = new Snapshot(Arrays.asList(decision), Arrays.asList(impressionEvent));
79+
80+
Visitor visitor = new Visitor(userId, null, buildAttributeList(projectConfig, attributes), Arrays.asList(snapshot));
81+
List<Visitor> visitors = Arrays.asList(visitor);
82+
EventBatch eventBatch = new EventBatch(clientEngine.getClientEngineValue(), clientVersion, projectConfig.getAccountId(), visitors, projectConfig.getAnonymizeIP(), projectConfig.getProjectId(), projectConfig.getRevision());
83+
String payload = this.serializer.serialize(eventBatch);
84+
return new LogEvent(LogEvent.RequestMethod.POST, EVENT_ENDPOINT, Collections.<String, String>emptyMap(), payload);
85+
}
86+
87+
public LogEvent createConversionEvent(@Nonnull ProjectConfig projectConfig,
3688
@Nonnull Map<Experiment, Variation> experimentVariationMap,
3789
@Nonnull String userId,
3890
@Nonnull String eventId,
3991
@Nonnull String eventName,
4092
@Nonnull Map<String, String> attributes,
41-
@Nonnull Map<String, ?> eventTags);
93+
@Nonnull Map<String, ?> eventTags) {
94+
95+
if (experimentVariationMap.isEmpty()) {
96+
return null;
97+
}
98+
99+
ArrayList<Decision> decisions = new ArrayList<Decision>();
100+
for (Map.Entry<Experiment, Variation> entry : experimentVariationMap.entrySet()) {
101+
Decision decision = new Decision(entry.getKey().getLayerId(), entry.getKey().getId(), entry.getValue().getId(), false);
102+
decisions.add(decision);
103+
}
104+
105+
EventType eventType = projectConfig.getEventNameMapping().get(eventName);
106+
107+
Event conversionEvent = new Event(System.currentTimeMillis(),UUID.randomUUID().toString(), eventType.getId(),
108+
eventType.getKey(), null, EventTagUtils.getRevenueValue(eventTags), eventTags, eventType.getKey(), EventTagUtils.getNumericValue(eventTags));
109+
Snapshot snapshot = new Snapshot(decisions, Arrays.asList(conversionEvent));
110+
111+
Visitor visitor = new Visitor(userId, null, buildAttributeList(projectConfig, attributes), Arrays.asList(snapshot));
112+
List<Visitor> visitors = Arrays.asList(visitor);
113+
EventBatch eventBatch = new EventBatch(clientEngine.getClientEngineValue(), clientVersion, projectConfig.getAccountId(), visitors, projectConfig.getAnonymizeIP(), projectConfig.getProjectId(), projectConfig.getRevision());
114+
String payload = this.serializer.serialize(eventBatch);
115+
return new LogEvent(LogEvent.RequestMethod.POST, EVENT_ENDPOINT, Collections.<String, String>emptyMap(), payload);
116+
}
117+
118+
private List<Attribute> buildAttributeList(ProjectConfig projectConfig, Map<String, String> attributes) {
119+
List<Attribute> attributesList = new ArrayList<Attribute>();
120+
121+
Map<String, com.optimizely.ab.config.Attribute> attributeMap = projectConfig.getAttributeKeyMapping();
122+
for (Map.Entry<String, String> entry : attributes.entrySet()) {
123+
com.optimizely.ab.config.Attribute projectAttribute = attributeMap.get(entry.getKey());
124+
Attribute attribute = new Attribute((projectAttribute != null ? projectAttribute.getId() : null),
125+
entry.getKey(), Attribute.CUSTOM_ATTRIBUTE_TYPE, entry.getValue());
126+
127+
if (entry.getKey() == DecisionService.BUCKETING_ATTRIBUTE) {
128+
attribute = new Attribute(com.optimizely.ab.bucketing.DecisionService.BUCKETING_ATTRIBUTE,
129+
ATTRIBUTE_KEY_FOR_BUCKETING_ATTRIBUTE, Attribute.CUSTOM_ATTRIBUTE_TYPE, entry.getValue());
130+
}
131+
132+
attributesList.add(attribute);
133+
}
134+
135+
return attributesList;
136+
}
42137
}

core-api/src/main/java/com/optimizely/ab/event/internal/EventBuilderV2.java

-233
This file was deleted.

0 commit comments

Comments
 (0)