Skip to content

Commit f29078e

Browse files
committed
Updated Factory
1 parent 076a850 commit f29078e

File tree

3 files changed

+254
-3
lines changed

3 files changed

+254
-3
lines changed

client/src/main/java/io/split/client/SplitFactoryImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyn
257257
_telemetrySyncTask = new TelemetrySyncTask(config.getTelemetryRefreshRate(), _telemetrySynchronizer,
258258
config.getThreadFactory());
259259

260-
FallbackTreatmentCalculatorImp fallbackTreatmentCalculatorImp = new FallbackTreatmentCalculatorImp(null);
260+
FallbackTreatmentCalculatorImp fallbackTreatmentCalculatorImp = new FallbackTreatmentCalculatorImp(config.fallbackTreatments());
261261
// Evaluator
262262
_evaluator = new EvaluatorImp(splitCache, segmentCache, ruleBasedSegmentCache, fallbackTreatmentCalculatorImp);
263263

@@ -352,7 +352,7 @@ protected SplitFactoryImpl(String apiToken, SplitClientConfig config, CustomStor
352352
_telemetrySynchronizer = new TelemetryConsumerSubmitter(customStorageWrapper, _sdkMetadata);
353353
UserCustomRuleBasedSegmentAdapterConsumer userCustomRuleBasedSegmentAdapterConsumer =
354354
new UserCustomRuleBasedSegmentAdapterConsumer(customStorageWrapper);
355-
FallbackTreatmentCalculatorImp fallbackTreatmentCalculatorImp = new FallbackTreatmentCalculatorImp(null);
355+
FallbackTreatmentCalculatorImp fallbackTreatmentCalculatorImp = new FallbackTreatmentCalculatorImp(config.fallbackTreatments());
356356
_evaluator = new EvaluatorImp(userCustomSplitAdapterConsumer, userCustomSegmentAdapterConsumer,
357357
userCustomRuleBasedSegmentAdapterConsumer, fallbackTreatmentCalculatorImp);
358358
_impressionsSender = PluggableImpressionSender.create(customStorageWrapper);
@@ -453,7 +453,7 @@ protected SplitFactoryImpl(SplitClientConfig config) {
453453
SplitTasks splitTasks = SplitTasks.build(_splitSynchronizationTask, _segmentSynchronizationTaskImp,
454454
_impressionsManager, null, null, null);
455455

456-
FallbackTreatmentCalculatorImp fallbackTreatmentCalculatorImp = new FallbackTreatmentCalculatorImp(null);
456+
FallbackTreatmentCalculatorImp fallbackTreatmentCalculatorImp = new FallbackTreatmentCalculatorImp(config.fallbackTreatments());
457457
// Evaluator
458458
_evaluator = new EvaluatorImp(splitCache, segmentCache, ruleBasedSegmentCache, fallbackTreatmentCalculatorImp);
459459

client/src/test/java/io/split/client/SplitClientIntegrationTest.java

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import io.split.SplitMockServer;
55
import io.split.client.api.SplitView;
66
import io.split.client.dtos.EvaluationOptions;
7+
import io.split.client.dtos.FallbackTreatment;
8+
import io.split.client.dtos.FallbackTreatmentsConfiguration;
79
import io.split.client.impressions.ImpressionsManager;
810
import io.split.client.utils.CustomDispatcher;
911
import io.split.storages.enums.OperationMode;
@@ -1175,6 +1177,222 @@ public MockResponse dispatch(RecordedRequest request) {
11751177
splitServer.shutdown();
11761178
}
11771179

1180+
@Test
1181+
public void FallbackTreatmentGlobalAndByFlagTest() throws Exception {
1182+
String splits = new String(Files.readAllBytes(Paths.get("src/test/resources/splits_imp_toggle.json")), StandardCharsets.UTF_8);
1183+
List<RecordedRequest> allRequests = new ArrayList<>();
1184+
Dispatcher dispatcher = new Dispatcher() {
1185+
@Override
1186+
public MockResponse dispatch(RecordedRequest request) {
1187+
allRequests.add(request);
1188+
switch (request.getPath()) {
1189+
case "/api/splitChanges?s=1.3&since=-1&rbSince=-1":
1190+
return new MockResponse().setResponseCode(200).setBody(splits);
1191+
case "/api/splitChanges?s=1.3&since=1602796638344&rbSince=-1":
1192+
return new MockResponse().setResponseCode(200).setBody("{\"ff\":{\"d\":[], \"s\":1602796638344, \"t\":1602796638344}, \"rbs\":{\"d\":[],\"s\":-1,\"t\":-1}}");
1193+
case "/api/testImpressions/bulk":
1194+
return new MockResponse().setResponseCode(200);
1195+
case "/api/testImpressions/count":
1196+
return new MockResponse().setResponseCode(200);
1197+
case "/v1/keys/ss":
1198+
return new MockResponse().setResponseCode(200);
1199+
case "/v1/metrics/usage":
1200+
return new MockResponse().setResponseCode(200);
1201+
case "/v1/metrics/config":
1202+
return new MockResponse().setResponseCode(200);
1203+
}
1204+
return new MockResponse().setResponseCode(404);
1205+
}
1206+
};
1207+
1208+
MockWebServer server = new MockWebServer();
1209+
server.setDispatcher(dispatcher);
1210+
1211+
server.start();
1212+
String serverURL = String.format("http://%s:%s", server.getHostName(), server.getPort());
1213+
FallbackTreatmentsConfiguration fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration(new FallbackTreatment("on-fallback", "{\"prop1\", \"val1\"}"),
1214+
new HashMap<String, FallbackTreatment>() {{ put("feature", new FallbackTreatment("off-fallback", "{\"prop2\", \"val2\"}")); }});
1215+
1216+
SplitClientConfig config = SplitClientConfig.builder()
1217+
.setBlockUntilReadyTimeout(10000)
1218+
.endpoint(serverURL, serverURL)
1219+
.telemetryURL(serverURL + "/v1")
1220+
.authServiceURL(String.format("%s/api/auth/enabled", serverURL))
1221+
.streamingEnabled(false)
1222+
.featuresRefreshRate(5)
1223+
.impressionsMode(ImpressionsManager.Mode.DEBUG)
1224+
.fallbackTreatments(fallbackTreatmentsConfiguration)
1225+
.build();
1226+
1227+
SplitFactory factory = SplitFactoryBuilder.build("fake-api-token", config);
1228+
SplitClient client = factory.client();
1229+
client.blockUntilReady();
1230+
1231+
Assert.assertEquals("off", client.getTreatment("user1", "without_impression_toggle"));
1232+
Assert.assertEquals("off-fallback", client.getTreatmentWithConfig("user2", "feature").treatment());
1233+
Assert.assertEquals("{\"prop2\", \"val2\"}", client.getTreatmentWithConfig("user2", "feature").config());
1234+
Assert.assertEquals("on-fallback", client.getTreatmentWithConfig("user2", "feature2").treatment());
1235+
Assert.assertEquals("{\"prop1\", \"val1\"}", client.getTreatmentWithConfig("user2", "feature2").config());
1236+
1237+
client.destroy();
1238+
boolean check1 = false;
1239+
for (int i=0; i < allRequests.size(); i++ ) {
1240+
if (allRequests.get(i).getPath().equals("/api/testImpressions/bulk") ) {
1241+
String body = allRequests.get(i).getBody().readUtf8();
1242+
if (body.contains("user1")) {
1243+
check1 = true;
1244+
Assert.assertTrue(body.contains("without_impression_toggle"));
1245+
}
1246+
}
1247+
}
1248+
server.shutdown();
1249+
Assert.assertTrue(check1);
1250+
}
1251+
1252+
@Test
1253+
public void FallbackTreatmentGlobalTest() throws Exception {
1254+
String splits = new String(Files.readAllBytes(Paths.get("src/test/resources/splits_imp_toggle.json")), StandardCharsets.UTF_8);
1255+
List<RecordedRequest> allRequests = new ArrayList<>();
1256+
Dispatcher dispatcher = new Dispatcher() {
1257+
@Override
1258+
public MockResponse dispatch(RecordedRequest request) {
1259+
allRequests.add(request);
1260+
switch (request.getPath()) {
1261+
case "/api/splitChanges?s=1.3&since=-1&rbSince=-1":
1262+
return new MockResponse().setResponseCode(200).setBody(splits);
1263+
case "/api/splitChanges?s=1.3&since=1602796638344&rbSince=-1":
1264+
return new MockResponse().setResponseCode(200).setBody("{\"ff\":{\"d\":[], \"s\":1602796638344, \"t\":1602796638344}, \"rbs\":{\"d\":[],\"s\":-1,\"t\":-1}}");
1265+
case "/api/testImpressions/bulk":
1266+
return new MockResponse().setResponseCode(200);
1267+
case "/api/testImpressions/count":
1268+
return new MockResponse().setResponseCode(200);
1269+
case "/v1/keys/ss":
1270+
return new MockResponse().setResponseCode(200);
1271+
case "/v1/metrics/usage":
1272+
return new MockResponse().setResponseCode(200);
1273+
case "/v1/metrics/config":
1274+
return new MockResponse().setResponseCode(200);
1275+
}
1276+
return new MockResponse().setResponseCode(404);
1277+
}
1278+
};
1279+
1280+
MockWebServer server = new MockWebServer();
1281+
server.setDispatcher(dispatcher);
1282+
1283+
server.start();
1284+
String serverURL = String.format("http://%s:%s", server.getHostName(), server.getPort());
1285+
FallbackTreatmentsConfiguration fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration(new FallbackTreatment("on-fallback", "{\"prop1\", \"val1\"}"),
1286+
null);
1287+
1288+
SplitClientConfig config = SplitClientConfig.builder()
1289+
.setBlockUntilReadyTimeout(10000)
1290+
.endpoint(serverURL, serverURL)
1291+
.telemetryURL(serverURL + "/v1")
1292+
.authServiceURL(String.format("%s/api/auth/enabled", serverURL))
1293+
.streamingEnabled(false)
1294+
.featuresRefreshRate(5)
1295+
.impressionsMode(ImpressionsManager.Mode.DEBUG)
1296+
.fallbackTreatments(fallbackTreatmentsConfiguration)
1297+
.build();
1298+
1299+
SplitFactory factory = SplitFactoryBuilder.build("fake-api-token", config);
1300+
SplitClient client = factory.client();
1301+
client.blockUntilReady();
1302+
1303+
Assert.assertEquals("off", client.getTreatment("user1", "without_impression_toggle"));
1304+
Assert.assertEquals("on-fallback", client.getTreatmentWithConfig("user2", "feature").treatment());
1305+
Assert.assertEquals("{\"prop1\", \"val1\"}", client.getTreatmentWithConfig("user2", "feature").config());
1306+
Assert.assertEquals("on-fallback", client.getTreatmentWithConfig("user2", "feature2").treatment());
1307+
Assert.assertEquals("{\"prop1\", \"val1\"}", client.getTreatmentWithConfig("user2", "feature2").config());
1308+
1309+
client.destroy();
1310+
boolean check1 = false;
1311+
for (int i=0; i < allRequests.size(); i++ ) {
1312+
if (allRequests.get(i).getPath().equals("/api/testImpressions/bulk") ) {
1313+
String body = allRequests.get(i).getBody().readUtf8();
1314+
if (body.contains("user1")) {
1315+
check1 = true;
1316+
Assert.assertTrue(body.contains("without_impression_toggle"));
1317+
}
1318+
}
1319+
}
1320+
server.shutdown();
1321+
Assert.assertTrue(check1);
1322+
}
1323+
1324+
@Test
1325+
public void FallbackTreatmentByFlagTest() throws Exception {
1326+
String splits = new String(Files.readAllBytes(Paths.get("src/test/resources/splits_imp_toggle.json")), StandardCharsets.UTF_8);
1327+
List<RecordedRequest> allRequests = new ArrayList<>();
1328+
Dispatcher dispatcher = new Dispatcher() {
1329+
@Override
1330+
public MockResponse dispatch(RecordedRequest request) {
1331+
allRequests.add(request);
1332+
switch (request.getPath()) {
1333+
case "/api/splitChanges?s=1.3&since=-1&rbSince=-1":
1334+
return new MockResponse().setResponseCode(200).setBody(splits);
1335+
case "/api/splitChanges?s=1.3&since=1602796638344&rbSince=-1":
1336+
return new MockResponse().setResponseCode(200).setBody("{\"ff\":{\"d\":[], \"s\":1602796638344, \"t\":1602796638344}, \"rbs\":{\"d\":[],\"s\":-1,\"t\":-1}}");
1337+
case "/api/testImpressions/bulk":
1338+
return new MockResponse().setResponseCode(200);
1339+
case "/api/testImpressions/count":
1340+
return new MockResponse().setResponseCode(200);
1341+
case "/v1/keys/ss":
1342+
return new MockResponse().setResponseCode(200);
1343+
case "/v1/metrics/usage":
1344+
return new MockResponse().setResponseCode(200);
1345+
case "/v1/metrics/config":
1346+
return new MockResponse().setResponseCode(200);
1347+
}
1348+
return new MockResponse().setResponseCode(404);
1349+
}
1350+
};
1351+
1352+
MockWebServer server = new MockWebServer();
1353+
server.setDispatcher(dispatcher);
1354+
1355+
server.start();
1356+
String serverURL = String.format("http://%s:%s", server.getHostName(), server.getPort());
1357+
FallbackTreatmentsConfiguration fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration(null,
1358+
new HashMap<String, FallbackTreatment>() {{ put("feature", new FallbackTreatment("off-fallback", "{\"prop2\", \"val2\"}")); }});
1359+
1360+
SplitClientConfig config = SplitClientConfig.builder()
1361+
.setBlockUntilReadyTimeout(10000)
1362+
.endpoint(serverURL, serverURL)
1363+
.telemetryURL(serverURL + "/v1")
1364+
.authServiceURL(String.format("%s/api/auth/enabled", serverURL))
1365+
.streamingEnabled(false)
1366+
.featuresRefreshRate(5)
1367+
.impressionsMode(ImpressionsManager.Mode.DEBUG)
1368+
.fallbackTreatments(fallbackTreatmentsConfiguration)
1369+
.build();
1370+
1371+
SplitFactory factory = SplitFactoryBuilder.build("fake-api-token", config);
1372+
SplitClient client = factory.client();
1373+
client.blockUntilReady();
1374+
1375+
Assert.assertEquals("off", client.getTreatment("user1", "without_impression_toggle"));
1376+
Assert.assertEquals("off-fallback", client.getTreatmentWithConfig("user2", "feature").treatment());
1377+
Assert.assertEquals("{\"prop2\", \"val2\"}", client.getTreatmentWithConfig("user2", "feature").config());
1378+
Assert.assertEquals("control", client.getTreatmentWithConfig("user2", "feature2").treatment());
1379+
Assert.assertEquals(null, client.getTreatmentWithConfig("user2", "feature2").config());
1380+
1381+
client.destroy();
1382+
boolean check1 = false;
1383+
for (int i=0; i < allRequests.size(); i++ ) {
1384+
if (allRequests.get(i).getPath().equals("/api/testImpressions/bulk") ) {
1385+
String body = allRequests.get(i).getBody().readUtf8();
1386+
if (body.contains("user1")) {
1387+
check1 = true;
1388+
Assert.assertTrue(body.contains("without_impression_toggle"));
1389+
}
1390+
}
1391+
}
1392+
server.shutdown();
1393+
Assert.assertTrue(check1);
1394+
}
1395+
11781396
private SSEMockServer buildSSEMockServer(SSEMockServer.SseEventQueue eventQueue) {
11791397
return new SSEMockServer(eventQueue, (token, version, channel) -> {
11801398
if (!"1.1".equals(version)) {

client/src/test/java/io/split/client/SplitFactoryImplTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package io.split.client;
22

3+
import io.split.client.dtos.FallbackTreatment;
4+
import io.split.client.dtos.FallbackTreatmentCalculatorImp;
5+
import io.split.client.dtos.FallbackTreatmentsConfiguration;
36
import io.split.client.dtos.ProxyConfiguration;
47
import io.split.client.impressions.ImpressionsManager;
58
import io.split.client.utils.FileTypeEnum;
9+
import io.split.engine.evaluator.EvaluatorImp;
610
import io.split.integrations.IntegrationsConfig;
711
import io.split.service.SplitHttpClientImpl;
812
import io.split.storages.enums.OperationMode;
@@ -56,11 +60,26 @@ public void testFactoryInstantiation() throws Exception {
5660
.authServiceURL(AUTH_SERVICE)
5761
.setBlockUntilReadyTimeout(10000)
5862
.telemetryURL(SplitClientConfig.TELEMETRY_ENDPOINT)
63+
.fallbackTreatments(new FallbackTreatmentsConfiguration(new FallbackTreatment("on"), null))
5964
.build();
6065
SplitFactoryImpl splitFactory = new SplitFactoryImpl(API_KEY, splitClientConfig);
6166

6267
assertNotNull(splitFactory.client());
6368
assertNotNull(splitFactory.manager());
69+
70+
Field fallbackField = SplitClientImpl.class.getDeclaredField("_fallbackTreatmentCalculator");
71+
fallbackField.setAccessible(true);
72+
FallbackTreatmentCalculatorImp fallbackCalc = (FallbackTreatmentCalculatorImp) fallbackField.get(splitFactory.client());
73+
assertNotNull(fallbackCalc);
74+
75+
Field evalField = SplitClientImpl.class.getDeclaredField("_evaluator");
76+
evalField.setAccessible(true);
77+
EvaluatorImp evaluatorImp = (EvaluatorImp) evalField.get(splitFactory.client());
78+
assertNotNull(fallbackCalc);
79+
fallbackField = EvaluatorImp.class.getDeclaredField("_fallbackTreatmentCalculator");
80+
fallbackField.setAccessible(true);
81+
fallbackCalc = (FallbackTreatmentCalculatorImp) fallbackField.get(evaluatorImp);
82+
assertNotNull(fallbackCalc);
6483
}
6584

6685
@Test
@@ -365,6 +384,20 @@ public void testFactoryConsumerInstantiation() throws Exception {
365384
Thread.sleep(1500);
366385
Mockito.verify(userStorageWrapper, Mockito.times(1)).connect();
367386
Mockito.verify(telemetrySynchronizer, Mockito.times(1)).synchronizeConfig(Mockito.anyObject(), Mockito.anyLong(), Mockito.anyObject(), Mockito.anyObject());
387+
388+
Field fallbackField = SplitClientImpl.class.getDeclaredField("_fallbackTreatmentCalculator");
389+
fallbackField.setAccessible(true);
390+
FallbackTreatmentCalculatorImp fallbackCalc = (FallbackTreatmentCalculatorImp) fallbackField.get(splitFactory.client());
391+
assertNotNull(fallbackCalc);
392+
393+
Field evalField = SplitClientImpl.class.getDeclaredField("_evaluator");
394+
evalField.setAccessible(true);
395+
EvaluatorImp evaluatorImp = (EvaluatorImp) evalField.get(splitFactory.client());
396+
assertNotNull(fallbackCalc);
397+
fallbackField = EvaluatorImp.class.getDeclaredField("_fallbackTreatmentCalculator");
398+
fallbackField.setAccessible(true);
399+
fallbackCalc = (FallbackTreatmentCalculatorImp) fallbackField.get(evaluatorImp);
400+
assertNotNull(fallbackCalc);
368401
}
369402

370403
@Test

0 commit comments

Comments
 (0)