Skip to content

Commit 030d2bc

Browse files
authored
Merge pull request #42 from optimizely/mng/add-ip-anon
Add IP anonymization to event payload.
2 parents 6a3f2aa + 91a6eef commit 030d2bc

File tree

16 files changed

+71
-12
lines changed

16 files changed

+71
-12
lines changed

core-api/src/main/java/com/optimizely/ab/config/ProjectConfig.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public String toString() {
5858
private final String projectId;
5959
private final String revision;
6060
private final String version;
61+
private final boolean anonymizeIP;
6162
private final List<Group> groups;
6263
private final List<Experiment> experiments;
6364
private final List<Attribute> attributes;
@@ -79,18 +80,19 @@ public String toString() {
7980
public ProjectConfig(String accountId, String projectId, String version, String revision, List<Group> groups,
8081
List<Experiment> experiments, List<Attribute> attributes, List<EventType> eventType,
8182
List<Audience> audiences) {
82-
this(accountId, projectId, version, revision, groups, experiments, attributes, eventType, audiences,
83+
this(accountId, projectId, version, revision, groups, experiments, attributes, eventType, audiences, false,
8384
null);
8485
}
8586

8687
public ProjectConfig(String accountId, String projectId, String version, String revision, List<Group> groups,
8788
List<Experiment> experiments, List<Attribute> attributes, List<EventType> eventType,
88-
List<Audience> audiences, List<LiveVariable> liveVariables) {
89+
List<Audience> audiences, boolean anonymizeIP, List<LiveVariable> liveVariables) {
8990

9091
this.accountId = accountId;
9192
this.projectId = projectId;
9293
this.version = version;
9394
this.revision = revision;
95+
this.anonymizeIP = anonymizeIP;
9496

9597
this.groups = Collections.unmodifiableList(groups);
9698
List<Experiment> allExperiments = new ArrayList<Experiment>();
@@ -151,6 +153,10 @@ public String getRevision() {
151153
return revision;
152154
}
153155

156+
public boolean getAnonymizeIP() {
157+
return anonymizeIP;
158+
}
159+
154160
public List<Group> getGroups() {
155161
return groups;
156162
}
@@ -233,6 +239,7 @@ public String toString() {
233239
", projectId='" + projectId + '\'' +
234240
", revision='" + revision + '\'' +
235241
", version='" + version + '\'' +
242+
", anonymizeIP='" + anonymizeIP + '\'' +
236243
", groups=" + groups +
237244
", experiments=" + experiments +
238245
", attributes=" + attributes +

core-api/src/main/java/com/optimizely/ab/config/parser/JsonConfigParser.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,16 @@ public ProjectConfig parseProjectConfig(@Nonnull String json) throws ConfigParse
7373
List<Audience> audiences = parseAudiences(rootObject.getJSONArray("audiences"));
7474
List<Group> groups = parseGroups(rootObject.getJSONArray("groups"));
7575

76+
boolean anonymizeIP = false;
7677
List<LiveVariable> liveVariables = null;
7778
if (version.equals(ProjectConfig.Version.V3.toString())) {
7879
liveVariables = parseLiveVariables(rootObject.getJSONArray("variables"));
80+
81+
anonymizeIP = rootObject.getBoolean("anonymizeIP");
7982
}
8083

8184
return new ProjectConfig(accountId, projectId, version, revision, groups, experiments, attributes, events,
82-
audiences, liveVariables);
85+
audiences, anonymizeIP, liveVariables);
8386
} catch (Exception e) {
8487
throw new ConfigParseException("Unable to parse datafile: " + json, e);
8588
}

core-api/src/main/java/com/optimizely/ab/config/parser/JsonSimpleConfigParser.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,16 @@ public ProjectConfig parseProjectConfig(@Nonnull String json) throws ConfigParse
7575
List<Audience> audiences = parseAudiences((JSONArray)parser.parse(rootObject.get("audiences").toString()));
7676
List<Group> groups = parseGroups((JSONArray)rootObject.get("groups"));
7777

78+
boolean anonymizeIP = false;
7879
List<LiveVariable> liveVariables = null;
7980
if (version.equals(ProjectConfig.Version.V3.toString())) {
8081
liveVariables = parseLiveVariables((JSONArray)rootObject.get("variables"));
82+
83+
anonymizeIP = (Boolean)rootObject.get("anonymizeIP");
8184
}
8285

8386
return new ProjectConfig(accountId, projectId, version, revision, groups, experiments, attributes, events,
84-
audiences, liveVariables);
87+
audiences, anonymizeIP, liveVariables);
8588
} catch (Exception e) {
8689
throw new ConfigParseException("Unable to parse datafile: " + json, e);
8790
}

core-api/src/main/java/com/optimizely/ab/config/parser/ProjectConfigGsonDeserializer.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,17 @@ public ProjectConfig deserialize(JsonElement json, Type typeOfT, JsonDeserializa
7272
List<Audience> audiences =
7373
context.deserialize(jsonObject.get("audiences").getAsJsonArray(), audienceType);
7474

75+
boolean anonymizeIP = false;
7576
// live variables should be null if using V1
7677
List<LiveVariable> liveVariables = null;
7778
if (version.equals(ProjectConfig.Version.V3.toString())) {
7879
Type liveVariablesType = new TypeToken<List<LiveVariable>>() {}.getType();
7980
liveVariables = context.deserialize(jsonObject.getAsJsonArray("variables"), liveVariablesType);
81+
82+
anonymizeIP = jsonObject.get("anonymizeIP").getAsBoolean();
8083
}
8184

8285
return new ProjectConfig(accountId, projectId, version, revision, groups, experiments, attributes, events,
83-
audiences, liveVariables);
86+
audiences, anonymizeIP, liveVariables);
8487
}
8588
}

