diff --git a/src/main/java/com/launchdarkly/client/LDClient.java b/src/main/java/com/launchdarkly/client/LDClient.java index e9594f910..57f1fca23 100644 --- a/src/main/java/com/launchdarkly/client/LDClient.java +++ b/src/main/java/com/launchdarkly/client/LDClient.java @@ -308,6 +308,24 @@ public JsonElement jsonVariation(String featureKey, LDUser user, JsonElement def return value; } + @Override + public boolean isFlagKnown(String featureKey) { + if (!initialized()) { + logger.warn("Evaluation called before Client has been initialized for feature flag " + featureKey + "; returning unknown"); + return false; + } + + try { + if (config.featureStore.get(featureKey) != null) { + return true; + } + } catch (Exception e) { + logger.error("Encountered exception in LaunchDarkly client", e); + } + + return false; + } + private JsonElement evaluate(String featureKey, LDUser user, JsonElement defaultValue, VariationType expectedType) { if (user == null || user.getKey() == null) { logger.warn("Null user or null user key when evaluating flag: " + featureKey + "; returning default value"); diff --git a/src/main/java/com/launchdarkly/client/LDClientInterface.java b/src/main/java/com/launchdarkly/client/LDClientInterface.java index 93ffd49a3..7c78f486f 100644 --- a/src/main/java/com/launchdarkly/client/LDClientInterface.java +++ b/src/main/java/com/launchdarkly/client/LDClientInterface.java @@ -30,6 +30,8 @@ public interface LDClientInterface extends Closeable { JsonElement jsonVariation(String featureKey, LDUser user, JsonElement defaultValue); + boolean isFlagKnown(String featureKey); + @Override void close() throws IOException; diff --git a/src/test/java/com/launchdarkly/client/LDClientTest.java b/src/test/java/com/launchdarkly/client/LDClientTest.java index b3f2355a4..a1221e76d 100644 --- a/src/test/java/com/launchdarkly/client/LDClientTest.java +++ b/src/test/java/com/launchdarkly/client/LDClientTest.java @@ -272,6 +272,49 @@ public void testTestFeatureStoreJsonVariationArray() throws Exception { verifyAll(); } + @Test + public void testIsFlagKnown() throws Exception { + TestFeatureStore testFeatureStore = new TestFeatureStore(); + LDConfig config = new LDConfig.Builder() + .startWaitMillis(10L) + .stream(false) + .featureStore(testFeatureStore) + .build(); + + expect(initFuture.get(10L, TimeUnit.MILLISECONDS)).andReturn(new Object()); + expect(pollingProcessor.start()).andReturn(initFuture); + expect(pollingProcessor.initialized()).andReturn(true).times(2); + replayAll(); + + client = createMockClient(config); + + testFeatureStore.setIntegerValue("key", 1); + assertTrue("Flag is known", client.isFlagKnown("key")); + assertFalse("Flag is unknown", client.isFlagKnown("unKnownKey")); + verifyAll(); + } + + @Test + public void testIsFlagKnownCallBeforeInitialization() throws Exception { + TestFeatureStore testFeatureStore = new TestFeatureStore(); + LDConfig config = new LDConfig.Builder() + .startWaitMillis(10L) + .stream(false) + .featureStore(testFeatureStore) + .build(); + + expect(initFuture.get(10L, TimeUnit.MILLISECONDS)).andReturn(new Object()); + expect(pollingProcessor.start()).andReturn(initFuture); + expect(pollingProcessor.initialized()).andReturn(false).times(1); + replayAll(); + + client = createMockClient(config); + + testFeatureStore.setIntegerValue("key", 1); + assertFalse("Flag is marked as unknown", client.isFlagKnown("key")); + verifyAll(); + } + @Test public void testUseLdd() throws IOException { LDConfig config = new LDConfig.Builder()