diff --git a/src/main/java/dev/openfeature/sdk/FeatureProvider.java b/src/main/java/dev/openfeature/sdk/FeatureProvider.java index 22819ef10..ec9a3d1a8 100644 --- a/src/main/java/dev/openfeature/sdk/FeatureProvider.java +++ b/src/main/java/dev/openfeature/sdk/FeatureProvider.java @@ -15,12 +15,43 @@ default List getProviderHooks() { return new ArrayList<>(); } + /** + * Resolves a feature flag value as a {@link Number}. + * + * @param key the unique identifier for the flag + * @param defaultValue the default value to return if the flag cannot be resolved + * @param ctx the evaluation context containing any relevant information for resolution + * @return a {@link ProviderEvaluation} containing the resolved {@code Number} value and additional eval details + */ + default ProviderEvaluation getNumberEvaluation(String key, Number defaultValue, EvaluationContext ctx) { + ProviderEvaluation dep = getDoubleEvaluation(key, defaultValue.doubleValue(), ctx); + return new ProviderEvaluation<>( + dep.getValue(), + dep.getReason(), + dep.getVariant(), + dep.getErrorCode(), + dep.getErrorMessage(), + dep.getFlagMetadata()); + } + ProviderEvaluation getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx); ProviderEvaluation getStringEvaluation(String key, String defaultValue, EvaluationContext ctx); + /** + * Evaluate feature flag returning an integer value. + * + * @deprecated please use {@link #getNumberEvaluation(String, Number, EvaluationContext)} + */ + @Deprecated ProviderEvaluation getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx); + /** + * Evaluate a feature flag returning a double value. + * + * @deprecated please use {@link #getNumberEvaluation(String, Number, EvaluationContext)} + */ + @Deprecated ProviderEvaluation getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx); ProviderEvaluation getObjectEvaluation(String key, Value defaultValue, EvaluationContext ctx); diff --git a/src/main/java/dev/openfeature/sdk/FlagValueType.java b/src/main/java/dev/openfeature/sdk/FlagValueType.java index a8938d454..41d6d5c82 100644 --- a/src/main/java/dev/openfeature/sdk/FlagValueType.java +++ b/src/main/java/dev/openfeature/sdk/FlagValueType.java @@ -3,6 +3,7 @@ @SuppressWarnings("checkstyle:MissingJavadocType") public enum FlagValueType { STRING, + NUMBER, INTEGER, DOUBLE, OBJECT, diff --git a/src/main/java/dev/openfeature/sdk/NoOpProvider.java b/src/main/java/dev/openfeature/sdk/NoOpProvider.java index e427b9701..cfd1b164d 100644 --- a/src/main/java/dev/openfeature/sdk/NoOpProvider.java +++ b/src/main/java/dev/openfeature/sdk/NoOpProvider.java @@ -41,6 +41,7 @@ public ProviderEvaluation getStringEvaluation(String key, String default } @Override + @Deprecated public ProviderEvaluation getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) { return ProviderEvaluation.builder() .value(defaultValue) @@ -50,6 +51,7 @@ public ProviderEvaluation getIntegerEvaluation(String key, Integer defa } @Override + @Deprecated public ProviderEvaluation getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) { return ProviderEvaluation.builder() .value(defaultValue) diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index b5522b66a..b34714407 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -287,9 +287,11 @@ private ProviderEvaluation createProviderEvaluation( case STRING: return provider.getStringEvaluation(key, (String) defaultValue, invocationContext); case INTEGER: - return provider.getIntegerEvaluation(key, (Integer) defaultValue, invocationContext); + return provider.getNumberEvaluation(key, (Integer) defaultValue, invocationContext); + case NUMBER: + return provider.getNumberEvaluation(key, (Number) defaultValue, invocationContext); case DOUBLE: - return provider.getDoubleEvaluation(key, (Double) defaultValue, invocationContext); + return provider.getNumberEvaluation(key, (Double) defaultValue, invocationContext); case OBJECT: return provider.getObjectEvaluation(key, (Value) defaultValue, invocationContext); default: diff --git a/src/test/java/dev/openfeature/sdk/NoOpProviderTest.java b/src/test/java/dev/openfeature/sdk/NoOpProviderTest.java index d0c7c6014..c4b75ab76 100644 --- a/src/test/java/dev/openfeature/sdk/NoOpProviderTest.java +++ b/src/test/java/dev/openfeature/sdk/NoOpProviderTest.java @@ -41,4 +41,11 @@ void value() { ProviderEvaluation eval = p.getObjectEvaluation("key", s, null); assertEquals(s, eval.getValue()); } + + @Test + void noOpNumber() { + NoOpProvider p = new NoOpProvider(); + ProviderEvaluation eval = p.getNumberEvaluation("key", 123456789L, null); + assertEquals(123456789.0, eval.getValue()); + } } diff --git a/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java b/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java index ec87acd70..3569027d2 100644 --- a/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java @@ -40,6 +40,9 @@ void flag_value_set() { ProviderEvaluation int_result = p.getIntegerEvaluation("key", 4, new ImmutableContext()); assertNotNull(int_result.getValue()); + ProviderEvaluation number_result = p.getNumberEvaluation("key", 2L, new ImmutableContext()); + assertNotNull(number_result.getValue()); + ProviderEvaluation double_result = p.getDoubleEvaluation("key", 0.4, new ImmutableContext()); assertNotNull(double_result.getValue()); @@ -97,6 +100,9 @@ void variant_set() { ProviderEvaluation int_result = p.getIntegerEvaluation("key", 4, new ImmutableContext()); assertNotNull(int_result.getReason()); + ProviderEvaluation number_result = p.getNumberEvaluation("key", 2L, new ImmutableContext()); + assertNotNull(number_result.getReason()); + ProviderEvaluation double_result = p.getDoubleEvaluation("key", 0.4, new ImmutableContext()); assertNotNull(double_result.getReason());