Skip to content

Commit 7e8b73c

Browse files
authored
✨ feat: support debug event track (#40)
* ✨ feat: support debug event track
1 parent 1405c65 commit 7e8b73c

File tree

10 files changed

+125
-29
lines changed

10 files changed

+125
-29
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
<groupId>com.featureprobe</groupId>
77
<artifactId>server-sdk-java</artifactId>
8-
<version>2.1.1</version>
8+
<version>2.2.0</version>
99
<name>server-sdk-java</name>
1010
<description>FeatureProbe Server Side SDK for Java</description>
1111

src/main/java/com/featureprobe/sdk/server/AccessEvent.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,17 @@ public class AccessEvent extends Event {
3030

3131
private final Integer ruleIndex;
3232

33-
private final String reason;
34-
3533
@JsonIgnore
3634
private boolean trackAccessEvents;
3735

38-
public AccessEvent(String user, String key, Object value, Long version, Integer variationIndex,
39-
Integer ruleIndex, String reason, boolean trackAccessEvents) {
40-
super("access", System.currentTimeMillis(), user);
36+
public AccessEvent(FPUser user, String key, Object value, Long version, Integer variationIndex,
37+
Integer ruleIndex, boolean trackAccessEvents) {
38+
super("access", System.currentTimeMillis(), user.getKey());
4139
this.value = value;
4240
this.version = version;
4341
this.variationIndex = variationIndex;
4442
this.key = key;
4543
this.ruleIndex = ruleIndex;
46-
this.reason = reason;
4744
this.trackAccessEvents = trackAccessEvents;
4845
}
4946

@@ -67,10 +64,6 @@ public Integer getRuleIndex() {
6764
return ruleIndex;
6865
}
6966

70-
public String getReason() {
71-
return reason;
72-
}
73-
7467
public boolean isTrackAccessEvents() {
7568
return trackAccessEvents;
7669
}

src/main/java/com/featureprobe/sdk/server/CustomEvent.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ public class CustomEvent extends Event {
2323

2424
private final Double value;
2525

26-
public CustomEvent(String name, String user, Double value) {
27-
super("custom", System.currentTimeMillis(), user);
26+
public CustomEvent(String name, FPUser user, Double value) {
27+
super("custom", System.currentTimeMillis(), user.getKey());
2828
this.name = name;
2929
this.value = value;
3030
}

src/main/java/com/featureprobe/sdk/server/DataRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ public interface DataRepository extends Closeable {
3636

3737
Map<String, Segment> getAllSegment();
3838

39+
Long getDebugUntilTime();
40+
3941
boolean initialized();
4042

4143
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.featureprobe.sdk.server;
19+
20+
public class DebugEvent extends Event {
21+
22+
private final String key;
23+
private final Object value;
24+
25+
private final Long version;
26+
27+
private final Integer variationIndex;
28+
29+
private final Integer ruleIndex;
30+
31+
private final String reason;
32+
33+
private FPUser userDetail;
34+
35+
public DebugEvent(FPUser user, String key, Object value, Long version, Integer variationIndex,
36+
Integer ruleIndex, String reason) {
37+
super("debug", System.currentTimeMillis(), user.getKey());
38+
this.value = value;
39+
this.version = version;
40+
this.variationIndex = variationIndex;
41+
this.key = key;
42+
this.ruleIndex = ruleIndex;
43+
this.reason = reason;
44+
this.userDetail = user;
45+
}
46+
47+
public String getKey() {
48+
return key;
49+
}
50+
51+
public Object getValue() {
52+
return value;
53+
}
54+
55+
public Long getVersion() {
56+
return version;
57+
}
58+
59+
public Integer getVariationIndex() {
60+
return variationIndex;
61+
}
62+
63+
public Integer getRuleIndex() {
64+
return ruleIndex;
65+
}
66+
67+
public String getReason() {
68+
return reason;
69+
}
70+
71+
public FPUser getUserDetail() {
72+
return userDetail;
73+
}
74+
}

src/main/java/com/featureprobe/sdk/server/DefaultEventProcessor.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,10 +245,11 @@ boolean isEmpty() {
245245
void add(Event event) {
246246
if (event instanceof AccessEvent) {
247247
access.add(event);
248-
if (((AccessEvent) event).isTrackAccessEvents()) {
248+
AccessEvent accessEvent = ((AccessEvent) event);
249+
if (accessEvent.isTrackAccessEvents()) {
249250
events.add(event);
250251
}
251-
} else if (event instanceof CustomEvent) {
252+
} else {
252253
events.add(event);
253254
}
254255
}

src/main/java/com/featureprobe/sdk/server/FeatureProbe.java

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import com.fasterxml.jackson.core.JsonProcessingException;
2121
import com.fasterxml.jackson.databind.ObjectMapper;
22-
import com.featureprobe.sdk.server.exceptions.PrerequisitesDeepOverflowException;
2322
import com.featureprobe.sdk.server.model.Segment;
2423
import com.featureprobe.sdk.server.model.Toggle;
2524
import com.google.common.annotations.VisibleForTesting;
@@ -243,7 +242,7 @@ public boolean initialized() {
243242
* @param user {@link FPUser}
244243
*/
245244
public void track(String eventName, FPUser user) {
246-
eventProcessor.push(new CustomEvent(eventName, user.getKey(), null));
245+
eventProcessor.push(new CustomEvent(eventName, user, null));
247246
}
248247

249248
/**
@@ -254,7 +253,7 @@ public void track(String eventName, FPUser user) {
254253
* @param value a numeric value
255254
*/
256255
public void track(String eventName, FPUser user, double value) {
257-
eventProcessor.push(new CustomEvent(eventName, user.getKey(), value));
256+
eventProcessor.push(new CustomEvent(eventName, user, value));
258257
}
259258

260259
private <T> T jsonEvaluate(String toggleKey, FPUser user, T defaultValue, Class<T> clazz) {
@@ -266,7 +265,7 @@ private <T> T jsonEvaluate(String toggleKey, FPUser user, T defaultValue, Class<
266265
EvaluationResult evalResult = toggle.eval(user, toggles, segments, defaultValue,
267266
config.prerequisiteDeep);
268267
String value = mapper.writeValueAsString(evalResult.getValue());
269-
eventProcessor.push(buildAccessEvent(toggle, evalResult, user));
268+
trackEvent(toggle, evalResult, user);
270269
return mapper.readValue(value, clazz);
271270
}
272271
} catch (JsonProcessingException e) {
@@ -285,7 +284,7 @@ private <T> T genericEvaluate(String toggleKey, FPUser user, T defaultValue, Cla
285284
if (Objects.nonNull(toggle)) {
286285
EvaluationResult evalResult = toggle.eval(user, toggles, segments, defaultValue,
287286
config.prerequisiteDeep);
288-
eventProcessor.push(buildAccessEvent(toggle, evalResult, user));
287+
trackEvent(toggle, evalResult, user);
289288
return clazz.cast(evalResult.getValue());
290289
}
291290
} catch (ClassCastException e) {
@@ -318,9 +317,6 @@ private <T> FPDetail<T> genericEvaluateDetail(String toggleKey, FPUser user, T d
318317
} catch (ClassCastException | JsonProcessingException e) {
319318
logger.error(LOG_CONVERSION_ERROR, toggleKey, e);
320319
detail.setReason(REASON_TYPE_MISMATCH);
321-
} catch (PrerequisitesDeepOverflowException e) {
322-
logger.error(e.getMessage(), toggleKey, e);
323-
detail.setReason(e.getMessage());
324320
} catch (Exception e) {
325321
logger.error(LOG_HANDLE_ERROR, toggleKey, e);
326322
detail.setReason(REASON_HANDLE_ERROR);
@@ -349,7 +345,7 @@ private <T> FPDetail<T> getEvaluateDetail(String toggleKey, FPUser user, T defau
349345
detail.setReason(evalResult.getReason());
350346
detail.setRuleIndex(evalResult.getRuleIndex());
351347
detail.setVersion(Optional.of(evalResult.getVersion()));
352-
eventProcessor.push(buildAccessEvent(toggle, evalResult, user));
348+
trackEvent(toggle, evalResult, user);
353349
} else {
354350
detail.setReason("Toggle not exist");
355351
detail.setValue(defaultValue);
@@ -361,12 +357,26 @@ private <T> FPDetail<T> getEvaluateDetail(String toggleKey, FPUser user, T defau
361357
return detail;
362358
}
363359

360+
private void trackEvent(Toggle toggle, EvaluationResult evalResult, FPUser user) {
361+
eventProcessor.push(buildAccessEvent(toggle, evalResult, user));
362+
if (Objects.nonNull(dataRepository.getDebugUntilTime())
363+
&& dataRepository.getDebugUntilTime() >= System.currentTimeMillis()) {
364+
eventProcessor.push(buildDebugEvent(toggle, evalResult, user));
365+
}
366+
}
367+
364368
private Event buildAccessEvent(Toggle toggle, EvaluationResult evalResult, FPUser user) {
365369
boolean trackAccessEvents =
366370
Objects.isNull(toggle.getTrackAccessEvents()) ? false : toggle.getTrackAccessEvents().booleanValue();
367-
return new AccessEvent(user.getKey(), toggle.getKey(), evalResult.getValue(),
371+
return new AccessEvent(user, toggle.getKey(), evalResult.getValue(),
372+
evalResult.getVersion(), evalResult.getVariationIndex().orElse(null),
373+
evalResult.getRuleIndex().orElse(null), trackAccessEvents);
374+
}
375+
376+
private Event buildDebugEvent(Toggle toggle, EvaluationResult evalResult, FPUser user) {
377+
return new DebugEvent(user, toggle.getKey(), evalResult.getValue(),
368378
evalResult.getVersion(), evalResult.getVariationIndex().orElse(null),
369-
evalResult.getRuleIndex().orElse(null), evalResult.getReason(), trackAccessEvents);
379+
evalResult.getRuleIndex().orElse(null), evalResult.getReason());
370380
}
371381

372382
}

src/main/java/com/featureprobe/sdk/server/MemoryDataRepository.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.featureprobe.sdk.server.model.Segment;
2222
import com.featureprobe.sdk.server.model.Toggle;
2323
import com.google.common.collect.ImmutableMap;
24+
2425
import java.util.Map;
2526
import java.util.Objects;
2627

@@ -39,7 +40,7 @@ public void refresh(Repository repository) {
3940
&& Objects.nonNull(repository.getSegments())) {
4041
Map<String, Toggle> toggles = ImmutableMap.copyOf(repository.getToggles());
4142
Map<String, Segment> segments = ImmutableMap.copyOf(repository.getSegments());
42-
data = new Repository(toggles, segments);
43+
data = new Repository(toggles, segments, repository.getDebugUntilTime());
4344
this.initialized = true;
4445
this.updatedTimestamp = System.currentTimeMillis();
4546
}
@@ -78,6 +79,11 @@ public Map<String, Segment> getAllSegment() {
7879
return ImmutableMap.of();
7980
}
8081

82+
@Override
83+
public Long getDebugUntilTime() {
84+
return data.getDebugUntilTime();
85+
}
86+
8187
@Override
8288
public boolean initialized() {
8389
return this.initialized;

src/main/java/com/featureprobe/sdk/server/model/Repository.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,15 @@ public final class Repository {
2525

2626
private Map<String, Segment> segments;
2727

28+
private Long debugUntilTime;
29+
2830
public Repository() {
2931
}
3032

31-
public Repository(Map<String, Toggle> toggles, Map<String, Segment> segments) {
33+
public Repository(Map<String, Toggle> toggles, Map<String, Segment> segments, Long debugUntilTime) {
3234
this.toggles = toggles;
3335
this.segments = segments;
36+
this.debugUntilTime = debugUntilTime;
3437
}
3538

3639
public Map<String, Toggle> getToggles() {
@@ -49,4 +52,11 @@ public void setSegments(Map<String, Segment> segments) {
4952
this.segments = segments;
5053
}
5154

55+
public Long getDebugUntilTime() {
56+
return debugUntilTime;
57+
}
58+
59+
public void setDebugUntilTime(Long debugUntilTime) {
60+
this.debugUntilTime = debugUntilTime;
61+
}
5262
}

src/test/groovy/com/featureprobe/sdk/server/AccessSummaryRecorderSpec.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class AccessSummaryRecorderSpec extends Specification {
1010
def setup() {
1111
accessRecorder = new AccessSummaryRecorder()
1212
FPUser user = new FPUser().stableRollout("test_user")
13-
event = new AccessEvent(user.key, "test_toggle", "true", 1, 0, 1, "hid default rule.", true)
13+
event = new AccessEvent(user, "test_toggle", "true", 1, 0, 1, true)
1414
}
1515

1616
def "add a Event"() {

0 commit comments

Comments
 (0)