Skip to content

Commit 6b1c7f7

Browse files
committed
Add GsonParser for FeatureFlags
Fix GsonParsing of FeatureFlags
1 parent a8c0dc5 commit 6b1c7f7

File tree

6 files changed

+96
-13
lines changed

6 files changed

+96
-13
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public String toString() {
7575
", layerId='" + layerId + '\'' +
7676
", experimentIds=" + experimentIds +
7777
", variables=" + variables +
78+
", variableKeyToLiveVariableMap=" + variableKeyToLiveVariableMap +
7879
'}';
7980
}
8081

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
*
3+
* Copyright 2017, Optimizely and contributors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.optimizely.ab.config.parser;
18+
19+
import com.google.gson.JsonDeserializationContext;
20+
import com.google.gson.JsonDeserializer;
21+
import com.google.gson.JsonElement;
22+
import com.google.gson.JsonObject;
23+
import com.google.gson.JsonParseException;
24+
import com.optimizely.ab.config.FeatureFlag;
25+
26+
import java.lang.reflect.Type;
27+
28+
public class FeatureFlagGsonDeserializer implements JsonDeserializer<FeatureFlag> {
29+
@Override
30+
public FeatureFlag deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
31+
throws JsonParseException {
32+
33+
JsonObject jsonObject = json.getAsJsonObject();
34+
return GsonHelpers.parseFeatureFlag(jsonObject, context);
35+
}
36+
}

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818

1919
import com.google.gson.Gson;
2020
import com.google.gson.GsonBuilder;
21-
2221
import com.optimizely.ab.config.Experiment;
22+
import com.optimizely.ab.config.FeatureFlag;
2323
import com.optimizely.ab.config.Group;
24-
import com.optimizely.ab.config.audience.Audience;
2524
import com.optimizely.ab.config.ProjectConfig;
25+
import com.optimizely.ab.config.audience.Audience;
2626

2727
import javax.annotation.Nonnull;
2828

@@ -40,11 +40,12 @@ public ProjectConfig parseProjectConfig(@Nonnull String json) throws ConfigParse
4040
throw new ConfigParseException("Unable to parse empty json.");
4141
}
4242
Gson gson = new GsonBuilder()
43-
.registerTypeAdapter(ProjectConfig.class, new ProjectConfigGsonDeserializer())
44-
.registerTypeAdapter(Audience.class, new AudienceGsonDeserializer())
45-
.registerTypeAdapter(Group.class, new GroupGsonDeserializer())
46-
.registerTypeAdapter(Experiment.class, new ExperimentGsonDeserializer())
47-
.create();
43+
.registerTypeAdapter(Audience.class, new AudienceGsonDeserializer())
44+
.registerTypeAdapter(Experiment.class, new ExperimentGsonDeserializer())
45+
.registerTypeAdapter(FeatureFlag.class, new FeatureFlagGsonDeserializer())
46+
.registerTypeAdapter(Group.class, new GroupGsonDeserializer())
47+
.registerTypeAdapter(ProjectConfig.class, new ProjectConfigGsonDeserializer())
48+
.create();
4849

