From c58f3abbd43bf667cbe60722c542be7cffb03169 Mon Sep 17 00:00:00 2001 From: Thomas Poignant Date: Fri, 24 Jan 2025 17:48:51 +0100 Subject: [PATCH 1/2] feat(go-feature-flag): Support exporter metadata Signed-off-by: Thomas Poignant --- .../go_feature_flag_provider.rb | 5 +++ .../openfeature/go-feature-flag/options.rb | 5 ++- .../gofeatureflag/provider_spec.rb | 37 +++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/providers/openfeature-go-feature-flag-provider/lib/openfeature/go-feature-flag/go_feature_flag_provider.rb b/providers/openfeature-go-feature-flag-provider/lib/openfeature/go-feature-flag/go_feature_flag_provider.rb index 9cb6f24..5806f05 100644 --- a/providers/openfeature-go-feature-flag-provider/lib/openfeature/go-feature-flag/go_feature_flag_provider.rb +++ b/providers/openfeature-go-feature-flag-provider/lib/openfeature/go-feature-flag/go_feature_flag_provider.rb @@ -35,6 +35,11 @@ def evaluate(flag_key:, default_value:, allowed_classes:, evaluation_context: ni evaluation_context = OpenFeature::SDK::EvaluationContext.new if evaluation_context.nil? validate_parameters(flag_key, evaluation_context) + # enrich the evaluation context with the exporter_metadata + @options.exporter_metadata ||= {} + @options.exporter_metadata.merge!({"openfeature" => true, "provider" => "ruby"}) + evaluation_context.fields["gofeatureflag"] = {"exporterMetadata" => @options.exporter_metadata} + # do a http call to the go feature flag server parsed_response = @goff_api.evaluate_ofrep_api(flag_key: flag_key, evaluation_context: evaluation_context) parsed_response = OfrepApiResponse unless parsed_response.is_a?(OfrepApiResponse) diff --git a/providers/openfeature-go-feature-flag-provider/lib/openfeature/go-feature-flag/options.rb b/providers/openfeature-go-feature-flag-provider/lib/openfeature/go-feature-flag/options.rb index 609b5fa..5f24bf3 100644 --- a/providers/openfeature-go-feature-flag-provider/lib/openfeature/go-feature-flag/options.rb +++ b/providers/openfeature-go-feature-flag-provider/lib/openfeature/go-feature-flag/options.rb @@ -6,12 +6,13 @@ module OpenFeature module GoFeatureFlag # This class is the configuration class for the GoFeatureFlagProvider class Options - attr_accessor :endpoint, :custom_headers + attr_accessor :endpoint, :custom_headers, :exporter_metadata - def initialize(endpoint: nil, headers: {}) + def initialize(endpoint: nil, headers: {}, exporter_metadata: nil) validate_endpoint(endpoint: endpoint) @endpoint = endpoint @custom_headers = headers + @exporter_metadata = exporter_metadata end private diff --git a/providers/openfeature-go-feature-flag-provider/spec/openfeature/gofeatureflag/provider_spec.rb b/providers/openfeature-go-feature-flag-provider/spec/openfeature/gofeatureflag/provider_spec.rb index 30b17d1..5bdd49d 100644 --- a/providers/openfeature-go-feature-flag-provider/spec/openfeature/gofeatureflag/provider_spec.rb +++ b/providers/openfeature-go-feature-flag-provider/spec/openfeature/gofeatureflag/provider_spec.rb @@ -684,4 +684,41 @@ expect(eval).to eql(want) end end + + context "#exporter_metadata" do + it "should send exporter_metadata in the API if set in provider" do + test_name = RSpec.current_example.description + request_body = nil + stub_request(:post, "http://localhost:1031/ofrep/v1/evaluate/flags/boolean_flag") + .with { |req| request_body = req.body } + .to_return(status: 200, body: + { + key: "double_key", + metadata: {"website" => "https://gofeatureflag.org"}, + value: true, + reason: "TARGETING_MATCH", + variant: "variantA" + }.to_json) + + options = OpenFeature::GoFeatureFlag::Options.new(endpoint: "http://localhost:1031", exporter_metadata: { + "key1" => "value1", + "key2" => 123, + "key3" => 123.45 + }) + goff_test_provider = OpenFeature::GoFeatureFlag::Provider.new(options: options) + + OpenFeature::SDK.configure do |config| + config.set_provider(goff_test_provider, domain: test_name) + end + client = OpenFeature::SDK.build_client(domain: test_name) + client.fetch_boolean_details( + flag_key: "boolean_flag", + default_value: false, + evaluation_context: OpenFeature::SDK::EvaluationContext.new(targeting_key: "9b9450f8-ab5c-4dcf-872f-feda3f6ccb16") + ) + got = JSON.parse(request_body) + want = JSON.parse('{"context":{"gofeatureflag":{"exporterMetadata":{"key1":"value1","openfeature":true,"provider":"ruby", "key2": 123, "key3":123.45}},"targetingKey":"9b9450f8-ab5c-4dcf-872f-feda3f6ccb16"}}') + expect(got).to eql(want) + end + end end From 278b12064d9ffb02ada4a1bd5efd594bc56e9090 Mon Sep 17 00:00:00 2001 From: Thomas Poignant Date: Sat, 25 Jan 2025 10:01:26 +0100 Subject: [PATCH 2/2] fix nit review comment Signed-off-by: Thomas Poignant --- .../openfeature/go-feature-flag/go_feature_flag_provider.rb | 3 +-- .../lib/openfeature/go-feature-flag/options.rb | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/providers/openfeature-go-feature-flag-provider/lib/openfeature/go-feature-flag/go_feature_flag_provider.rb b/providers/openfeature-go-feature-flag-provider/lib/openfeature/go-feature-flag/go_feature_flag_provider.rb index 5806f05..dc00f78 100644 --- a/providers/openfeature-go-feature-flag-provider/lib/openfeature/go-feature-flag/go_feature_flag_provider.rb +++ b/providers/openfeature-go-feature-flag-provider/lib/openfeature/go-feature-flag/go_feature_flag_provider.rb @@ -36,8 +36,7 @@ def evaluate(flag_key:, default_value:, allowed_classes:, evaluation_context: ni validate_parameters(flag_key, evaluation_context) # enrich the evaluation context with the exporter_metadata - @options.exporter_metadata ||= {} - @options.exporter_metadata.merge!({"openfeature" => true, "provider" => "ruby"}) + @options.exporter_metadata.merge!("openfeature" => true, "provider" => "ruby") evaluation_context.fields["gofeatureflag"] = {"exporterMetadata" => @options.exporter_metadata} # do a http call to the go feature flag server diff --git a/providers/openfeature-go-feature-flag-provider/lib/openfeature/go-feature-flag/options.rb b/providers/openfeature-go-feature-flag-provider/lib/openfeature/go-feature-flag/options.rb index 5f24bf3..823fe7b 100644 --- a/providers/openfeature-go-feature-flag-provider/lib/openfeature/go-feature-flag/options.rb +++ b/providers/openfeature-go-feature-flag-provider/lib/openfeature/go-feature-flag/options.rb @@ -8,7 +8,7 @@ module GoFeatureFlag class Options attr_accessor :endpoint, :custom_headers, :exporter_metadata - def initialize(endpoint: nil, headers: {}, exporter_metadata: nil) + def initialize(endpoint: nil, headers: {}, exporter_metadata: {}) validate_endpoint(endpoint: endpoint) @endpoint = endpoint @custom_headers = headers