Skip to content

feat: add "json" type to FeatureVariable #372

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -65,25 +65,30 @@ public static VariableStatus fromString(String variableStatusString) {
public static final String INTEGER_TYPE = "integer";
public static final String DOUBLE_TYPE = "double";
public static final String BOOLEAN_TYPE = "boolean";
public static final String JSON_TYPE = "json";

private final String id;
private final String key;
private final String defaultValue;
private final String type;
@Nullable
private final String subType; // this is for backward-compatibility (json type)
@Nullable
private final VariableStatus status;

@JsonCreator
public FeatureVariable(@JsonProperty("id") String id,
@JsonProperty("key") String key,
@JsonProperty("defaultValue") String defaultValue,
@JsonProperty("status") VariableStatus status,
@JsonProperty("type") String type) {
@JsonProperty("type") String type,
@JsonProperty("subType") String subType) {
this.id = id;
this.key = key;
this.defaultValue = defaultValue;
this.status = status;
this.type = type;
this.subType = subType;
}

@Nullable
Expand All @@ -104,6 +109,7 @@ public String getDefaultValue() {
}

public String getType() {
if (type.equals(STRING_TYPE) && subType != null && subType.equals(JSON_TYPE)) return JSON_TYPE;
return type;
}

Expand All @@ -114,6 +120,7 @@ public String toString() {
", key='" + key + '\'' +
", defaultValue='" + defaultValue + '\'' +
", type=" + type +
", subType=" + subType +
", status=" + status +
'}';
}
Expand All @@ -138,7 +145,8 @@ public int hashCode() {
result = 31 * result + key.hashCode();
result = 31 * result + defaultValue.hashCode();
result = 31 * result + type.hashCode();
result = 31 * result + status.hashCode();
result = 31 * result + (subType != null ? subType.hashCode() : 0);
result = 31 * result + (status != null ? status.hashCode() : 0);
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -345,12 +345,16 @@ private List<FeatureVariable> parseFeatureVariables(JSONArray featureVariablesJs
String key = FeatureVariableObject.getString("key");
String defaultValue = FeatureVariableObject.getString("defaultValue");
String type = FeatureVariableObject.getString("type");
String subType = null;
if (FeatureVariableObject.has("subType")) {
subType = FeatureVariableObject.getString("subType");
}
FeatureVariable.VariableStatus status = null;
if (FeatureVariableObject.has("status")) {
status = FeatureVariable.VariableStatus.fromString(FeatureVariableObject.getString("status"));
}

featureVariables.add(new FeatureVariable(id, key, defaultValue, status, type));
featureVariables.add(new FeatureVariable(id, key, defaultValue, status, type, subType));
}

return featureVariables;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,9 +335,10 @@ private List<FeatureVariable> parseFeatureVariables(JSONArray featureVariablesJs
String key = (String) featureVariableObject.get("key");
String defaultValue = (String) featureVariableObject.get("defaultValue");
String type = (String) featureVariableObject.get("type");
String subType = (String) featureVariableObject.get("subType");
VariableStatus status = VariableStatus.fromString((String) featureVariableObject.get("status"));

featureVariables.add(new FeatureVariable(id, key, defaultValue, status, type));
featureVariables.add(new FeatureVariable(id, key, defaultValue, status, type, subType));
}

return featureVariables;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,8 @@ public class ValidProjectConfigV4 {
VARIABLE_DOUBLE_VARIABLE_KEY,
VARIABLE_DOUBLE_DEFAULT_VALUE,
null,
FeatureVariable.DOUBLE_TYPE
FeatureVariable.DOUBLE_TYPE,
null
);
private static final String FEATURE_SINGLE_VARIABLE_INTEGER_ID = "3281420120";
public static final String FEATURE_SINGLE_VARIABLE_INTEGER_KEY = "integer_single_variable_feature";
Expand All @@ -259,7 +260,8 @@ public class ValidProjectConfigV4 {
VARIABLE_INTEGER_VARIABLE_KEY,
VARIABLE_INTEGER_DEFAULT_VALUE,
null,
FeatureVariable.INTEGER_TYPE
FeatureVariable.INTEGER_TYPE,
null
);
private static final String FEATURE_SINGLE_VARIABLE_BOOLEAN_ID = "2591051011";
public static final String FEATURE_SINGLE_VARIABLE_BOOLEAN_KEY = "boolean_single_variable_feature";
Expand All @@ -271,7 +273,8 @@ public class ValidProjectConfigV4 {
VARIABLE_BOOLEAN_VARIABLE_KEY,
VARIABLE_BOOLEAN_VARIABLE_DEFAULT_VALUE,
null,
FeatureVariable.BOOLEAN_TYPE
FeatureVariable.BOOLEAN_TYPE,
null
);
private static final FeatureFlag FEATURE_FLAG_SINGLE_VARIABLE_BOOLEAN = new FeatureFlag(
FEATURE_SINGLE_VARIABLE_BOOLEAN_ID,
Expand All @@ -292,7 +295,8 @@ public class ValidProjectConfigV4 {
VARIABLE_STRING_VARIABLE_KEY,
VARIABLE_STRING_VARIABLE_DEFAULT_VALUE,
null,
FeatureVariable.STRING_TYPE
FeatureVariable.STRING_TYPE,
null
);
private static final String ROLLOUT_1_ID = "1058508303";
private static final String ROLLOUT_1_EVERYONE_ELSE_EXPERIMENT_ID = "1785077004";
Expand Down Expand Up @@ -388,7 +392,8 @@ public class ValidProjectConfigV4 {
VARIABLE_FIRST_LETTER_KEY,
VARIABLE_FIRST_LETTER_DEFAULT_VALUE,
null,
FeatureVariable.STRING_TYPE
FeatureVariable.STRING_TYPE,
null
);
private static final String VARIABLE_REST_OF_NAME_ID = "4052219963";
private static final String VARIABLE_REST_OF_NAME_KEY = "rest_of_name";
Expand All @@ -398,17 +403,41 @@ public class ValidProjectConfigV4 {
VARIABLE_REST_OF_NAME_KEY,
VARIABLE_REST_OF_NAME_DEFAULT_VALUE,
null,
FeatureVariable.STRING_TYPE
FeatureVariable.STRING_TYPE,
null
);
private static final String VARIABLE_JSON_PATCHED_TYPE_ID = "4111661000";
private static final String VARIABLE_JSON_PATCHED_TYPE_KEY = "json_patched";
private static final String VARIABLE_JSON_PATCHED_TYPE_DEFAULT_VALUE = "{\"k1\":\"v1\",\"k2\":3.5,\"k3\":true,\"k4\":{\"kk1\":\"vv1\",\"kk2\":false}}";
private static final FeatureVariable VARIABLE_JSON_PATCHED_TYPE_VARIABLE = new FeatureVariable(
VARIABLE_JSON_PATCHED_TYPE_ID,
VARIABLE_JSON_PATCHED_TYPE_KEY,
VARIABLE_JSON_PATCHED_TYPE_DEFAULT_VALUE,
null,
FeatureVariable.STRING_TYPE,
FeatureVariable.JSON_TYPE
);
private static final String VARIABLE_JSON_NATIVE_TYPE_ID = "4111661001";
private static final String VARIABLE_JSON_NATIVE_TYPE_KEY = "json_native";
private static final String VARIABLE_JSON_NATIVE_TYPE_DEFAULT_VALUE = "{\"k1\":\"v1\",\"k2\":3.5,\"k3\":true,\"k4\":{\"kk1\":\"vv1\",\"kk2\":false}}";
private static final FeatureVariable VARIABLE_JSON_NATIVE_TYPE_VARIABLE = new FeatureVariable(
VARIABLE_JSON_NATIVE_TYPE_ID,
VARIABLE_JSON_NATIVE_TYPE_KEY,
VARIABLE_JSON_NATIVE_TYPE_DEFAULT_VALUE,
null,
FeatureVariable.JSON_TYPE,
null
);
private static final String VARIABLE_FUTURE_TYPE_ID = "4111661234";
private static final String VARIABLE_FUTURE_TYPE_ID = "4111661002";
private static final String VARIABLE_FUTURE_TYPE_KEY = "future_variable";
private static final String VARIABLE_FUTURE_TYPE_DEFAULT_VALUE = "future_value";
private static final FeatureVariable VARIABLE_FUTURE_TYPE_VARIABLE = new FeatureVariable(
VARIABLE_FUTURE_TYPE_ID,
VARIABLE_FUTURE_TYPE_KEY,
VARIABLE_FUTURE_TYPE_DEFAULT_VALUE,
null,
"future_type"
"future_type",
null
);
private static final String FEATURE_MUTEX_GROUP_FEATURE_ID = "3263342226";
public static final String FEATURE_MUTEX_GROUP_FEATURE_KEY = "mutex_group_feature";
Expand All @@ -420,7 +449,8 @@ public class ValidProjectConfigV4 {
VARIABLE_CORRELATING_VARIATION_NAME_KEY,
VARIABLE_CORRELATING_VARIATION_NAME_DEFAULT_VALUE,
null,
FeatureVariable.STRING_TYPE
FeatureVariable.STRING_TYPE,
null
);

// group IDs
Expand Down Expand Up @@ -733,6 +763,10 @@ public class ValidProjectConfigV4 {
new FeatureVariableUsageInstance(
VARIABLE_REST_OF_NAME_ID,
"red"
),
new FeatureVariableUsageInstance(
VARIABLE_JSON_PATCHED_TYPE_ID,
"{\"k1\":\"s1\",\"k2\":103.5,\"k3\":false,\"k4\":{\"kk1\":\"ss1\",\"kk2\":true}}"
)
)
);
Expand All @@ -750,6 +784,10 @@ public class ValidProjectConfigV4 {
new FeatureVariableUsageInstance(
VARIABLE_REST_OF_NAME_ID,
"eorge"
),
new FeatureVariableUsageInstance(
VARIABLE_JSON_PATCHED_TYPE_ID,
"{\"k1\":\"s2\",\"k2\":203.5,\"k3\":true,\"k4\":{\"kk1\":\"ss2\",\"kk2\":true}}"
)
)
);
Expand All @@ -768,6 +806,10 @@ public class ValidProjectConfigV4 {
new FeatureVariableUsageInstance(
VARIABLE_REST_OF_NAME_ID,
"red"
),
new FeatureVariableUsageInstance(
VARIABLE_JSON_PATCHED_TYPE_ID,
"{\"k1\":\"s3\",\"k2\":303.5,\"k3\":true,\"k4\":{\"kk1\":\"ss3\",\"kk2\":false}}"
)
)
);
Expand All @@ -785,6 +827,10 @@ public class ValidProjectConfigV4 {
new FeatureVariableUsageInstance(
VARIABLE_REST_OF_NAME_ID,
"eorge"
),
new FeatureVariableUsageInstance(
VARIABLE_JSON_PATCHED_TYPE_ID,
"{\"k1\":\"s4\",\"k2\":403.5,\"k3\":false,\"k4\":{\"kk1\":\"ss4\",\"kk2\":true}}"
)
)
);
Expand Down Expand Up @@ -1262,6 +1308,8 @@ public class ValidProjectConfigV4 {
DatafileProjectConfigTestUtils.createListOfObjects(
VARIABLE_FIRST_LETTER_VARIABLE,
VARIABLE_REST_OF_NAME_VARIABLE,
VARIABLE_JSON_PATCHED_TYPE_VARIABLE,
VARIABLE_JSON_NATIVE_TYPE_VARIABLE,
VARIABLE_FUTURE_TYPE_VARIABLE
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.optimizely.ab.config.FeatureFlag;
import com.optimizely.ab.config.FeatureVariable;
import com.optimizely.ab.config.ProjectConfig;
import com.optimizely.ab.config.audience.Audience;
import com.optimizely.ab.config.audience.Condition;
Expand All @@ -42,6 +44,7 @@
import static com.optimizely.ab.config.DatafileProjectConfigTestUtils.validProjectConfigV3;
import static com.optimizely.ab.config.DatafileProjectConfigTestUtils.validProjectConfigV4;
import static com.optimizely.ab.config.DatafileProjectConfigTestUtils.verifyProjectConfig;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

/**
Expand Down Expand Up @@ -92,6 +95,45 @@ public void parseNullFeatureEnabledProjectConfigV4() throws Exception {

}

@Test
public void parseFeatureVariablesWithJsonPatched() throws Exception {
JsonSimpleConfigParser parser = new JsonSimpleConfigParser();
ProjectConfig actual = parser.parseProjectConfig(validConfigJsonV4());

// "string" type + "json" subType

FeatureFlag featureFlag = actual.getFeatureKeyMapping().get("multi_variate_feature");
FeatureVariable variable = featureFlag.getVariableKeyToFeatureVariableMap().get("json_patched");

assertEquals(variable.getType(), "json");
}

@Test
public void parseFeatureVariablesWithJsonNative() throws Exception {
JsonSimpleConfigParser parser = new JsonSimpleConfigParser();
ProjectConfig actual = parser.parseProjectConfig(validConfigJsonV4());

// native "json" type

FeatureFlag featureFlag = actual.getFeatureKeyMapping().get("multi_variate_feature");
FeatureVariable variable = featureFlag.getVariableKeyToFeatureVariableMap().get("json_native");

assertEquals(variable.getType(), "json");
}

@Test
public void parseFeatureVariablesWithFutureType() throws Exception {
JsonSimpleConfigParser parser = new JsonSimpleConfigParser();
ProjectConfig actual = parser.parseProjectConfig(validConfigJsonV4());

// unknown type

FeatureFlag featureFlag = actual.getFeatureKeyMapping().get("multi_variate_feature");
FeatureVariable variable = featureFlag.getVariableKeyToFeatureVariableMap().get("future_variable");

assertEquals(variable.getType(), "future_type");
}

@Test
public void parseAudience() throws Exception {
JsonObject jsonObject = new JsonObject();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.optimizely.ab.config.FeatureFlag;
import com.optimizely.ab.config.FeatureVariable;
import com.optimizely.ab.config.ProjectConfig;
import com.optimizely.ab.config.audience.Audience;
import com.optimizely.ab.config.audience.Condition;
Expand All @@ -36,6 +38,7 @@
import static com.optimizely.ab.config.DatafileProjectConfigTestUtils.validProjectConfigV3;
import static com.optimizely.ab.config.DatafileProjectConfigTestUtils.validProjectConfigV4;
import static com.optimizely.ab.config.DatafileProjectConfigTestUtils.verifyProjectConfig;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

/**
Expand Down Expand Up @@ -86,6 +89,44 @@ public void parseNullFeatureEnabledProjectConfigV4() throws Exception {

}

@Test
public void parseFeatureVariablesWithJsonPatched() throws Exception {
JsonSimpleConfigParser parser = new JsonSimpleConfigParser();
ProjectConfig actual = parser.parseProjectConfig(validConfigJsonV4());

// "string" type + "json" subType

FeatureFlag featureFlag = actual.getFeatureKeyMapping().get("multi_variate_feature");
FeatureVariable variable = featureFlag.getVariableKeyToFeatureVariableMap().get("json_patched");

assertEquals(variable.getType(), "json");
}

@Test
public void parseFeatureVariablesWithJsonNative() throws Exception {
JsonSimpleConfigParser parser = new JsonSimpleConfigParser();
ProjectConfig actual = parser.parseProjectConfig(validConfigJsonV4());

// native "json" type

FeatureFlag featureFlag = actual.getFeatureKeyMapping().get("multi_variate_feature");
FeatureVariable variable = featureFlag.getVariableKeyToFeatureVariableMap().get("json_native");

assertEquals(variable.getType(), "json");
}

@Test
public void parseFeatureVariablesWithFutureType() throws Exception {
JsonSimpleConfigParser parser = new JsonSimpleConfigParser();
ProjectConfig actual = parser.parseProjectConfig(validConfigJsonV4());

// unknown type

FeatureFlag featureFlag = actual.getFeatureKeyMapping().get("multi_variate_feature");
FeatureVariable variable = featureFlag.getVariableKeyToFeatureVariableMap().get("future_variable");

assertEquals(variable.getType(), "future_type");
}

@Test
public void parseAudience() throws Exception {
Expand Down
Loading