4950
try {
5051
return gson.fromJson(json, ProjectConfig.class);

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,18 @@
2121
import com.google.gson.JsonElement;
2222
import com.google.gson.JsonObject;
2323
import com.google.gson.reflect.TypeToken;
24-
2524
import com.optimizely.ab.config.Experiment;
2625
import com.optimizely.ab.config.Experiment.ExperimentStatus;
26+
import com.optimizely.ab.config.FeatureFlag;
27+
import com.optimizely.ab.config.LiveVariable;
2728
import com.optimizely.ab.config.LiveVariableUsageInstance;
2829
import com.optimizely.ab.config.TrafficAllocation;
2930
import com.optimizely.ab.config.Variation;
3031

3132
import java.lang.reflect.Type;
3233
import java.util.ArrayList;
33-
import java.util.List;
3434
import java.util.HashMap;
35+
import java.util.List;
3536
import java.util.Map;
3637
import java.util.Set;
3738

@@ -114,4 +115,28 @@ static Experiment parseExperiment(JsonObject experimentJson, String groupId, Jso
114115
static Experiment parseExperiment(JsonObject experimentJson, JsonDeserializationContext context) {
115116
return parseExperiment(experimentJson, "", context);
116117
}
118+
119+
static FeatureFlag parseFeatureFlag(JsonObject featureFlagJson, JsonDeserializationContext context) {
120+
String id = featureFlagJson.get("id").getAsString();
121+
String key = featureFlagJson.get("key").getAsString();
122+
String layerId = featureFlagJson.get("layerId").getAsString();
123+
124+
JsonArray experimentIdsJson = featureFlagJson.getAsJsonArray("experimentIds");
125+
List<String> experimentIds = new ArrayList<String>();
126+
for (JsonElement experimentIdObj : experimentIdsJson) {
127+
experimentIds.add(experimentIdObj.getAsString());
128+
}
129+
130+
Type liveVariableType = new TypeToken<List<LiveVariable>>() {}.getType();
131+
List<LiveVariable> liveVariables = context.deserialize(featureFlagJson.getAsJsonArray("variables"),
132+
liveVariableType);
133+
134+
return new FeatureFlag(
135+
id,
136+
key,
137+
layerId,
138+
experimentIds,
139+
liveVariables
140+
);
141+
}
117142
}

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

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.optimizely.ab.config.Attribute;
2626
import com.optimizely.ab.config.EventType;
2727
import com.optimizely.ab.config.Experiment;
28+
import com.optimizely.ab.config.FeatureFlag;
2829
import com.optimizely.ab.config.Group;
2930
import com.optimizely.ab.config.LiveVariable;
3031
import com.optimizely.ab.config.ProjectConfig;
@@ -47,6 +48,7 @@ public ProjectConfig deserialize(JsonElement json, Type typeOfT, JsonDeserializa
4748
String projectId = jsonObject.get("projectId").getAsString();
4849
String revision = jsonObject.get("revision").getAsString();
4950
String version = jsonObject.get("version").getAsString();
51+
int datafileVersion = Integer.parseInt(version);
5052

5153
// generic list type tokens
5254
Type groupsType = new TypeToken<List<Group>>() {}.getType();
@@ -70,14 +72,32 @@ public ProjectConfig deserialize(JsonElement json, Type typeOfT, JsonDeserializa
7072
boolean anonymizeIP = false;
7173
// live variables should be null if using V2
7274
List<LiveVariable> liveVariables = null;
73-
if (version.equals(ProjectConfig.Version.V3.toString())) {
75+
if (datafileVersion >= 3) {
7476
Type liveVariablesType = new TypeToken<List<LiveVariable>>() {}.getType();
7577
liveVariables = context.deserialize(jsonObject.getAsJsonArray("variables"), liveVariablesType);
7678

7779
anonymizeIP = jsonObject.get("anonymizeIP").getAsBoolean();
7880
}
7981

80-
return new ProjectConfig(accountId, projectId, version, revision, groups, experiments, attributes, events,
81-
audiences, anonymizeIP, liveVariables);
82+
List<FeatureFlag> featureFlags = null;
83+
if (datafileVersion >= 4) {
84+
Type featureFlagsType = new TypeToken<List<FeatureFlag>>() {}.getType();
85+
featureFlags = context.deserialize(jsonObject.getAsJsonArray("featureFlags"), featureFlagsType);
86+
}
87+
88+
return new ProjectConfig(
89+
accountId,
90+
anonymizeIP,
91+
projectId,
92+
revision,
93+
version,
94+
attributes,
95+
audiences,
96+
events,
97+
experiments,
98+
featureFlags,
99+
groups,
100+
liveVariables
101+
);
82102
}
83103
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public void parseProjectConfigV3() throws Exception {
5757
}
5858

5959
@Test
60-
public void parseProjectCOnfigV4() throws Exception {
60+
public void parseProjectConfigV4() throws Exception {
6161
GsonConfigParser parser = new GsonConfigParser();
6262
ProjectConfig actual = parser.parseProjectConfig(validConfigJsonV4());
6363
ProjectConfig expected = validProjectConfigV4();

0 commit comments

Comments
 (0)