Skip to content

Commit ca9c039

Browse files
add support for getParsedJSONAssignment method returning JsonNode (FF-896) (#26)
* add support for getParsedJSONAssignment method returning JsonNode (FF-896) * fix comment
1 parent 48e33c7 commit ca9c039

File tree

3 files changed

+87
-53
lines changed

3 files changed

+87
-53
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>cloud.eppo</groupId>
88
<artifactId>eppo-server-sdk</artifactId>
9-
<version>2.0.2</version>
9+
<version>2.1.0</version>
1010

1111
<name>${project.groupId}:${project.artifactId}</name>
1212
<description>Eppo Server-Side SDK for Java</description>

src/main/java/com/eppo/sdk/EppoClient.java

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.eppo.sdk.helpers.InputValidator;
2323
import com.eppo.sdk.helpers.RuleValidator;
2424
import com.eppo.sdk.helpers.Shard;
25+
import com.fasterxml.jackson.databind.JsonNode;
2526

2627
import lombok.extern.slf4j.Slf4j;
2728

@@ -60,8 +61,7 @@ private EppoClient(ConfigurationStore configurationStore, Timer poller, EppoClie
6061
private Optional<EppoValue> getAssignmentValue(
6162
String subjectKey,
6263
String flagKey,
63-
SubjectAttributes subjectAttributes
64-
) {
64+
SubjectAttributes subjectAttributes) {
6565
// Validate Input Values
6666
InputValidator.validateNotBlank(subjectKey, "Invalid argument: subjectKey cannot be blank");
6767
InputValidator.validateNotBlank(flagKey, "Invalid argument: flagKey cannot be blank");
@@ -142,6 +142,8 @@ private Optional<?> getTypedAssignment(String subjectKey, String experimentKey,
142142
return Optional.of(value.get().boolValue());
143143
case NUMBER:
144144
return Optional.of(value.get().doubleValue());
145+
case JSON_NODE:
146+
return Optional.of(value.get().jsonNodeValue());
145147
default:
146148
return Optional.of(value.get().stringValue());
147149
}
@@ -258,7 +260,7 @@ public Optional<Double> getDoubleAssignment(String subjectKey, String experiment
258260
* @param subjectAttributes
259261
* @return
260262
*/
261-
public Optional<String> getJSONAssignment(String subjectKey, String experimentKey,
263+
public Optional<String> getJSONStringAssignment(String subjectKey, String experimentKey,
262264
SubjectAttributes subjectAttributes) {
263265
return this.getStringAssignment(subjectKey, experimentKey, subjectAttributes);
264266
}
@@ -271,8 +273,34 @@ public Optional<String> getJSONAssignment(String subjectKey, String experimentKe
271273
* @param experimentKey
272274
* @return
273275
*/
274-
public Optional<String> getJSONAssignment(String subjectKey, String experimentKey) {
275-
return this.getJSONAssignment(subjectKey, experimentKey, new SubjectAttributes());
276+
public Optional<String> getJSONStringAssignment(String subjectKey, String experimentKey) {
277+
return this.getJSONStringAssignment(subjectKey, experimentKey, new SubjectAttributes());
278+
}
279+
280+
/**
281+
* This function will return JSON assignment value
282+
*
283+
* @param subjectKey
284+
* @param experimentKey
285+
* @param subjectAttributes
286+
* @return
287+
*/
288+
public Optional<JsonNode> getParsedJSONAssignment(String subjectKey, String experimentKey,
289+
SubjectAttributes subjectAttributes) {
290+
return (Optional<JsonNode>) this.getTypedAssignment(subjectKey, experimentKey, EppoValueType.JSON_NODE,
291+
subjectAttributes);
292+
}
293+
294+
/**
295+
* This function will return JSON assignment value without passing
296+
* subjectAttributes
297+
*
298+
* @param subjectKey
299+
* @param experimentKey
300+
* @return
301+
*/
302+
public Optional<JsonNode> getParsedJSONAssignment(String subjectKey, String experimentKey) {
303+
return this.getParsedJSONAssignment(subjectKey, experimentKey, new SubjectAttributes());
276304
}
277305

278306
/**

src/test/java/com/eppo/sdk/EppoClientTest.java

Lines changed: 53 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
import com.eppo.sdk.dto.*;
1313
import com.eppo.sdk.helpers.Converter;
14-
import com.fasterxml.jackson.core.JacksonException;
1514
import com.fasterxml.jackson.core.JsonParser;
1615
import com.fasterxml.jackson.databind.*;
1716
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
@@ -31,7 +30,6 @@
3130

3231
import lombok.Data;
3332

34-
3533
@ExtendWith(WireMockExtension.class)
3634
public class EppoClientTest {
3735

@@ -120,23 +118,24 @@ public AssignmentValueType deserialize(JsonParser jsonParser, DeserializationCon
120118
void init() {
121119
setupMockRacServer();
122120
EppoClientConfig config = EppoClientConfig.builder()
123-
.apiKey("mock-api-key")
124-
.baseURL("http://localhost:4001")
125-
.assignmentLogger(new IAssignmentLogger() {
126-
@Override
127-
public void logAssignment(AssignmentLogData logData) {
128-
// Auto-generated method stub
129-
}
130-
})
131-
.build();
121+
.apiKey("mock-api-key")
122+
.baseURL("http://localhost:4001")
123+
.assignmentLogger(new IAssignmentLogger() {
124+
@Override
125+
public void logAssignment(AssignmentLogData logData) {
126+
// Auto-generated method stub
127+
}
128+
})
129+
.build();
132130
EppoClient.init(config);
133131
}
134132

135133
private void setupMockRacServer() {
136134
this.mockServer = new WireMockServer(TEST_PORT);
137135
this.mockServer.start();
138136
String racResponseJson = getMockRandomizedAssignmentResponse();
139-
this.mockServer.stubFor(WireMock.get(WireMock.urlMatching(".*randomized_assignment.*")).willReturn(WireMock.okJson(racResponseJson)));
137+
this.mockServer.stubFor(
138+
WireMock.get(WireMock.urlMatching(".*randomized_assignment.*")).willReturn(WireMock.okJson(racResponseJson)));
140139
}
141140

142141
@AfterEach
@@ -159,8 +158,14 @@ void testAssignments(AssignmentTestCase testCase) throws IOException {
159158
assertEquals(expectedBooleanAssignments, actualBooleanAssignments);
160159
break;
161160
case JSON:
162-
List<String> actualJSONAssignments = this.getJSONAssignments(testCase);
163-
assertEquals(testCase.expectedAssignments, actualJSONAssignments);
161+
List<JsonNode> actualJSONAssignments = this.getJSONAssignments(testCase);
162+
for (JsonNode node : actualJSONAssignments) {
163+
assertEquals(JsonNodeType.OBJECT, node.getNodeType());
164+
}
165+
166+
assertEquals(testCase.expectedAssignments, actualJSONAssignments.stream()
167+
.map(node -> node.toString())
168+
.collect(Collectors.toList()));
164169
break;
165170
default:
166171
List<String> actualStringAssignments = this.getStringAssignments(testCase);
@@ -173,48 +178,49 @@ private List<?> getAssignments(AssignmentTestCase testCase, AssignmentValueType
173178
EppoClient client = EppoClient.getInstance();
174179
if (testCase.subjectsWithAttributes != null) {
175180
return testCase.subjectsWithAttributes.stream()
181+
.map(subject -> {
182+
try {
183+
switch (valueType) {
184+
case NUMERIC:
185+
return client.getDoubleAssignment(subject.subjectKey, testCase.experiment, subject.subjectAttributes)
186+
.orElse(null);
187+
case BOOLEAN:
188+
return client.getBooleanAssignment(subject.subjectKey, testCase.experiment, subject.subjectAttributes)
189+
.orElse(null);
190+
case JSON:
191+
return client
192+
.getParsedJSONAssignment(subject.subjectKey, testCase.experiment, subject.subjectAttributes)
193+
.orElse(null);
194+
default:
195+
return client.getStringAssignment(subject.subjectKey, testCase.experiment, subject.subjectAttributes)
196+
.orElse(null);
197+
}
198+
} catch (Exception e) {
199+
throw new RuntimeException(e);
200+
}
201+
}).collect(Collectors.toList());
202+
}
203+
return testCase.subjects.stream()
176204
.map(subject -> {
177205
try {
178206
switch (valueType) {
179207
case NUMERIC:
180-
return client.getDoubleAssignment(subject.subjectKey, testCase.experiment, subject.subjectAttributes)
181-
.orElse(null);
208+
return client.getDoubleAssignment(subject, testCase.experiment)
209+
.orElse(null);
182210
case BOOLEAN:
183-
return client.getBooleanAssignment(subject.subjectKey, testCase.experiment, subject.subjectAttributes)
184-
.orElse(null);
211+
return client.getBooleanAssignment(subject, testCase.experiment)
212+
.orElse(null);
185213
case JSON:
186-
return client.getJSONAssignment(subject.subjectKey, testCase.experiment, subject.subjectAttributes)
187-
.orElse(null);
214+
return client.getParsedJSONAssignment(subject, testCase.experiment)
215+
.orElse(null);
188216
default:
189-
return client.getStringAssignment(subject.subjectKey, testCase.experiment, subject.subjectAttributes)
190-
.orElse(null);
217+
return client.getStringAssignment(subject, testCase.experiment)
218+
.orElse(null);
191219
}
192220
} catch (Exception e) {
193221
throw new RuntimeException(e);
194222
}
195223
}).collect(Collectors.toList());
196-
}
197-
return testCase.subjects.stream()
198-
.map(subject -> {
199-
try {
200-
switch (valueType) {
201-
case NUMERIC:
202-
return client.getDoubleAssignment(subject, testCase.experiment)
203-
.orElse(null);
204-
case BOOLEAN:
205-
return client.getBooleanAssignment(subject, testCase.experiment)
206-
.orElse(null);
207-
case JSON:
208-
return client.getJSONAssignment(subject, testCase.experiment)
209-
.orElse(null);
210-
default:
211-
return client.getStringAssignment(subject, testCase.experiment)
212-
.orElse(null);
213-
}
214-
} catch (Exception e) {
215-
throw new RuntimeException(e);
216-
}
217-
}).collect(Collectors.toList());
218224
}
219225

220226
private List<String> getStringAssignments(AssignmentTestCase testCase) {
@@ -229,8 +235,8 @@ private List<Boolean> getBooleanAssignments(AssignmentTestCase testCase) {
229235
return (List<Boolean>) this.getAssignments(testCase, AssignmentValueType.BOOLEAN);
230236
}
231237

232-
private List<String> getJSONAssignments(AssignmentTestCase testCase) {
233-
return (List<String>) this.getAssignments(testCase, AssignmentValueType.JSON);
238+
private List<JsonNode> getJSONAssignments(AssignmentTestCase testCase) {
239+
return (List<JsonNode>) this.getAssignments(testCase, AssignmentValueType.JSON);
234240
}
235241

236242
private static Stream<Arguments> getAssignmentTestData() throws IOException {
@@ -248,7 +254,7 @@ private static Stream<Arguments> getAssignmentTestData() throws IOException {
248254
private static String getMockRandomizedAssignmentResponse() {
249255
File mockRacResponse = new File("src/test/resources/rac-experiments-v3.json");
250256
try {
251-
return FileUtils.readFileToString(mockRacResponse, "UTF8");
257+
return FileUtils.readFileToString(mockRacResponse, "UTF8");
252258
} catch (Exception e) {
253259
throw new RuntimeException("Error reading mock RAC data", e);
254260
}

0 commit comments

Comments
 (0)