Skip to content

Commit 567d2f1

Browse files
committed
Added label not ready for fallback
1 parent f29078e commit 567d2f1

File tree

3 files changed

+103
-19
lines changed

3 files changed

+103
-19
lines changed

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

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -510,12 +510,15 @@ private SplitResult getTreatmentWithConfigInternal(String matchingKey, String bu
510510
long start = System.currentTimeMillis();
511511

512512
EvaluatorImp.TreatmentLabelAndChangeNumber result = _evaluator.evaluateFeature(matchingKey, bucketingKey, featureFlag, attributes);
513-
514-
if (result.label != null && result.label.contains(Labels.DEFINITION_NOT_FOUND) && _gates.isSDKReady()) {
515-
_log.warn(String.format(
516-
"%s: you passed \"%s\" that does not exist in this environment, " +
517-
"please double check what feature flags exist in the Split user interface.", methodEnum.getMethod(), featureFlag));
518-
return checkFallbackTreatment(featureFlag);
513+
String label = result.label;
514+
if (result.label != null && result.label.contains(Labels.DEFINITION_NOT_FOUND)) {
515+
if (_gates.isSDKReady()) {
516+
_log.warn(String.format(
517+
"%s: you passed \"%s\" that does not exist in this environment, " +
518+
"please double check what feature flags exist in the Split user interface.", methodEnum.getMethod(), featureFlag));
519+
return checkFallbackTreatment(featureFlag);
520+
}
521+
label = result.label.replace(Labels.DEFINITION_NOT_FOUND, Labels.NOT_READY);
519522
}
520523

521524
recordStats(
@@ -525,7 +528,7 @@ private SplitResult getTreatmentWithConfigInternal(String matchingKey, String bu
525528
start,
526529
result.treatment,
527530
String.format("sdk.%s", methodEnum.getMethod()),
528-
_config.labelsEnabled() ? result.label : null,
531+
_config.labelsEnabled() ? label : null,
529532
result.changeNumber,
530533
attributes,
531534
result.track,
@@ -634,20 +637,23 @@ private Map<String, SplitResult> processEvaluatorResult(Map<String, EvaluatorImp
634637
List<DecoratedImpression> decoratedImpressions = new ArrayList<>();
635638
Map<String, SplitResult> result = new HashMap<>();
636639
evaluatorResult.keySet().forEach(flag -> {
640+
String label = evaluatorResult.get(flag).label;
637641
if (evaluatorResult.get(flag).label != null &&
638-
evaluatorResult.get(flag).label.contains(Labels.DEFINITION_NOT_FOUND) &&
639-
_gates.isSDKReady()) {
640-
_log.warn(String.format("%s: you passed \"%s\" that does not exist in this environment please double check " +
641-
"what feature flags exist in the Split user interface.", methodEnum.getMethod(), flag));
642-
result.put(flag, checkFallbackTreatment(flag));
643-
} else {
644-
result.put(flag, new SplitResult(evaluatorResult.get(flag).treatment, evaluatorResult.get(flag).configurations));
645-
decoratedImpressions.add(
646-
new DecoratedImpression(
647-
new Impression(matchingKey, bucketingKey, flag, evaluatorResult.get(flag).treatment, System.currentTimeMillis(),
648-
evaluatorResult.get(flag).label, evaluatorResult.get(flag).changeNumber, attributes, properties),
649-
evaluatorResult.get(flag).track));
642+
evaluatorResult.get(flag).label.contains(Labels.DEFINITION_NOT_FOUND)) {
643+
if (_gates.isSDKReady()) {
644+
_log.warn(String.format("%s: you passed \"%s\" that does not exist in this environment please double check " +
645+
"what feature flags exist in the Split user interface.", methodEnum.getMethod(), flag));
646+
result.put(flag, checkFallbackTreatment(flag));
647+
return;
648+
}
649+
label = evaluatorResult.get(flag).label.replace(Labels.DEFINITION_NOT_FOUND, Labels.NOT_READY);
650650
}
651+
result.put(flag, new SplitResult(evaluatorResult.get(flag).treatment, evaluatorResult.get(flag).configurations));
652+
decoratedImpressions.add(
653+
new DecoratedImpression(
654+
new Impression(matchingKey, bucketingKey, flag, evaluatorResult.get(flag).treatment, System.currentTimeMillis(),
655+
label, evaluatorResult.get(flag).changeNumber, attributes, properties),
656+
evaluatorResult.get(flag).track));
651657
});
652658
_telemetryEvaluationProducer.recordLatency(methodEnum, System.currentTimeMillis() - initTime);
653659
if (!decoratedImpressions.isEmpty()) {

client/src/main/java/io/split/engine/evaluator/Labels.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ public class Labels {
88
public static final String EXCEPTION = "exception";
99
public static final String UNSUPPORTED_MATCHER = "targeting rule type unsupported by sdk";
1010
public static final String PREREQUISITES_NOT_MET = "prerequisites not met";
11+
public static final String NOT_READY = "not ready";
1112
}

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

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,6 +1393,83 @@ public MockResponse dispatch(RecordedRequest request) {
13931393
Assert.assertTrue(check1);
13941394
}
13951395

1396+
@Test
1397+
public void FallbackTreatmentNotReadyTest() throws Exception {
1398+
String splits = new String(Files.readAllBytes(Paths.get("src/test/resources/splits_imp_toggle.json")), StandardCharsets.UTF_8);
1399+
List<RecordedRequest> allRequests = new ArrayList<>();
1400+
Dispatcher dispatcher = new Dispatcher() {
1401+
@Override
1402+
public MockResponse dispatch(RecordedRequest request) throws InterruptedException {
1403+
allRequests.add(request);
1404+
switch (request.getPath()) {
1405+
case "/api/splitChanges?s=1.3&since=-1&rbSince=-1":
1406+
Thread.sleep(1000);
1407+
return new MockResponse().setResponseCode(200).setBody(splits);
1408+
case "/api/splitChanges?s=1.3&since=1602796638344&rbSince=-1":
1409+
return new MockResponse().setResponseCode(200).setBody("{\"ff\":{\"d\":[], \"s\":1602796638344, \"t\":1602796638344}, \"rbs\":{\"d\":[],\"s\":-1,\"t\":-1}}");
1410+
case "/api/testImpressions/bulk":
1411+
return new MockResponse().setResponseCode(200);
1412+
case "/api/testImpressions/count":
1413+
return new MockResponse().setResponseCode(200);
1414+
case "/v1/keys/ss":
1415+
return new MockResponse().setResponseCode(200);
1416+
case "/v1/metrics/usage":
1417+
return new MockResponse().setResponseCode(200);
1418+
case "/v1/metrics/config":
1419+
return new MockResponse().setResponseCode(200);
1420+
}
1421+
return new MockResponse().setResponseCode(404);
1422+
}
1423+
};
1424+
1425+
MockWebServer server = new MockWebServer();
1426+
server.setDispatcher(dispatcher);
1427+
1428+
server.start();
1429+
String serverURL = String.format("http://%s:%s", server.getHostName(), server.getPort());
1430+
FallbackTreatmentsConfiguration fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration(new FallbackTreatment("on-fallback", "{\"prop1\", \"val1\"}"),
1431+
null);
1432+
1433+
SplitClientConfig config = SplitClientConfig.builder()
1434+
.setBlockUntilReadyTimeout(10000)
1435+
.endpoint(serverURL, serverURL)
1436+
.telemetryURL(serverURL + "/v1")
1437+
.authServiceURL(String.format("%s/api/auth/enabled", serverURL))
1438+
.streamingEnabled(false)
1439+
.featuresRefreshRate(5)
1440+
.impressionsMode(ImpressionsManager.Mode.DEBUG)
1441+
.fallbackTreatments(fallbackTreatmentsConfiguration)
1442+
.build();
1443+
1444+
SplitFactory factory = SplitFactoryBuilder.build("fake-api-token", config);
1445+
SplitClient client = factory.client();
1446+
1447+
Assert.assertEquals("on-fallback", client.getTreatment("user1", "without_impression_toggle"));
1448+
Assert.assertEquals("on-fallback", client.getTreatment("user2", "feature"));
1449+
client.blockUntilReady();
1450+
1451+
client.destroy();
1452+
boolean check1 = false, check2 = false;
1453+
for (int i=0; i < allRequests.size(); i++ ) {
1454+
if (allRequests.get(i).getPath().equals("/api/testImpressions/bulk") ) {
1455+
String body = allRequests.get(i).getBody().readUtf8();
1456+
if (body.contains("user2")) {
1457+
check1 = true;
1458+
Assert.assertTrue(body.contains("feature"));
1459+
Assert.assertTrue(body.contains("fallback - not ready"));
1460+
}
1461+
if (body.contains("user1")) {
1462+
check2 = true;
1463+
Assert.assertTrue(body.contains("without_impression_toggle"));
1464+
Assert.assertTrue(body.contains("fallback - not ready"));
1465+
}
1466+
}
1467+
}
1468+
server.shutdown();
1469+
Assert.assertTrue(check1);
1470+
Assert.assertTrue(check2);
1471+
}
1472+
13961473
private SSEMockServer buildSSEMockServer(SSEMockServer.SseEventQueue eventQueue) {
13971474
return new SSEMockServer(eventQueue, (token, version, channel) -> {
13981475
if (!"1.1".equals(version)) {

0 commit comments

Comments
 (0)