|
| 1 | +# frozen_string_literal: true |
| 2 | + |
| 3 | +require 'json' |
| 4 | +require_relative 'ext' |
| 5 | +require_relative 'resolution_details' |
| 6 | + |
| 7 | +module Datadog |
| 8 | + module OpenFeature |
| 9 | + # Evaluation using native extension |
| 10 | + class NativeEvaluator |
| 11 | + def initialize(configuration) |
| 12 | + @libdatadog_api_failure = Datadog::Core::LIBDATADOG_API_FAILURE |
| 13 | + if configuration && !@libdatadog_api_failure |
| 14 | + @configuration = Datadog::Core::FeatureFlags::Configuration.new(configuration) |
| 15 | + end |
| 16 | + end |
| 17 | + |
| 18 | + def get_assignment(flag_key, default_value, context, expected_type) |
| 19 | + return build_fatal_error(default_value) if @libdatadog_api_failure |
| 20 | + |
| 21 | + configuration = @configuration |
| 22 | + return build_not_ready_error(default_value) if configuration.nil? |
| 23 | + |
| 24 | + native_details = configuration.get_assignment(flag_key, expected_type.to_sym, context) |
| 25 | + |
| 26 | + variant = native_details.variant |
| 27 | + value = native_details.value |
| 28 | + if expected_type == 'object' && value.is_a?(String) |
| 29 | + # JSON flags return value as string. We need to parse it. |
| 30 | + value = JSON.parse(value) |
| 31 | + elsif variant.nil? |
| 32 | + value = default_value |
| 33 | + end |
| 34 | + |
| 35 | + ResolutionDetails.new( |
| 36 | + value: value, |
| 37 | + variant: variant, |
| 38 | + allocation_key: native_details.allocation_key, |
| 39 | + reason: native_details.reason, |
| 40 | + error?: native_details.error?, |
| 41 | + error_code: native_details.error_code, |
| 42 | + error_message: native_details.error_message, |
| 43 | + log?: native_details.log?, |
| 44 | + flag_metadata: native_details.flag_metadata, |
| 45 | + ) |
| 46 | + rescue JSON::ParserError => e |
| 47 | + ResolutionDetails.build_error( |
| 48 | + value: default_value, |
| 49 | + error_code: 'PARSE_ERROR', |
| 50 | + error_message: "Failed to parse JSON value: #{e.message}" |
| 51 | + ) |
| 52 | + end |
| 53 | + |
| 54 | + private |
| 55 | + |
| 56 | + def build_fatal_error(default_value) |
| 57 | + ResolutionDetails.build_error( |
| 58 | + value: default_value, |
| 59 | + error_code: Ext::PROVIDER_FATAL, |
| 60 | + error_message: "libdatadog is not available: #{@libdatadog_api_failure}" |
| 61 | + ) |
| 62 | + end |
| 63 | + |
| 64 | + def build_not_ready_error(default_value) |
| 65 | + ResolutionDetails.build_error( |
| 66 | + value: default_value, |
| 67 | + error_code: Ext::PROVIDER_NOT_READY, |
| 68 | + error_message: 'Configuration not available' |
| 69 | + ) |
| 70 | + end |
| 71 | + end |
| 72 | + end |
| 73 | +end |
0 commit comments