-
Notifications
You must be signed in to change notification settings - Fork 79
feat: Update fractional logic to support hashing consistency ADR. #1831
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
47eae44
bf6c0c9
555541d
4993a76
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -15,14 +15,19 @@ public final class Utils { | |||||||||
| private Utils() {} | ||||||||||
|
|
||||||||||
| public static Object convert(String value, String type) throws ClassNotFoundException, IOException { | ||||||||||
| if (Objects.equals(value, "null")) return null; | ||||||||||
| if ("Null".equals(type)) return null; | ||||||||||
| if (Objects.equals(value, "null") && !"String".equals(type)) return null; | ||||||||||
|
Comment on lines
+18
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== locate files =="
git ls-files | rg '(^|/)Utils\.java$|EvaluatorUtils\.ja$|flagd' || true
echo "== relevant Utils.java =="
if [ -f providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/Utils.java ]; then
cat -n providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/Utils.java
fi
echo "== compare EvaluatorUtils if present =="
if [ -f tools/flagd-api-testkit/src/main/java/dev/openfeature/contrib/tools/flagd/api/testkit/EvaluatorUtils.java ]; then
cat -n tools/flagd-api-testkit/src/main/java/dev/openfeature/contrib/tools/flagd/api/testkit/EvaluatorUtils.java
fi
echo "== search for Utils method name/call sites =="
rg -n "public static Object|convert|valueOf|Null|\"null\"" providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/Utils.java tools/flagd-api-testkit/src/main/java/dev/openfeature/contrib/tools/flagd/api/testkit/EvaluatorUtils.java 2>/dev/null || true
echo "== git diff stat/name status if available =="
git diff --stat HEAD~1..HEAD 2>/dev/null || git status --short 2>/dev/null || trueRepository: open-feature/java-sdk-contrib Length of output: 1944 🏁 Script executed: #!/bin/bash
set -euo pipefail
# Behavioral probe: model the Java switch expression from utils/evaluator files using Java semantics.
# This avoids modifying repository files and keeps the probe read-only.
python3 - <<'PY'
class JavaLike:
def convert(self, value, target_type):
if target_type == "Null":
return None
if value == "null" and target_type != "String":
return None
if target_type == "Boolean":
return bool(value.lower() == "true") if isinstance(value, str) else bool(value)
if target_type == "Integer":
if isinstance(value, str):
if value in ("null", "Infinity", "-Infinity"):
raise ValueError("badIntFormat")
return int(value)
raise TypeError("non-string integer")
if target_type == "Number":
if isinstance(value, str):
return float(value)
raise TypeError("non-string number")
if target_type == "String":
return str(value)
raise NotImplementedError(target_type)
cases = [
(None, "Boolean"),
("null", "Boolean"),
(None, "Integer"),
("null", "Integer"),
(None, "Number"),
("null", "Number"),
(None, "Object"),
("null", "Object"),
(None, "String"),
("null", "String"),
]
for value, target_type in cases:
try:
out = JavaLike().convert(value, target_type)
except Exception as ex:
out = f"{type(ex).__name__}: {ex}"
print(f"({value!r}, {target_type!r}) -> {out!r}")
PYRepository: open-feature/java-sdk-contrib Length of output: 1944 🌐 Web query:
💡 Result: The file Citations:
🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== locate files =="
git ls-files | rg '(^|/)Utils\.java$|EvaluatorUtils\.ja$|flagd' || true
echo "== relevant Utils.java =="
if [ -f providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/Utils.java ]; then
cat -n providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/Utils.java
fi
echo "== compare EvaluatorUtils if present =="
if [ -f tools/flagd-api-testkit/src/main/java/dev/openfeature/contrib/tools/flagd/api/testkit/EvaluatorUtils.java ]; then
cat -n tools/flagd-api-testkit/src/main/java/dev/openfeature/contrib/tools/flagd/api/testkit/EvaluatorUtils.java
fi
echo "== search for Utils method name/call sites =="
rg -n "public static Object|convert|valueOf|Null|\"null\"" providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/Utils.java tools/flagd-api-testkit/src/main/java/dev/openfeature/contrib/tools/flagd/api/testkit/EvaluatorUtils.java 2>/dev/null || true
echo "== git diff stat/name status if available =="
git diff --stat HEAD~1..HEAD 2>/dev/null || git status --short 2>/dev/null || trueRepository: open-feature/java-sdk-contrib Length of output: 1944 🏁 Script executed: #!/bin/bash
set -euo pipefail
# Behavioral probe: model the Java switch expression from utils/evaluator files using Java semantics.
# This avoids modifying repository files and keeps the probe read-only.
python3 - <<'PY'
class JavaLike:
def convert(self, value, target_type):
if target_type == "Null":
return None
if value == "null" and target_type != "String":
return None
if target_type == "Boolean":
return bool(value.lower() == "true") if isinstance(value, str) else bool(value)
if target_type == "Integer":
if isinstance(value, str):
if value in ("null", "Infinity", "-Infinity"):
raise ValueError("badIntFormat")
return int(value)
raise TypeError("non-string integer")
if target_type == "Number":
if isinstance(value, str):
return float(value)
raise TypeError("non-string number")
if target_type == "String":
return str(value)
raise NotImplementedError(target_type)
cases = [
(None, "Boolean"),
("null", "Boolean"),
(None, "Integer"),
("null", "Integer"),
(None, "Number"),
("null", "Number"),
(None, "Object"),
("null", "Object"),
(None, "String"),
("null", "String"),
]
for value, target_type in cases:
try:
out = JavaLike().convert(value, target_type)
except Exception as ex:
out = f"{type(ex).__name__}: {ex}"
print(f"({value!r}, {target_type!r}) -> {out!r}")
PYRepository: open-feature/java-sdk-contrib Length of output: 1944 🌐 Web query:
💡 Result: The class EvaluatorUtils in the open-feature/java-sdk-contrib repository is part of the flagd-api-testkit toolset [1][2][3]. While specific code details regarding a null check on value are not explicitly documented in high-level summaries, the project frequently addresses null pointer exceptions (NPEs) and null handling across its tools and providers to ensure robustness in flag evaluation [4][5][6]. Recent updates in the flagd-related modules have focused on: - Improving null safety: Defensive null checks have been added to prevent NPEs in various evaluation contexts, such as when handling flag metadata [4][5]. - Consistent evaluation: Changes have been made to evaluation logic, such as treating DISABLED flags as successful evaluations [3][7] and fixing custom operator conformance edge cases that previously returned null on errors [6]. If you are investigating a specific null value behavior in EvaluatorUtils.java, it is likely related to these broader efforts to standardize how missing metadata, disabled flags, or evaluation errors are handled within the OpenFeature flagd ecosystem. For the most accurate technical analysis of the code at its current state, please refer to the source file directly on the main branch of the repository [8]. Citations:
🌐 Web query:
💡 Result: The file Citations:
🌐 Web query:
💡 Result: The file located at providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/Utils.java is part of the flagd provider test suite within the open-feature/java-sdk-contrib repository [1][2]. This utility class typically contains helper methods used for end-to-end (e2e) testing of the flagd provider [3][2]. Recent development in the java-sdk-contrib repository has involved significant architectural changes to these e2e tests to support parallel execution and performance improvements [4]. Specifically, the repository utilizes Cucumber for its e2e testing, and utility classes like this are instrumental in managing test state, container lifecycles, and environment synchronization across test scenarios [2][4]. Due to the active nature of this repository, the contents of specific test utility files are frequently updated to accommodate new features, refactoring of test runners, and dependency management [2][4][5]. For the most up-to-date and accurate code, please refer directly to the official GitHub repository [6]. Citations:
🌐 Web query:
💡 Result: The EvaluatorUtils.java file is a component within the OpenFeature flagd Java ecosystem, typically associated with utilities for the flagd-api-testkit or related evaluation logic [1][2][3]. In the context of the flagd-api-testkit and flagd Java evaluators, a check for Citations:
🌐 Web query:
💡 Result: There is no standard or known operation in the open-feature/java-sdk-contrib repository to "Convert to Tools Null valueOf." Research into the repository indicates that recent efforts have focused on fixing NullPointerExceptions [1] and improving operator conformance [2] within its tools modules, specifically within flagd-core components [1]. The term "valueOf" is a standard Java method often used for type conversion (e.g., String.valueOf(Object)) [3], but it is not associated with a specific migration or conversion utility in this context. If you are encountering an issue related to null handling or value conversion, it is likely related to general Java programming practices or specific bugs within the providers/tools, rather than a documented library feature. If you are looking to resolve null-related issues in your implementation, common approaches in the OpenFeature Java ecosystem include: 1. Ensuring proper null checks when accessing metadata or evaluation results [1]. 2. Using the standard SDK evaluation methods that support default values, which are designed to handle nulls safely [4]. 3. Reviewing project-specific pull requests (such as PR Citations:
Handle actual This guard handles the Proposed guard if ("Null".equals(type)) return null;
- if (Objects.equals(value, "null") && !"String".equals(type)) return null;
+ if (value == null || (Objects.equals(value, "null") && !"String".equals(type))) return null;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
| switch (type) { | ||||||||||
| case "Boolean": | ||||||||||
| return Boolean.parseBoolean(value); | ||||||||||
| case "String": | ||||||||||
| return value; | ||||||||||
| case "Integer": | ||||||||||
| return Integer.parseInt(value); | ||||||||||
| try { | ||||||||||
| return Integer.parseInt(value); | ||||||||||
| } catch (NumberFormatException e) { | ||||||||||
| return Long.parseLong(value); | ||||||||||
| } | ||||||||||
| case "Float": | ||||||||||
| return Double.parseDouble(value); | ||||||||||
| case "Long": | ||||||||||
|
|
||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,7 +22,10 @@ private EvaluatorUtils() {} | |
| * @return the converted value, or {@code null} if {@code value} is "null" or empty for Object | ||
| */ | ||
| public static Object convert(String value, String type) throws IOException { | ||
| if (value == null || value.equals("null")) { | ||
| if ("Null".equals(type)) { | ||
| return null; | ||
| } | ||
| if (value == null || (value.equals("null") && !"String".equals(type))) { | ||
|
Comment on lines
+25
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Update the The documentation omits the Proposed documentation update- * `@param` type the flag type name: Boolean, String, Integer, Float, or Object
- * `@return` the converted value, or {`@code` null} if {`@code` value} is "null" or empty for Object
+ * `@param` type the flag type name: Null, Boolean, String, Integer, Float, or Object
+ * `@return` the converted value; String preserves the literal "null", and Object
+ * converts an empty value to an empty object🤖 Prompt for AI Agents |
||
| return null; | ||
| } | ||
| switch (type) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift
Preserve cleanup after fatal errors.
Line 119 sets
isInitializedtofalsebeforeFlagdProvider.shutdown()runs.FlagdProvider.onFatalcallsfatalError(...)and thenshutdown().FlagdProvider.shutdown()returns when!syncResources.isInitialized(), before it callsflagResolver.shutdown(), shuts downerrorExecutor, or marks the resource as shut down. This can leave fatal provider resources running andisShutDownfalse.Change the shutdown contract so fatal cleanup does not depend on
isInitialized, or use a separate cleanup state. Add a regression test for a fatal error after initialization.🤖 Prompt for AI Agents