-
Notifications
You must be signed in to change notification settings - Fork 3
Changed UpdateFlags function to return absl::Status #114
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
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 | ||||
|---|---|---|---|---|---|---|
|
|
@@ -6,6 +6,7 @@ | |||||
| #include <nlohmann/json.hpp> | ||||||
|
|
||||||
| #include "absl/log/log.h" | ||||||
| #include "absl/strings/str_cat.h" | ||||||
| #include "embedded_schemas.h" | ||||||
|
|
||||||
| using Json = nlohmann::json; | ||||||
|
|
@@ -38,13 +39,13 @@ class FlagSync::Validator { | |||||
| validator.set_root_schema(Json::parse(schema::schemas.at("flagd.json"))); | ||||||
| } | ||||||
|
|
||||||
| bool Validate(const Json& json) const { | ||||||
| absl::Status Validate(const Json& json) const { | ||||||
|
Contributor
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. |
||||||
| try { | ||||||
| validator.validate(json); | ||||||
| return true; | ||||||
| return absl::OkStatus(); | ||||||
| } catch (const std::exception& e) { | ||||||
| LOG(ERROR) << "Flag configuration validation failed: " << e.what(); | ||||||
| return false; | ||||||
| return absl::InvalidArgumentError( | ||||||
| absl::StrCat("Flag configuration validation failed: ", e.what())); | ||||||
| } | ||||||
| } | ||||||
| }; | ||||||
|
|
@@ -58,12 +59,11 @@ FlagSync::FlagSync() | |||||
|
|
||||||
| FlagSync::~FlagSync() = default; | ||||||
|
|
||||||
| void FlagSync::UpdateFlags(const nlohmann::json& new_json) { | ||||||
| absl::Status FlagSync::UpdateFlags(const nlohmann::json& new_json) { | ||||||
|
Contributor
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. Update the definition of To fully leverage move semantics and avoid deep copies of the JSON structure, you should also update the body of this function (which is outside the current diff) to use auto new_flags_snapshot =
std::make_shared<const nlohmann::json>(std::move(new_json["flags"]));
auto new_metadata_snapshot =
std::make_shared<const nlohmann::json>(std::move(new_json["metadata"]));
Suggested change
References
|
||||||
| if (validator_) { | ||||||
| if (!validator_->Validate(new_json)) { | ||||||
| // Validation failed, do not update flags. | ||||||
| LOG(ERROR) << "Flag configuration validation failed, skipping update."; | ||||||
| return; | ||||||
| absl::Status status = validator_->Validate(new_json); | ||||||
| if (!status.ok()) { | ||||||
| return status; | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
|
|
@@ -83,6 +83,8 @@ void FlagSync::UpdateFlags(const nlohmann::json& new_json) { | |||||
| current_flags_ = std::move(new_flags_snapshot); | ||||||
| global_metadata_ = std::move(new_metadata_snapshot); | ||||||
| } | ||||||
|
|
||||||
| return absl::OkStatus(); | ||||||
| } | ||||||
|
|
||||||
| void FlagSync::ClearFlags() { | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -22,7 +22,7 @@ class FlagSync { | |||||
| std::shared_ptr<const nlohmann::json> GetMetadata() const; | ||||||
|
|
||||||
| protected: | ||||||
| void UpdateFlags(const nlohmann::json& new_json); | ||||||
| absl::Status UpdateFlags(const nlohmann::json& new_json); | ||||||
|
Contributor
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. Mark
Suggested change
|
||||||
| void ClearFlags(); | ||||||
|
|
||||||
| private: | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -16,8 +16,8 @@ class TestableSync : public flagd::FlagSync { | |||||||||||||
| } | ||||||||||||||
| absl::Status Shutdown() override { return absl::OkStatus(); } | ||||||||||||||
|
|
||||||||||||||
| void TriggerUpdate(const nlohmann::json& new_json) { | ||||||||||||||
| this->UpdateFlags(new_json); | ||||||||||||||
| absl::Status TriggerUpdate(const nlohmann::json& new_json) { | ||||||||||||||
| return this->UpdateFlags(new_json); | ||||||||||||||
| } | ||||||||||||||
|
Comment on lines
+19
to
21
Contributor
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. Update
Suggested change
|
||||||||||||||
| }; | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -46,7 +46,7 @@ TEST_F(EvaluatorTest, ResolveBooleanSuccess) { | |||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
|
|
||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = | ||||||||||||||
| openfeature::EvaluationContext::Builder().build(); | ||||||||||||||
|
|
@@ -63,7 +63,7 @@ TEST_F(EvaluatorTest, ResolveBooleanFlagNotFound) { | |||||||||||||
| nlohmann::json flags = nlohmann::json::parse(R"({ | ||||||||||||||
| "flags": {} | ||||||||||||||
| })"); | ||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = | ||||||||||||||
| openfeature::EvaluationContext::Builder().build(); | ||||||||||||||
|
|
@@ -89,7 +89,7 @@ TEST_F(EvaluatorTest, ResolveBooleanTypeMismatch) { | |||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
|
|
||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = | ||||||||||||||
| openfeature::EvaluationContext::Builder().build(); | ||||||||||||||
|
|
@@ -123,7 +123,7 @@ TEST_F(EvaluatorTest, ResolveBooleanMetadata) { | |||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
|
|
||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = | ||||||||||||||
| openfeature::EvaluationContext::Builder().build(); | ||||||||||||||
|
|
@@ -154,7 +154,7 @@ TEST_F(EvaluatorTest, ResolveBooleanVariantNotFound) { | |||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
|
|
||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = | ||||||||||||||
| openfeature::EvaluationContext::Builder().build(); | ||||||||||||||
|
|
@@ -183,7 +183,7 @@ TEST_F(EvaluatorTest, ResolveStringSuccess) { | |||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
|
|
||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = | ||||||||||||||
| openfeature::EvaluationContext::Builder().build(); | ||||||||||||||
|
|
@@ -209,7 +209,7 @@ TEST_F(EvaluatorTest, ResolveIntegerSuccess) { | |||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
|
|
||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = | ||||||||||||||
| openfeature::EvaluationContext::Builder().build(); | ||||||||||||||
|
|
@@ -235,7 +235,7 @@ TEST_F(EvaluatorTest, ResolveDoubleSuccess) { | |||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
|
|
||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = | ||||||||||||||
| openfeature::EvaluationContext::Builder().build(); | ||||||||||||||
|
|
@@ -266,7 +266,7 @@ TEST_F(EvaluatorTest, ResolveObjectSuccess) { | |||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
|
|
||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = | ||||||||||||||
| openfeature::EvaluationContext::Builder().build(); | ||||||||||||||
|
|
@@ -302,7 +302,7 @@ TEST_F(EvaluatorTest, ResolveStringTypeMismatch) { | |||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
|
|
||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = | ||||||||||||||
| openfeature::EvaluationContext::Builder().build(); | ||||||||||||||
|
|
@@ -327,7 +327,7 @@ TEST_F(EvaluatorTest, ResolveIntegerTypeMismatch) { | |||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
|
|
||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = | ||||||||||||||
| openfeature::EvaluationContext::Builder().build(); | ||||||||||||||
|
|
@@ -352,7 +352,7 @@ TEST_F(EvaluatorTest, ResolveDoubleTypeMismatch) { | |||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
|
|
||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = | ||||||||||||||
| openfeature::EvaluationContext::Builder().build(); | ||||||||||||||
|
|
@@ -371,7 +371,7 @@ class EvaluatorDefaultVariantTest | |||||||||||||
| TEST_P(EvaluatorDefaultVariantTest, ResolveBooleanReturnsDefault) { | ||||||||||||||
| nlohmann::json flags_json = | ||||||||||||||
| nlohmann::json::parse(R"({"flags":)" + GetParam() + "}"); | ||||||||||||||
| sync_->TriggerUpdate(flags_json); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags_json).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = | ||||||||||||||
| openfeature::EvaluationContext::Builder().build(); | ||||||||||||||
|
|
@@ -421,7 +421,7 @@ TEST_F(EvaluatorTest, ResolveBooleanDisabled) { | |||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
|
|
||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = | ||||||||||||||
| openfeature::EvaluationContext::Builder().build(); | ||||||||||||||
|
|
@@ -453,7 +453,7 @@ TEST_F(EvaluatorTest, ResolveStringTargetingSuccess) { | |||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
|
|
||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| // Match targeting rule | ||||||||||||||
| openfeature::EvaluationContext ctx_blue = | ||||||||||||||
|
|
@@ -504,7 +504,7 @@ TEST_F(EvaluatorTest, ResolveIntegerComplexTargeting) { | |||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
|
|
||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = openfeature::EvaluationContext::Builder() | ||||||||||||||
| .WithAttribute("env", "prod") | ||||||||||||||
|
|
@@ -538,7 +538,7 @@ TEST_F(EvaluatorTest, ResolveObjectNestedStructure) { | |||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
|
|
||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = | ||||||||||||||
| openfeature::EvaluationContext::Builder().build(); | ||||||||||||||
|
|
@@ -587,7 +587,7 @@ TEST_F(EvaluatorTest, ResolveBooleanFlagdSpecialVars) { | |||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
|
|
||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = | ||||||||||||||
| openfeature::EvaluationContext::Builder().build(); | ||||||||||||||
|
|
@@ -612,7 +612,7 @@ TEST_F(EvaluatorTest, ResolveBooleanTypeMismatchInTargeting) { | |||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
|
|
||||||||||||||
| sync_->TriggerUpdate(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->TriggerUpdate(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::EvaluationContext ctx = openfeature::EvaluationContext::Builder() | ||||||||||||||
| .WithAttribute("color", "blue") | ||||||||||||||
|
|
||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -16,7 +16,9 @@ class MockSync : public flagd::FlagSync { | |||||||||||||
| } | ||||||||||||||
| absl::Status Shutdown() override { return absl::OkStatus(); } | ||||||||||||||
|
|
||||||||||||||
| void SetFlags(const nlohmann::json& flags) { this->UpdateFlags(flags); } | ||||||||||||||
| absl::Status SetFlags(const nlohmann::json& flags) { | ||||||||||||||
| return this->UpdateFlags(flags); | ||||||||||||||
| } | ||||||||||||||
|
Comment on lines
+19
to
+21
Contributor
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. Update
Suggested change
|
||||||||||||||
| }; | ||||||||||||||
|
|
||||||||||||||
| class FlagdOpenFeatureTest : public ::testing::Test { | ||||||||||||||
|
|
@@ -54,7 +56,7 @@ TEST_F(FlagdOpenFeatureTest, BooleanEvaluation) { | |||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
| sync_->SetFlags(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->SetFlags(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| EXPECT_TRUE(client_->GetBooleanValue("bool-flag", false)); | ||||||||||||||
| EXPECT_FALSE(client_->GetBooleanValue("non-existent", false)); | ||||||||||||||
|
|
@@ -73,7 +75,7 @@ TEST_F(FlagdOpenFeatureTest, StringEvaluation) { | |||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
| sync_->SetFlags(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->SetFlags(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| EXPECT_EQ(client_->GetStringValue("string-flag", "default"), "value2"); | ||||||||||||||
| } | ||||||||||||||
|
|
@@ -91,7 +93,7 @@ TEST_F(FlagdOpenFeatureTest, IntegerEvaluation) { | |||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
| sync_->SetFlags(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->SetFlags(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| EXPECT_EQ(client_->GetIntegerValue("int-flag", 0), 1); | ||||||||||||||
| } | ||||||||||||||
|
|
@@ -109,7 +111,7 @@ TEST_F(FlagdOpenFeatureTest, DoubleEvaluation) { | |||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
| sync_->SetFlags(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->SetFlags(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| EXPECT_DOUBLE_EQ(client_->GetDoubleValue("double-flag", 0.0), 2.2); | ||||||||||||||
| } | ||||||||||||||
|
|
@@ -128,7 +130,7 @@ TEST_F(FlagdOpenFeatureTest, ObjectEvaluation) { | |||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
| sync_->SetFlags(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->SetFlags(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| openfeature::Value val = | ||||||||||||||
| client_->GetObjectValue("obj-flag", openfeature::Value()); | ||||||||||||||
|
|
@@ -159,7 +161,7 @@ TEST_F(FlagdOpenFeatureTest, EvaluationContextTargeting) { | |||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| })"); | ||||||||||||||
| sync_->SetFlags(flags); | ||||||||||||||
| EXPECT_TRUE(sync_->SetFlags(flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| // Without context, should return defaultVariant "red" | ||||||||||||||
| EXPECT_EQ(client_->GetStringValue("targeting-flag", "default"), "red-value"); | ||||||||||||||
|
|
||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -18,8 +18,8 @@ class MockSync : public flagd::FlagSync { | |||||||||||||
| (override)); | ||||||||||||||
| MOCK_METHOD(absl::Status, Shutdown, (), (override)); | ||||||||||||||
|
|
||||||||||||||
| void TriggerUpdate(const nlohmann::json& new_json) { | ||||||||||||||
| this->UpdateFlags(new_json); | ||||||||||||||
| absl::Status TriggerUpdate(const nlohmann::json& new_json) { | ||||||||||||||
| return this->UpdateFlags(new_json); | ||||||||||||||
| } | ||||||||||||||
|
Comment on lines
+21
to
23
Contributor
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. Update
Suggested change
|
||||||||||||||
| }; | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -55,7 +55,7 @@ TEST_F(FlagSyncTest, HelperMethodsUpdateAndRetrieveFlags) { | |||||||||||||
| } | ||||||||||||||
| })"_json; | ||||||||||||||
|
|
||||||||||||||
| sync_.TriggerUpdate(expected_flags); | ||||||||||||||
| EXPECT_TRUE(sync_.TriggerUpdate(expected_flags).ok()); | ||||||||||||||
|
|
||||||||||||||
| result_ptr = sync_.GetFlags(); | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -82,7 +82,7 @@ TEST_F(FlagSyncTest, ThreadSafetyReadersAndWriters) { | |||||||||||||
| const int k_iterations = 5000; | ||||||||||||||
| std::atomic<bool> start_flag{false}; | ||||||||||||||
|
|
||||||||||||||
| auto writer_func = [&]() { | ||||||||||||||
| auto writer_func = [&] { | ||||||||||||||
| while (!start_flag.load()); | ||||||||||||||
|
|
||||||||||||||
| for (int i = 0; i < k_iterations; ++i) { | ||||||||||||||
|
|
@@ -99,11 +99,11 @@ TEST_F(FlagSyncTest, ThreadSafetyReadersAndWriters) { | |||||||||||||
| "metadata": {} | ||||||||||||||
| })"_json; | ||||||||||||||
| update["flags"]["myFlag"]["variants"]["iteration"] = i; | ||||||||||||||
| sync_.TriggerUpdate(update); | ||||||||||||||
| EXPECT_TRUE(sync_.TriggerUpdate(update).ok()); | ||||||||||||||
| } | ||||||||||||||
| }; | ||||||||||||||
|
|
||||||||||||||
| auto reader_func = [&]() { | ||||||||||||||
| auto reader_func = [&] { | ||||||||||||||
| while (!start_flag.load()); | ||||||||||||||
|
|
||||||||||||||
| for (int i = 0; i < k_iterations; ++i) { | ||||||||||||||
|
|
||||||||||||||
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.
Pass
rawusingstd::moveto avoid copying the entire JSON object when callingUpdateFlags. Useautofor the status variable declaration as its type is clearly deduced from the function call.References