Skip to content
This repository was archived by the owner on May 30, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
db568d4
initial implementation of Java common SDK code (#1)
eli-darkly Mar 20, 2020
374e08e
stick with Java 7 for Android compatibility (#2)
eli-darkly Apr 15, 2020
f1b9cb4
add getters to EvaluationReason and hide its subclasses
eli-darkly Apr 20, 2020
e86ced3
completely remove EvaluationReason subclasses
eli-darkly Apr 20, 2020
a8d1a91
Merge pull request #3 from launchdarkly/eb/ch74282/hide-reason-subcla…
eli-darkly Apr 20, 2020
0ff060b
Merge pull request #4 from launchdarkly/eb/ch74282/remove-reason-subc…
eli-darkly Apr 20, 2020
d440fd0
add JSON helpers, better serialization logic, and Gson adapter
eli-darkly Apr 20, 2020
04eaf1a
javadoc fixes
eli-darkly Apr 21, 2020
433a1e7
remove @since tags, misc doc fixes, add note about changelogging
eli-darkly Apr 21, 2020
55e3c1b
Merge branch 'eb/ch74370/javadoc-since' into eb/ch73994/gson-interop
eli-darkly Apr 21, 2020
fe6f0eb
fix sample code
eli-darkly Apr 22, 2020
97a8fa3
rename Gson adapter, use factory method
eli-darkly Apr 22, 2020
2c5cc2b
Merge pull request #5 from launchdarkly/eb/ch74370/javadoc-since
eli-darkly Apr 22, 2020
511c9e2
improve and rigorously test equals() for all immutable types
eli-darkly Apr 24, 2020
525daa6
simplifying
eli-darkly Apr 24, 2020
3e222c3
simplifying
eli-darkly Apr 24, 2020
d003179
make EvaluationDetail non-nullable + use boolean singletons
eli-darkly Apr 24, 2020
b810cd7
hide Gson in pom
eli-darkly Apr 24, 2020
129d5b6
doc additions
eli-darkly Apr 24, 2020
0ab6d7c
Merge pull request #8 from launchdarkly/eb/ch74915/non-null-index
eli-darkly Apr 27, 2020
36d3fba
Merge pull request #6 from launchdarkly/eb/ch73994/gson-interop
eli-darkly Apr 27, 2020
939b879
Merge branch 'master' into eb/ch68094/test-equals
eli-darkly Apr 27, 2020
6136698
javadoc fixes
eli-darkly Apr 27, 2020
fa2dd6c
Merge branch 'master' into eb/ch68094/test-equals
eli-darkly Apr 27, 2020
9bd6dbb
Merge pull request #7 from launchdarkly/eb/ch68094/test-equals
eli-darkly Apr 28, 2020
5458738
add Jackson adapter (#9)
eli-darkly Apr 28, 2020
5635a1d
more predictable exception behavior for LDValue.parse()
eli-darkly Apr 28, 2020
4ac7396
Merge pull request #11 from launchdarkly/eb/ch73994/parse-exception
eli-darkly Apr 28, 2020
21e9167
fix the JSON behavior of EvaluationDetail (#10)
eli-darkly Apr 28, 2020
7c29e7b
maximize and enforce test coverage (#12)
eli-darkly Apr 28, 2020
7a2aa77
build and test in Android! (#13)
eli-darkly Apr 29, 2020
aa9f794
Merge branch 'master' of github.com:launchdarkly/java-sdk-common
eli-darkly Apr 29, 2020
d5c3b0d
ensure real nulls can't be stored in an LDValue
eli-darkly May 23, 2020
9e200fb
clean up some unnecessary coverage warnings
eli-darkly May 23, 2020
08f2b21
Merge pull request #15 from launchdarkly/eb/ch77641/null-safety
eli-darkly May 27, 2020
8fbc7a0
more convenient location for coverage reports
eli-darkly May 27, 2020
fbe209b
remove rc1 from changelog
eli-darkly Jun 1, 2020
7f83233
Merge branch 'master' of github.com:launchdarkly/java-sdk-common
eli-darkly Jun 2, 2020
ac4a2cd
Removed the guides link
bwoskow-ld Feb 3, 2021
1cad8c5
Use Android machine image for CircleCI Android tests. (#17)
gwhelanLD Mar 30, 2021
17f0b0b
improve Gson integration using reader/writer delegation + add LDValue…
eli-darkly Mar 30, 2021
96931b3
add LDValue.arrayOf() + misc javadoc fixes
eli-darkly Mar 30, 2021
99c51e9
Merge pull request #19 from launchdarkly/eb/ch104357/array-of
eli-darkly Mar 30, 2021
41058b9
Add inExperiment attribute to FALLTHROUGH and RULE_MATCH reasons
robertjneal Apr 3, 2021
0ea70c9
fix javadoc
robertjneal Apr 3, 2021
532fa70
Update src/main/java/com/launchdarkly/sdk/EvaluationReason.java
robertjneal Apr 6, 2021
7526a58
Update src/main/java/com/launchdarkly/sdk/EvaluationReason.java
robertjneal Apr 6, 2021
e3c06ec
Update src/main/java/com/launchdarkly/sdk/EvaluationReason.java
robertjneal Apr 6, 2021
0b6aef3
Update src/main/java/com/launchdarkly/sdk/EvaluationReason.java
robertjneal Apr 6, 2021
6e1b358
respond to review comments
robertjneal Apr 6, 2021
76533ce
fix test
robertjneal Apr 6, 2021
a9c82c7
Merge pull request #20 from launchdarkly/rneal/ch101658/add-inExperim…
robertjneal Apr 6, 2021
b468c4e
javadoc fix
eli-darkly Apr 8, 2021
fede11e
Merge branch 'master' into exp-alloc
eli-darkly Apr 8, 2021
a5abd08
add validation of javadoc build in CI
eli-darkly Apr 8, 2021
1e11684
add another Eclipse metadata exclusion to .gitignore
eli-darkly Apr 8, 2021
bceedef
Merge pull request #21 from launchdarkly/eb/ch105283/check-javadoc
eli-darkly Apr 8, 2021
3a8aa98
partially revert ch103941 fix that doesn't work in the Java SDK
eli-darkly Apr 14, 2021
3f02d6d
Merge pull request #22 from launchdarkly/eb/ch103941/revert-gson-adapter
eli-darkly Apr 14, 2021
7dee1cf
Merge branch 'master' into exp-alloc
eli-darkly Apr 14, 2021
36fe80f
unrevert some JSON improvements from previous revert
eli-darkly Apr 16, 2021
cfdece2
Merge pull request #23 from launchdarkly/eb/ch103941/json-partial-unr…
eli-darkly Apr 17, 2021
9d50c7e
improve Gson integration using reader/writer delegation - take 2
eli-darkly Apr 19, 2021
df89903
Merge pull request #24 from launchdarkly/eb/ch103941/gson-adapter-fix
eli-darkly Apr 21, 2021
b8ace9b
better Jackson adapter + misc JSON test improvements (#18)
eli-darkly Apr 21, 2021
cd9525e
omit redundant method call (this commit was mistakenly left out of th…
eli-darkly Apr 21, 2021
62c6988
merge from public after release
LaunchDarklyCI Apr 22, 2021
f5680a1
Merge branch 'master' of github.com:launchdarkly/java-sdk-common
eli-darkly Apr 22, 2021
08c734f
avoid unnecessarily adding ".0" to JSON numbers (#25)
eli-darkly Apr 22, 2021
3dbe3f2
merge from public after release
LaunchDarklyCI Apr 22, 2021
6a5a5f6
update Gradle to 6.8.3
eli-darkly May 5, 2021
113c27d
Merge pull request #26 from launchdarkly/eb/ch104534/gradle-update
eli-darkly May 5, 2021
b91dd33
Kotlinize main build script
eli-darkly May 5, 2021
9088dff
rm obsolete comments
eli-darkly May 5, 2021
41a846b
Merge pull request #27 from launchdarkly/eb/ch107687/gradle-kotlin
eli-darkly May 6, 2021
b5c338e
bump Jackson compile-time dependency to 2.10.5.1 due to CVE-2020-2564…
eli-darkly Jun 14, 2021
b9116a8
exclude Gson & Jackson from published dependencies in a more correct …
eli-darkly Jun 14, 2021
242a8f5
merge from public after release
LaunchDarklyCI Jun 15, 2021
6589606
Merge branch 'exp-alloc'
eli-darkly Jun 17, 2021
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
69 changes: 60 additions & 9 deletions src/main/java/com/launchdarkly/sdk/EvaluationReason.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
*/
@JsonAdapter(EvaluationReasonTypeAdapter.class)
public final class EvaluationReason implements JsonSerializable {
private static boolean IN_EXPERIMENT = true;
private static boolean NOT_IN_EXPERIMENT = false;

/**
* Enumerated type defining the possible values of {@link EvaluationReason#getKind()}.
*/
Expand Down Expand Up @@ -96,6 +99,7 @@ public static enum ErrorKind {
// static instances to avoid repeatedly allocating reasons for the same parameters
private static final EvaluationReason OFF_INSTANCE = new EvaluationReason(Kind.OFF);
private static final EvaluationReason FALLTHROUGH_INSTANCE = new EvaluationReason(Kind.FALLTHROUGH);
private static final EvaluationReason FALLTHROUGH_INSTANCE_IN_EXPERIMENT = new EvaluationReason(Kind.FALLTHROUGH, IN_EXPERIMENT);
private static final EvaluationReason TARGET_MATCH_INSTANCE = new EvaluationReason(Kind.TARGET_MATCH);
private static final EvaluationReason ERROR_CLIENT_NOT_READY = new EvaluationReason(ErrorKind.CLIENT_NOT_READY, null);
private static final EvaluationReason ERROR_FLAG_NOT_FOUND = new EvaluationReason(ErrorKind.FLAG_NOT_FOUND, null);
Expand All @@ -108,25 +112,31 @@ public static enum ErrorKind {
private final int ruleIndex;
private final String ruleId;
private final String prerequisiteKey;
private final boolean inExperiment;
private final ErrorKind errorKind;
private final Exception exception;

private EvaluationReason(Kind kind, int ruleIndex, String ruleId, String prerequisiteKey,
private EvaluationReason(Kind kind, int ruleIndex, String ruleId, String prerequisiteKey, boolean inExperiment,
ErrorKind errorKind, Exception exception) {
this.kind = kind;
this.ruleIndex = ruleIndex;
this.ruleId = ruleId;
this.prerequisiteKey = prerequisiteKey;
this.inExperiment = inExperiment;
this.errorKind = errorKind;
this.exception = exception;
}

private EvaluationReason(Kind kind) {
this(kind, -1, null, null, null, null);
this(kind, -1, null, null, NOT_IN_EXPERIMENT, null, null);
}

private EvaluationReason(Kind kind, boolean inExperiment) {
this(kind, -1, null, null, inExperiment, null, null);
}

private EvaluationReason(ErrorKind errorKind, Exception exception) {
this(Kind.ERROR, -1, null, null, errorKind, exception);
this(Kind.ERROR, -1, null, null, NOT_IN_EXPERIMENT, errorKind, exception);
}

/**
Expand Down Expand Up @@ -171,6 +181,17 @@ public String getPrerequisiteKey() {
return prerequisiteKey;
}

/**
* Whether the evaluation was part of an experiment. Returns true if the evaluation
* resulted in an experiment rollout *and* served one of the variations in the
* experiment. Otherwise it returns false.
*
* @return whether the evaluation was part of an experiment
*/
public boolean isInExperiment() {
return inExperiment;
}

/**
* An enumeration value indicating the general category of error, if the
* {@code kind} is {@link Kind#PREREQUISITE_FAILED}. Otherwise {@code null}.
Expand Down Expand Up @@ -223,16 +244,20 @@ public boolean equals(Object other) {
}
if (other instanceof EvaluationReason) {
EvaluationReason o = (EvaluationReason)other;
return kind == o.kind && ruleIndex == o.ruleIndex && Objects.equals(ruleId, o.ruleId)&&
Objects.equals(prerequisiteKey, o.prerequisiteKey) && Objects.equals(errorKind, o.errorKind) &&
Objects.equals(exception, o.exception);
return kind == o.kind &&
ruleIndex == o.ruleIndex &&
Objects.equals(ruleId, o.ruleId) &&
Objects.equals(prerequisiteKey, o.prerequisiteKey) &&
inExperiment == o.inExperiment &&
Objects.equals(errorKind, o.errorKind) &&
Objects.equals(exception, o.exception);
}
return false;
}

@Override
public int hashCode() {
return Objects.hash(kind, ruleIndex, ruleId, prerequisiteKey, errorKind, exception);
return Objects.hash(kind, ruleIndex, ruleId, prerequisiteKey, inExperiment, errorKind, exception);
}

/**
Expand All @@ -253,6 +278,18 @@ public static EvaluationReason fallthrough() {
return FALLTHROUGH_INSTANCE;
}

/**
* Returns an instance whose {@code kind} is {@link Kind#FALLTHROUGH} and
* where the inExperiment parameter represents whether the evaluation was
* part of an experiment.
*
* @param inExperiment whether the evaluation was part of an experiment
* @return a reason object
*/
public static EvaluationReason fallthrough(boolean inExperiment) {
return inExperiment ? FALLTHROUGH_INSTANCE_IN_EXPERIMENT : FALLTHROUGH_INSTANCE;
}

/**
* Returns an instance whose {@code kind} is {@link Kind#TARGET_MATCH}.
*
Expand All @@ -270,7 +307,21 @@ public static EvaluationReason targetMatch() {
* @return a reason object
*/
public static EvaluationReason ruleMatch(int ruleIndex, String ruleId) {
return new EvaluationReason(Kind.RULE_MATCH, ruleIndex, ruleId, null, null, null);
return ruleMatch(ruleIndex, ruleId, NOT_IN_EXPERIMENT);
}

/**
* Returns an instance whose {@code kind} is {@link Kind#RULE_MATCH} and
* where the inExperiment parameter represents whether the evaluation was
* part of an experiment.
*
* @param ruleIndex the rule index
* @param ruleId the rule identifier
* @param inExperiment whether the evaluation was part of an experiment
* @return a reason object
*/
public static EvaluationReason ruleMatch(int ruleIndex, String ruleId, boolean inExperiment) {
return new EvaluationReason(Kind.RULE_MATCH, ruleIndex, ruleId, null, inExperiment, null, null);
}

/**
Expand All @@ -280,7 +331,7 @@ public static EvaluationReason ruleMatch(int ruleIndex, String ruleId) {
* @return a reason object
*/
public static EvaluationReason prerequisiteFailed(String prerequisiteKey) {
return new EvaluationReason(Kind.PREREQUISITE_FAILED, -1, null, prerequisiteKey, null, null);
return new EvaluationReason(Kind.PREREQUISITE_FAILED, -1, null, prerequisiteKey, NOT_IN_EXPERIMENT, null, null);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ static EvaluationReason parse(JsonReader reader) throws IOException {
int ruleIndex = -1;
String ruleId = null;
String prereqKey = null;
boolean inExperiment = false;
EvaluationReason.ErrorKind errorKind = null;

reader.beginObject();
Expand All @@ -40,6 +41,9 @@ static EvaluationReason parse(JsonReader reader) throws IOException {
case "prerequisiteKey":
prereqKey = reader.nextString();
break;
case "inExperiment":
inExperiment = reader.nextBoolean();
break;
case "errorKind":
errorKind = readEnum(EvaluationReason.ErrorKind.class, reader);
break;
Expand All @@ -56,11 +60,11 @@ static EvaluationReason parse(JsonReader reader) throws IOException {
case OFF:
return EvaluationReason.off();
case FALLTHROUGH:
return EvaluationReason.fallthrough();
return EvaluationReason.fallthrough(inExperiment);
case TARGET_MATCH:
return EvaluationReason.targetMatch();
case RULE_MATCH:
return EvaluationReason.ruleMatch(ruleIndex, ruleId);
return EvaluationReason.ruleMatch(ruleIndex, ruleId, inExperiment);
case PREREQUISITE_FAILED:
return EvaluationReason.prerequisiteFailed(prereqKey);
case ERROR:
Expand All @@ -85,6 +89,16 @@ public void write(JsonWriter writer, EvaluationReason reason) throws IOException
writer.name("ruleId");
writer.value(reason.getRuleId());
}
if (reason.isInExperiment()) {
writer.name("inExperiment");
writer.value(reason.isInExperiment());
}
break;
case FALLTHROUGH:
if (reason.isInExperiment()) {
writer.name("inExperiment");
writer.value(reason.isInExperiment());
}
break;
case PREREQUISITE_FAILED:
writer.name("prerequisiteKey");
Expand Down
3 changes: 2 additions & 1 deletion src/test/java/com/launchdarkly/sdk/EvaluationReasonTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,11 @@ public void basicProperties() {
@Test
public void simpleStringRepresentations() {
assertEquals("OFF", EvaluationReason.off().toString());
assertEquals("FALLTHROUGH", EvaluationReason.fallthrough().toString());
assertEquals("TARGET_MATCH", EvaluationReason.targetMatch().toString());
assertEquals("RULE_MATCH(1)", EvaluationReason.ruleMatch(1, null).toString());
assertEquals("RULE_MATCH(1,id)", EvaluationReason.ruleMatch(1, "id").toString());
assertEquals("RULE_MATCH(1,id)", EvaluationReason.ruleMatch(1, "id", false).toString());
assertEquals("RULE_MATCH(1,id)", EvaluationReason.ruleMatch(1, "id", true).toString());
assertEquals("PREREQUISITE_FAILED(key)", EvaluationReason.prerequisiteFailed("key").toString());
assertEquals("ERROR(FLAG_NOT_FOUND)", EvaluationReason.error(FLAG_NOT_FOUND).toString());
assertEquals("ERROR(EXCEPTION)", EvaluationReason.exception(null).toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.junit.Test;

import static com.launchdarkly.sdk.json.JsonTestHelpers.verifyDeserializeInvalidJson;
import static com.launchdarkly.sdk.json.JsonTestHelpers.verifyDeserialize;
import static com.launchdarkly.sdk.json.JsonTestHelpers.verifySerialize;
import static com.launchdarkly.sdk.json.JsonTestHelpers.verifySerializeAndDeserialize;

Expand All @@ -15,16 +16,31 @@ public class EvaluationReasonJsonSerializationTest extends BaseTest {
public void reasonJsonSerializations() throws Exception {
verifySerializeAndDeserialize(EvaluationReason.off(), "{\"kind\":\"OFF\"}");
verifySerializeAndDeserialize(EvaluationReason.fallthrough(), "{\"kind\":\"FALLTHROUGH\"}");
verifySerializeAndDeserialize(EvaluationReason.fallthrough(false), "{\"kind\":\"FALLTHROUGH\"}");
verifySerializeAndDeserialize(EvaluationReason.fallthrough(true), "{\"kind\":\"FALLTHROUGH\",\"inExperiment\":true}");
verifySerializeAndDeserialize(EvaluationReason.targetMatch(), "{\"kind\":\"TARGET_MATCH\"}");
verifySerializeAndDeserialize(EvaluationReason.ruleMatch(1, "id"),
"{\"kind\":\"RULE_MATCH\",\"ruleIndex\":1,\"ruleId\":\"id\"}");
verifySerializeAndDeserialize(EvaluationReason.ruleMatch(1, "id", false),
"{\"kind\":\"RULE_MATCH\",\"ruleIndex\":1,\"ruleId\":\"id\"}");
verifySerializeAndDeserialize(EvaluationReason.ruleMatch(1, "id", true),
"{\"kind\":\"RULE_MATCH\",\"ruleIndex\":1,\"ruleId\":\"id\",\"inExperiment\":true}");
verifySerializeAndDeserialize(EvaluationReason.ruleMatch(1, null),
"{\"kind\":\"RULE_MATCH\",\"ruleIndex\":1}");
verifySerializeAndDeserialize(EvaluationReason.ruleMatch(1, null, false),
"{\"kind\":\"RULE_MATCH\",\"ruleIndex\":1}");
verifySerializeAndDeserialize(EvaluationReason.ruleMatch(1, null, true),
"{\"kind\":\"RULE_MATCH\",\"ruleIndex\":1,\"inExperiment\":true}");
verifySerializeAndDeserialize(EvaluationReason.prerequisiteFailed("key"),
"{\"kind\":\"PREREQUISITE_FAILED\",\"prerequisiteKey\":\"key\"}");
verifySerializeAndDeserialize(EvaluationReason.error(EvaluationReason.ErrorKind.FLAG_NOT_FOUND),
"{\"kind\":\"ERROR\",\"errorKind\":\"FLAG_NOT_FOUND\"}");

// properties with defaults can be included
verifyDeserialize(EvaluationReason.fallthrough(false), "{\"kind\":\"FALLTHROUGH\",\"inExperiment\":false}");
verifyDeserialize(EvaluationReason.ruleMatch(1, "id", false),
"{\"kind\":\"RULE_MATCH\",\"ruleIndex\":1,\"ruleId\":\"id\",\"inExperiment\":false}");

// unknown properties are ignored
JsonTestHelpers.verifyDeserialize(EvaluationReason.off(), "{\"kind\":\"OFF\",\"other\":true}");

Expand Down