core-api/src/main/java/com/optimizely/ab/config/parser/ProjectConfigJacksonDeserializer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,15 @@ public ProjectConfig deserialize(JsonParser parser, DeserializationContext conte
6868
List<Audience> audiences = mapper.readValue(node.get("audiences").toString(),
6969
new TypeReference<List<Audience>>() {});
7070

71+
boolean anonymizeIP = false;
7172
List<LiveVariable> liveVariables = null;
7273
if (version.equals(ProjectConfig.Version.V3.toString())) {
7374
liveVariables = mapper.readValue(node.get("variables").toString(),
7475
new TypeReference<List<LiveVariable>>() {});
76+
anonymizeIP = node.get("anonymizeIP").asBoolean();
7577
}
7678

7779
return new ProjectConfig(accountId, projectId, version, revision, groups, experiments, attributes, events,
78-
audiences, liveVariables);
80+
audiences, anonymizeIP, liveVariables);
7981
}
8082
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ public class EventBuilderV2 extends EventBuilder {
5151

5252
private static final Logger logger = LoggerFactory.getLogger(EventBuilderV2.class);
5353

54-
static final String IMPRESSION_ENDPOINT = "https://p13nlog.dz.optimizely.com/log/decision";
55-
static final String CONVERSION_ENDPOINT = "https://p13nlog.dz.optimizely.com/log/event";
54+
static final String IMPRESSION_ENDPOINT = "https://logx.optimizely.com/log/decision";
55+
static final String CONVERSION_ENDPOINT = "https://logx.optimizely.com/log/event";
5656

5757
@VisibleForTesting
5858
public final ClientEngine clientEngine;
@@ -95,6 +95,7 @@ public LogEvent createImpressionEvent(@Nonnull ProjectConfig projectConfig,
9595
impressionPayload.setUserFeatures(createFeatures(attributes, projectConfig));
9696
impressionPayload.setClientEngine(clientEngine);
9797
impressionPayload.setClientVersion(clientVersion);
98+
impressionPayload.setAnonymizeIP(projectConfig.getAnonymizeIP());
9899

99100
String payload = this.serializer.serialize(impressionPayload);
100101
return new LogEvent(RequestMethod.POST, IMPRESSION_ENDPOINT, Collections.<String, String>emptyMap(), payload);
@@ -133,6 +134,7 @@ public LogEvent createConversionEvent(@Nonnull ProjectConfig projectConfig,
133134

134135
conversionPayload.setEventFeatures(Collections.<Feature>emptyList());
135136
conversionPayload.setIsGlobalHoldback(false);
137+
conversionPayload.setAnonymizeIP(projectConfig.getAnonymizeIP());
136138
conversionPayload.setClientEngine(clientEngine);
137139
conversionPayload.setClientVersion(clientVersion);
138140

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ public class Conversion extends Event {
3131
private List<EventMetric> eventMetrics;
3232
private List<Feature> eventFeatures;
3333
private boolean isGlobalHoldback;
34+
private boolean anonymizeIP;
3435

3536
public Conversion() { }
3637

3738
public Conversion(String visitorId, long timestamp, String projectId, String accountId, List<Feature> userFeatures,
3839
List<LayerState> layerStates, String eventEntityId, String eventName,
39-
List<EventMetric> eventMetrics, List<Feature> eventFeatures, boolean isGlobalHoldback) {
40+
List<EventMetric> eventMetrics, List<Feature> eventFeatures, boolean isGlobalHoldback, boolean anonymizeIP) {
4041
this.visitorId = visitorId;
4142
this.timestamp = timestamp;
4243
this.projectId = projectId;
@@ -48,6 +49,7 @@ public Conversion(String visitorId, long timestamp, String projectId, String acc
4849
this.eventMetrics = eventMetrics;
4950
this.eventFeatures = eventFeatures;
5051
this.isGlobalHoldback = isGlobalHoldback;
52+
this.anonymizeIP = anonymizeIP;
5153
}
5254

5355
public String getVisitorId() {
@@ -138,6 +140,10 @@ public void setIsGlobalHoldback(boolean globalHoldback) {
138140
this.isGlobalHoldback = globalHoldback;
139141
}
140142

143+
public boolean getAnonymizeIP() { return anonymizeIP; }
144+
145+
public void setAnonymizeIP(boolean anonymizeIP) { this.anonymizeIP = anonymizeIP; }
146+
141147
@Override
142148
public boolean equals(Object other) {
143149
if (!(other instanceof Conversion))
@@ -192,6 +198,7 @@ public String toString() {
192198
", eventMetrics=" + eventMetrics +
193199
", eventFeatures=" + eventFeatures +
194200
", isGlobalHoldback=" + isGlobalHoldback +
201+
", anonymizeIP=" + anonymizeIP +
195202
", clientEngine='" + clientEngine +
196203
", clientVersion='" + clientVersion + '}';
197204
}

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ public class Impression extends Event {
2828
private String layerId;
2929
private String accountId;
3030
private List<Feature> userFeatures;
31+
private boolean anonymizeIP;
3132

3233
public Impression() { }
3334

3435
public Impression(String visitorId, long timestamp, boolean isGlobalHoldback, String projectId, Decision decision,
35-
String layerId, String accountId, List<Feature> userFeatures) {
36+
String layerId, String accountId, List<Feature> userFeatures, boolean anonymizeIP) {
3637
this.visitorId = visitorId;
3738
this.timestamp = timestamp;
3839
this.isGlobalHoldback = isGlobalHoldback;
@@ -41,6 +42,7 @@ public Impression(String visitorId, long timestamp, boolean isGlobalHoldback, St
4142
this.layerId = layerId;
4243
this.accountId = accountId;
4344
this.userFeatures = userFeatures;
45+
this.anonymizeIP = anonymizeIP;
4446
}
4547

4648
public String getVisitorId() {
@@ -107,6 +109,14 @@ public void setUserFeatures(List<Feature> userFeatures) {
107109
this.userFeatures = userFeatures;
108110
}
109111

112+
public boolean getAnonymizeIP() {
113+
return anonymizeIP;
114+
}
115+
116+
public void setAnonymizeIP(boolean anonymizeIP) {
117+
this.anonymizeIP = anonymizeIP;
118+
}
119+
110120
@Override
111121
public boolean equals(Object other) {
112122
if (!(other instanceof Impression))
@@ -147,6 +157,7 @@ public String toString() {
147157
"visitorId='" + visitorId + '\'' +
148158
", timestamp=" + timestamp +
149159
", isGlobalHoldback=" + isGlobalHoldback +
160+
", anonymizeIP=" + anonymizeIP +
150161
", projectId='" + projectId + '\'' +
151162
", decision=" + decision +
152163
", layerId='" + layerId + '\'' +

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ private JSONObject serializeImpression(Impression impression) {
4848
jsonObject.put("visitorId", impression.getVisitorId());
4949
jsonObject.put("timestamp", impression.getTimestamp());
5050
jsonObject.put("isGlobalHoldback", impression.getIsGlobalHoldback());
51+
jsonObject.put("anonymizeIP", impression.getAnonymizeIP());
5152
jsonObject.put("projectId", impression.getProjectId());
5253
jsonObject.put("decision", serializeDecision(impression.getDecision()));
5354
jsonObject.put("layerId", impression.getLayerId());
@@ -72,6 +73,7 @@ private JSONObject serializeConversion(Conversion conversion) {
7273
jsonObject.put("eventMetrics", serializeEventMetrics(conversion.getEventMetrics()));
7374
jsonObject.put("eventFeatures", serializeFeatures(conversion.getEventFeatures()));
7475
jsonObject.put("isGlobalHoldback", conversion.getIsGlobalHoldback());
76+
jsonObject.put("anonymizeIP", conversion.getAnonymizeIP());
7577
jsonObject.put("clientEngine", conversion.getClientEngine());
7678
jsonObject.put("clientVersion", conversion.getClientVersion());
7779

core-api/src/test/java/com/optimizely/ab/config/ProjectConfigTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
import static java.util.Arrays.asList;
3232
import static org.hamcrest.CoreMatchers.is;
33+
import static org.junit.Assert.assertFalse;
3334
import static org.junit.Assert.assertNull;
3435
import static org.junit.Assert.assertThat;
3536

@@ -179,4 +180,15 @@ public void verifyGetVariationToLiveVariableUsageInstanceMapping() throws Except
179180
assertThat(projectConfig.getVariationToLiveVariableUsageInstanceMapping(),
180181
is(expectedVariationToLiveVariableUsageInstanceMapping));
181182
}
183+
184+
/**
185+
* Asserts that anonymizeIP is set to false if not explicitly passed into the constructor (in the case of V1 or V2
186+
* projects).
187+
* @throws Exception
188+
*/
189+
@Test
190+
public void verifyAnonymizeIPIsFalseByDefault() throws Exception {
191+
ProjectConfig v2ProjectConfig = ProjectConfigTestUtils.validProjectConfigV2();
192+
assertFalse(v2ProjectConfig.getAnonymizeIP());
193+
}
182194
}

0 commit comments

Comments
 (0)