Skip to content
This repository was archived by the owner on May 30, 2024. It is now read-only.

Commit 0946b65

Browse files
prepare 4.9.0 release (#174)
1 parent 35930a0 commit 0946b65

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+2784
-740
lines changed
Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,65 @@
11
package com.launchdarkly.client;
22

3-
import com.google.gson.JsonArray;
4-
import com.google.gson.JsonElement;
5-
import com.google.gson.JsonPrimitive;
3+
import com.launchdarkly.client.value.LDValue;
4+
import com.launchdarkly.client.value.LDValueType;
5+
66
import org.slf4j.Logger;
77
import org.slf4j.LoggerFactory;
88

9-
import static com.launchdarkly.client.VersionedDataKind.SEGMENTS;
10-
119
import java.util.List;
1210

11+
import static com.launchdarkly.client.VersionedDataKind.SEGMENTS;
12+
1313
class Clause {
1414
private final static Logger logger = LoggerFactory.getLogger(Clause.class);
1515

1616
private String attribute;
1717
private Operator op;
18-
private List<JsonPrimitive> values; //interpreted as an OR of values
18+
private List<LDValue> values; //interpreted as an OR of values
1919
private boolean negate;
2020

2121
public Clause() {
2222
}
2323

24-
public Clause(String attribute, Operator op, List<JsonPrimitive> values, boolean negate) {
24+
public Clause(String attribute, Operator op, List<LDValue> values, boolean negate) {
2525
this.attribute = attribute;
2626
this.op = op;
2727
this.values = values;
2828
this.negate = negate;
2929
}
3030

3131
boolean matchesUserNoSegments(LDUser user) {
32-
JsonElement userValue = user.getValueForEvaluation(attribute);
33-
if (userValue == null) {
32+
LDValue userValue = user.getValueForEvaluation(attribute);
33+
if (userValue.isNull()) {
3434
return false;
3535
}
3636

37-
if (userValue.isJsonArray()) {
38-
JsonArray array = userValue.getAsJsonArray();
39-
for (JsonElement jsonElement : array) {
40-
if (!jsonElement.isJsonPrimitive()) {
41-
logger.error("Invalid custom attribute value in user object for user key \"{}\": {}", user.getKey(), jsonElement);
37+
if (userValue.getType() == LDValueType.ARRAY) {
38+
for (LDValue value: userValue.values()) {
39+
if (value.getType() == LDValueType.ARRAY || value.getType() == LDValueType.OBJECT) {
40+
logger.error("Invalid custom attribute value in user object for user key \"{}\": {}", user.getKey(), value);
4241
return false;
4342
}
44-
if (matchAny(jsonElement.getAsJsonPrimitive())) {
43+
if (matchAny(value)) {
4544
return maybeNegate(true);
4645
}
4746
}
4847
return maybeNegate(false);
49-
} else if (userValue.isJsonPrimitive()) {
50-
return maybeNegate(matchAny(userValue.getAsJsonPrimitive()));
48+
} else if (userValue.getType() != LDValueType.OBJECT) {
49+
return maybeNegate(matchAny(userValue));
5150
}
5251
logger.warn("Got unexpected user attribute type \"{}\" for user key \"{}\" and attribute \"{}\"",
53-
userValue.getClass().getName(), user.getKey(), attribute);
52+
userValue.getType(), user.getKey(), attribute);
5453
return false;
5554
}
5655

5756
boolean matchesUser(FeatureStore store, LDUser user) {
5857
// In the case of a segment match operator, we check if the user is in any of the segments,
5958
// and possibly negate
6059
if (op == Operator.segmentMatch) {
61-
for (JsonPrimitive j: values) {
60+
for (LDValue j: values) {
6261
if (j.isString()) {
63-
Segment segment = store.get(SEGMENTS, j.getAsString());
62+
Segment segment = store.get(SEGMENTS, j.stringValue());
6463
if (segment != null) {
6564
if (segment.matchesUser(user)) {
6665
return maybeNegate(true);
@@ -74,9 +73,9 @@ boolean matchesUser(FeatureStore store, LDUser user) {
7473
return matchesUserNoSegments(user);
7574
}
7675

77-
private boolean matchAny(JsonPrimitive userValue) {
76+
private boolean matchAny(LDValue userValue) {
7877
if (op != null) {
79-
for (JsonPrimitive v : values) {
78+
for (LDValue v : values) {
8079
if (op.apply(userValue, v)) {
8180
return true;
8281
}
@@ -91,6 +90,4 @@ private boolean maybeNegate(boolean b) {
9190
else
9291
return b;
9392
}
94-
95-
9693
}

src/main/java/com/launchdarkly/client/EvaluationDetail.java

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,48 @@
11
package com.launchdarkly.client;
22

33
import com.google.common.base.Objects;
4+
import com.launchdarkly.client.value.LDValue;
45

56
/**
67
* An object returned by the "variation detail" methods such as {@link LDClientInterface#boolVariationDetail(String, LDUser, boolean)},
78
* combining the result of a flag evaluation with an explanation of how it was calculated.
9+
* @param <T> the type of the wrapped value
810
* @since 4.3.0
911
*/
1012
public class EvaluationDetail<T> {
1113

1214
private final EvaluationReason reason;
1315
private final Integer variationIndex;
1416
private final T value;
15-
17+
18+
/**
19+
* Constructs an instance with all properties specified.
20+
*
21+
* @param reason an {@link EvaluationReason} (should not be null)
22+
* @param variationIndex an optional variation index
23+
* @param value a value of the desired type
24+
*/
1625
public EvaluationDetail(EvaluationReason reason, Integer variationIndex, T value) {
17-
this.reason = reason;
18-
this.variationIndex = variationIndex;
1926
this.value = value;
27+
this.variationIndex = variationIndex;
28+
this.reason = reason;
29+
}
30+
31+
/**
32+
* Factory method for an arbitrary value.
33+
*
34+
* @param value a value of the desired type
35+
* @param variationIndex an optional variation index
36+
* @param reason an {@link EvaluationReason} (should not be null)
37+
* @return an {@link EvaluationDetail}
38+
* @since 4.8.0
39+
*/
40+
public static <T> EvaluationDetail<T> fromValue(T value, Integer variationIndex, EvaluationReason reason) {
41+
return new EvaluationDetail<T>(reason, variationIndex, value);
2042
}
2143

22-
static <T> EvaluationDetail<T> error(EvaluationReason.ErrorKind errorKind, T defaultValue) {
23-
return new EvaluationDetail<>(EvaluationReason.error(errorKind), null, defaultValue);
44+
static EvaluationDetail<LDValue> error(EvaluationReason.ErrorKind errorKind, LDValue defaultValue) {
45+
return new EvaluationDetail<LDValue>(EvaluationReason.error(errorKind), null, LDValue.normalize(defaultValue));
2446
}
2547

2648
/**

src/main/java/com/launchdarkly/client/Event.java

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.launchdarkly.client;
22

33
import com.google.gson.JsonElement;
4+
import com.launchdarkly.client.value.LDValue;
45

56
/**
67
* Base class for all analytics events that are generated by the client. Also defines all of its own subclasses.
@@ -16,18 +17,22 @@ public Event(long creationDate, LDUser user) {
1617

1718
public static final class Custom extends Event {
1819
final String key;
19-
final JsonElement data;
20+
final LDValue data;
2021
final Double metricValue;
2122

22-
public Custom(long timestamp, String key, LDUser user, JsonElement data, Double metricValue) {
23+
/**
24+
* @since 4.8.0
25+
*/
26+
public Custom(long timestamp, String key, LDUser user, LDValue data, Double metricValue) {
2327
super(timestamp, user);
2428
this.key = key;
25-
this.data = data;
29+
this.data = data == null ? LDValue.ofNull() : data;
2630
this.metricValue = metricValue;
2731
}
2832

33+
@Deprecated
2934
public Custom(long timestamp, String key, LDUser user, JsonElement data) {
30-
this(timestamp, key, user, data, null);
35+
this(timestamp, key, user, LDValue.unsafeFromJsonElement(data), null);
3136
}
3237
}
3338

@@ -46,23 +51,20 @@ public Index(long timestamp, LDUser user) {
4651
public static final class FeatureRequest extends Event {
4752
final String key;
4853
final Integer variation;
49-
final JsonElement value;
50-
final JsonElement defaultVal;
54+
final LDValue value;
55+
final LDValue defaultVal;
5156
final Integer version;
5257
final String prereqOf;
5358
final boolean trackEvents;
5459
final Long debugEventsUntilDate;
5560
final EvaluationReason reason;
5661
final boolean debug;
5762

58-
@Deprecated
59-
public FeatureRequest(long timestamp, String key, LDUser user, Integer version, Integer variation, JsonElement value,
60-
JsonElement defaultVal, String prereqOf, boolean trackEvents, Long debugEventsUntilDate, boolean debug) {
61-
this(timestamp, key, user, version, variation, value, defaultVal, prereqOf, trackEvents, debugEventsUntilDate, null, debug);
62-
}
63-
64-
public FeatureRequest(long timestamp, String key, LDUser user, Integer version, Integer variation, JsonElement value,
65-
JsonElement defaultVal, String prereqOf, boolean trackEvents, Long debugEventsUntilDate, EvaluationReason reason, boolean debug) {
63+
/**
64+
* @since 4.8.0
65+
*/
66+
public FeatureRequest(long timestamp, String key, LDUser user, Integer version, Integer variation, LDValue value,
67+
LDValue defaultVal, EvaluationReason reason, String prereqOf, boolean trackEvents, Long debugEventsUntilDate, boolean debug) {
6668
super(timestamp, user);
6769
this.key = key;
6870
this.version = version;
@@ -75,6 +77,20 @@ public FeatureRequest(long timestamp, String key, LDUser user, Integer version,
7577
this.reason = reason;
7678
this.debug = debug;
7779
}
80+
81+
@Deprecated
82+
public FeatureRequest(long timestamp, String key, LDUser user, Integer version, Integer variation, JsonElement value,
83+
JsonElement defaultVal, String prereqOf, boolean trackEvents, Long debugEventsUntilDate, boolean debug) {
84+
this(timestamp, key, user, version, variation, LDValue.unsafeFromJsonElement(value), LDValue.unsafeFromJsonElement(defaultVal),
85+
null, prereqOf, trackEvents, debugEventsUntilDate, debug);
86+
}
87+
88+
@Deprecated
89+
public FeatureRequest(long timestamp, String key, LDUser user, Integer version, Integer variation, JsonElement value,
90+
JsonElement defaultVal, String prereqOf, boolean trackEvents, Long debugEventsUntilDate, EvaluationReason reason, boolean debug) {
91+
this(timestamp, key, user, version, variation, LDValue.unsafeFromJsonElement(value), LDValue.unsafeFromJsonElement(defaultVal),
92+
reason, prereqOf, trackEvents, debugEventsUntilDate, debug);
93+
}
7894
}
7995

8096
}

src/main/java/com/launchdarkly/client/EventFactory.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.launchdarkly.client;
22

3-
import com.google.gson.JsonElement;
3+
import com.launchdarkly.client.value.LDValue;
44

55
abstract class EventFactory {
66
public static final EventFactory DEFAULT = new DefaultEventFactory(false);
@@ -9,8 +9,8 @@ abstract class EventFactory {
99
protected abstract long getTimestamp();
1010
protected abstract boolean isIncludeReasons();
1111

12-
public Event.FeatureRequest newFeatureRequestEvent(FeatureFlag flag, LDUser user, JsonElement value,
13-
Integer variationIndex, EvaluationReason reason, JsonElement defaultValue, String prereqOf) {
12+
public Event.FeatureRequest newFeatureRequestEvent(FeatureFlag flag, LDUser user, LDValue value,
13+
Integer variationIndex, EvaluationReason reason, LDValue defaultValue, String prereqOf) {
1414
boolean requireExperimentData = isExperiment(flag, reason);
1515
return new Event.FeatureRequest(
1616
getTimestamp(),
@@ -20,46 +20,46 @@ public Event.FeatureRequest newFeatureRequestEvent(FeatureFlag flag, LDUser user
2020
variationIndex,
2121
value,
2222
defaultValue,
23+
(requireExperimentData || isIncludeReasons()) ? reason : null,
2324
prereqOf,
2425
requireExperimentData || flag.isTrackEvents(),
2526
flag.getDebugEventsUntilDate(),
26-
(requireExperimentData || isIncludeReasons()) ? reason : null,
2727
false
2828
);
2929
}
3030

31-
public Event.FeatureRequest newFeatureRequestEvent(FeatureFlag flag, LDUser user, EvaluationDetail<JsonElement> result, JsonElement defaultVal) {
31+
public Event.FeatureRequest newFeatureRequestEvent(FeatureFlag flag, LDUser user, EvaluationDetail<LDValue> result, LDValue defaultVal) {
3232
return newFeatureRequestEvent(flag, user, result == null ? null : result.getValue(),
3333
result == null ? null : result.getVariationIndex(), result == null ? null : result.getReason(),
3434
defaultVal, null);
3535
}
3636

37-
public Event.FeatureRequest newDefaultFeatureRequestEvent(FeatureFlag flag, LDUser user, JsonElement defaultValue,
37+
public Event.FeatureRequest newDefaultFeatureRequestEvent(FeatureFlag flag, LDUser user, LDValue defaultValue,
3838
EvaluationReason.ErrorKind errorKind) {
3939
return new Event.FeatureRequest(getTimestamp(), flag.getKey(), user, flag.getVersion(),
40-
null, defaultValue, defaultValue, null, flag.isTrackEvents(), flag.getDebugEventsUntilDate(),
41-
isIncludeReasons() ? EvaluationReason.error(errorKind) : null, false);
40+
null, defaultValue, defaultValue, isIncludeReasons() ? EvaluationReason.error(errorKind) : null,
41+
null, flag.isTrackEvents(), flag.getDebugEventsUntilDate(), false);
4242
}
4343

44-
public Event.FeatureRequest newUnknownFeatureRequestEvent(String key, LDUser user, JsonElement defaultValue,
44+
public Event.FeatureRequest newUnknownFeatureRequestEvent(String key, LDUser user, LDValue defaultValue,
4545
EvaluationReason.ErrorKind errorKind) {
46-
return new Event.FeatureRequest(getTimestamp(), key, user, null, null, defaultValue, defaultValue, null, false, null,
47-
isIncludeReasons() ? EvaluationReason.error(errorKind) : null, false);
46+
return new Event.FeatureRequest(getTimestamp(), key, user, null, null, defaultValue, defaultValue,
47+
isIncludeReasons() ? EvaluationReason.error(errorKind) : null, null, false, null, false);
4848
}
4949

50-
public Event.FeatureRequest newPrerequisiteFeatureRequestEvent(FeatureFlag prereqFlag, LDUser user, EvaluationDetail<JsonElement> result,
50+
public Event.FeatureRequest newPrerequisiteFeatureRequestEvent(FeatureFlag prereqFlag, LDUser user, EvaluationDetail<LDValue> result,
5151
FeatureFlag prereqOf) {
5252
return newFeatureRequestEvent(prereqFlag, user, result == null ? null : result.getValue(),
5353
result == null ? null : result.getVariationIndex(), result == null ? null : result.getReason(),
54-
null, prereqOf.getKey());
54+
LDValue.ofNull(), prereqOf.getKey());
5555
}
5656

5757
public Event.FeatureRequest newDebugEvent(Event.FeatureRequest from) {
5858
return new Event.FeatureRequest(from.creationDate, from.key, from.user, from.version, from.variation, from.value,
59-
from.defaultVal, from.prereqOf, from.trackEvents, from.debugEventsUntilDate, from.reason, true);
59+
from.defaultVal, from.reason, from.prereqOf, from.trackEvents, from.debugEventsUntilDate, true);
6060
}
6161

62-
public Event.Custom newCustomEvent(String key, LDUser user, JsonElement data, Double metricValue) {
62+
public Event.Custom newCustomEvent(String key, LDUser user, LDValue data, Double metricValue) {
6363
return new Event.Custom(getTimestamp(), key, user, data, metricValue);
6464
}
6565

0 commit comments

Comments
 (0)