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

Commit

Permalink
prepare 1.2.0 release (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
LaunchDarklyCI authored Jun 17, 2021
1 parent a0be198 commit 6ae5920
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 12 deletions.
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

0 comments on commit 6ae5920

Please sign in to comment.