Skip to content

Commit 5a8f307

Browse files
[AI-FSSDK] [FSSDK-12418] Remove experiment type validation from config parsing
1 parent e3e689e commit 5a8f307

File tree

6 files changed

+38
-93
lines changed

6 files changed

+38
-93
lines changed

core-api/src/main/java/com/optimizely/ab/config/parser/DatafileGsonDeserializer.java

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -126,28 +126,6 @@ public ProjectConfig deserialize(JsonElement json, Type typeOfT, JsonDeserializa
126126
region = jsonObject.get("region").getAsString();
127127
}
128128

129-
// Validate experiment types
130-
Set<String> validExperimentTypes = new HashSet<>(Arrays.asList(
131-
Experiment.TYPE_AB, Experiment.TYPE_MAB, Experiment.TYPE_CMAB,
132-
Experiment.TYPE_TD, Experiment.TYPE_FR
133-
));
134-
for (Experiment experiment : experiments) {
135-
if (experiment.getType() != null && !validExperimentTypes.contains(experiment.getType())) {
136-
throw new JsonParseException(
137-
String.format("Experiment \"%s\" has invalid type \"%s\". Valid types: %s.",
138-
experiment.getKey(), experiment.getType(), validExperimentTypes));
139-
}
140-
}
141-
for (Group group : groups) {
142-
for (Experiment experiment : group.getExperiments()) {
143-
if (experiment.getType() != null && !validExperimentTypes.contains(experiment.getType())) {
144-
throw new JsonParseException(
145-
String.format("Experiment \"%s\" has invalid type \"%s\". Valid types: %s.",
146-
experiment.getKey(), experiment.getType(), validExperimentTypes));
147-
}
148-
}
149-
}
150-
151129
return new DatafileProjectConfig(
152130
accountId,
153131
anonymizeIP,

core-api/src/main/java/com/optimizely/ab/config/parser/DatafileJacksonDeserializer.java

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -100,28 +100,6 @@ public DatafileProjectConfig deserialize(JsonParser parser, DeserializationConte
100100
region = node.get("region").textValue();
101101
}
102102

103-
// Validate experiment types
104-
Set<String> validExperimentTypes = new HashSet<>(Arrays.asList(
105-
Experiment.TYPE_AB, Experiment.TYPE_MAB, Experiment.TYPE_CMAB,
106-
Experiment.TYPE_TD, Experiment.TYPE_FR
107-
));
108-
for (Experiment experiment : experiments) {
109-
if (experiment.getType() != null && !validExperimentTypes.contains(experiment.getType())) {
110-
throw new IOException(
111-
String.format("Experiment \"%s\" has invalid type \"%s\". Valid types: %s.",
112-
experiment.getKey(), experiment.getType(), validExperimentTypes));
113-
}
114-
}
115-
for (Group group : groups) {
116-
for (Experiment experiment : group.getExperiments()) {
117-
if (experiment.getType() != null && !validExperimentTypes.contains(experiment.getType())) {
118-
throw new IOException(
119-
String.format("Experiment \"%s\" has invalid type \"%s\". Valid types: %s.",
120-
experiment.getKey(), experiment.getType(), validExperimentTypes));
121-
}
122-
}
123-
}
124-
125103
return new DatafileProjectConfig(
126104
accountId,
127105
anonymizeIP,

core-api/src/main/java/com/optimizely/ab/config/parser/JsonConfigParser.java

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -105,28 +105,6 @@ public ProjectConfig parseProjectConfig(@Nonnull String json) throws ConfigParse
105105
String regionString = rootObject.getString("region");
106106
}
107107

108-
// Validate experiment types
109-
Set<String> validExperimentTypes = new HashSet<>(Arrays.asList(
110-
Experiment.TYPE_AB, Experiment.TYPE_MAB, Experiment.TYPE_CMAB,
111-
Experiment.TYPE_TD, Experiment.TYPE_FR
112-
));
113-
for (Experiment experiment : experiments) {
114-
if (experiment.getType() != null && !validExperimentTypes.contains(experiment.getType())) {
115-
throw new ConfigParseException(
116-
String.format("Experiment \"%s\" has invalid type \"%s\". Valid types: %s.",
117-
experiment.getKey(), experiment.getType(), validExperimentTypes));
118-
}
119-
}
120-
for (Group group : groups) {
121-
for (Experiment experiment : group.getExperiments()) {
122-
if (experiment.getType() != null && !validExperimentTypes.contains(experiment.getType())) {
123-
throw new ConfigParseException(
124-
String.format("Experiment \"%s\" has invalid type \"%s\". Valid types: %s.",
125-
experiment.getKey(), experiment.getType(), validExperimentTypes));
126-
}
127-
}
128-
}
129-
130108
return new DatafileProjectConfig(
131109
accountId,
132110
anonymizeIP,
@@ -149,8 +127,6 @@ public ProjectConfig parseProjectConfig(@Nonnull String json) throws ConfigParse
149127
rollouts,
150128
integrations
151129
);
152-
} catch (ConfigParseException e) {
153-
throw e;
154130
} catch (RuntimeException e) {
155131
throw new ConfigParseException("Unable to parse datafile: " + json, e);
156132
} catch (Exception e) {

core-api/src/main/java/com/optimizely/ab/config/parser/JsonSimpleConfigParser.java

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -108,28 +108,6 @@ public ProjectConfig parseProjectConfig(@Nonnull String json) throws ConfigParse
108108
String regionString = (String) rootObject.get("region");
109109
}
110110

111-
// Validate experiment types
112-
Set<String> validExperimentTypes = new HashSet<>(Arrays.asList(
113-
Experiment.TYPE_AB, Experiment.TYPE_MAB, Experiment.TYPE_CMAB,
114-
Experiment.TYPE_TD, Experiment.TYPE_FR
115-
));
116-
for (Experiment experiment : experiments) {
117-
if (experiment.getType() != null && !validExperimentTypes.contains(experiment.getType())) {
118-
throw new ConfigParseException(
119-
String.format("Experiment \"%s\" has invalid type \"%s\". Valid types: %s.",
120-
experiment.getKey(), experiment.getType(), validExperimentTypes));
121-
}
122-
}
123-
for (Group group : groups) {
124-
for (Experiment experiment : group.getExperiments()) {
125-
if (experiment.getType() != null && !validExperimentTypes.contains(experiment.getType())) {
126-
throw new ConfigParseException(
127-
String.format("Experiment \"%s\" has invalid type \"%s\". Valid types: %s.",
128-
experiment.getKey(), experiment.getType(), validExperimentTypes));
129-
}
130-
}
131-
}
132-
133111
return new DatafileProjectConfig(
134112
accountId,
135113
anonymizeIP,
@@ -152,8 +130,6 @@ public ProjectConfig parseProjectConfig(@Nonnull String json) throws ConfigParse
152130
rollouts,
153131
integrations
154132
);
155-
} catch (ConfigParseException e) {
156-
throw e;
157133
} catch (RuntimeException ex) {
158134
throw new ConfigParseException("Unable to parse datafile: " + json, ex);
159135
} catch (Exception e) {

core-api/src/test/java/com/optimizely/ab/config/FeatureRolloutConfigTest.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,22 @@ public void featureRolloutWithEmptyRolloutIdDoesNotCrash() {
135135
}
136136

137137
/**
138-
* Test 6: Type field parsed - experiments with type field in the datafile
138+
* Test 6: Unknown type accepted - experiment with type "new_unknown_type"
139+
* does NOT cause error or rejection, and config parsing succeeds.
140+
*/
141+
@Test
142+
public void unknownExperimentTypeAccepted() {
143+
Experiment experiment = projectConfig.getExperimentKeyMapping().get("unknown_type_experiment");
144+
assertNotNull("Experiment with unknown type should be parsed successfully", experiment);
145+
assertEquals("new_unknown_type", experiment.getType());
146+
assertEquals("exp_unknown_type", experiment.getId());
147+
assertEquals("unknown_type_experiment", experiment.getKey());
148+
assertEquals(1, experiment.getVariations().size());
149+
assertEquals("unknown_variation", experiment.getVariations().get(0).getKey());
150+
}
151+
152+
/**
153+
* Test 7: Type field parsed - experiments with type field in the datafile
139154
* have the value correctly preserved after config parsing.
140155
*/
141156
@Test

core-api/src/test/resources/config/feature-rollout-config.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,28 @@
110110
"endOfRange": 5000
111111
}
112112
]
113+
},
114+
{
115+
"id": "exp_unknown_type",
116+
"key": "unknown_type_experiment",
117+
"status": "Running",
118+
"layerId": "layer_5",
119+
"audienceIds": [],
120+
"forcedVariations": {},
121+
"type": "new_unknown_type",
122+
"variations": [
123+
{
124+
"id": "var_unknown_1",
125+
"key": "unknown_variation",
126+
"featureEnabled": true
127+
}
128+
],
129+
"trafficAllocation": [
130+
{
131+
"entityId": "var_unknown_1",
132+
"endOfRange": 10000
133+
}
134+
]
113135
}
114136
],
115137
"featureFlags": [

0 commit comments

Comments
 (0)