Module: OpenFeature::SDK::Contrib::Providers::Common

Included in:
FileProvider, HttpProvider
Defined in:
lib/open_feature/sdk/contrib/providers/common.rb

Defined Under Namespace

Classes: ResolutionDetails

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#cache_durationInteger

Returns:

  • (Integer)


34
35
36
# File 'lib/open_feature/sdk/contrib/providers/common.rb', line 34

def cache_duration
  @cache_duration
end

#custom_parser#call<String> (readonly)

Returns:

  • (#call<String>)


37
38
39
# File 'lib/open_feature/sdk/contrib/providers/common.rb', line 37

def custom_parser
  @custom_parser
end

#deep_keysArray<String> (readonly)

Returns:

  • (Array<String>)


31
32
33
# File 'lib/open_feature/sdk/contrib/providers/common.rb', line 31

def deep_keys
  @deep_keys
end

#extra_optionsHash (readonly)

Returns:

  • (Hash)


19
20
21
# File 'lib/open_feature/sdk/contrib/providers/common.rb', line 19

def extra_options
  @extra_options
end

#formatSymbol (readonly)

Returns:

  • (Symbol)


28
29
30
# File 'lib/open_feature/sdk/contrib/providers/common.rb', line 28

def format
  @format
end

#metadataMetadata (readonly)

Returns:

  • (Metadata)


25
26
27
# File 'lib/open_feature/sdk/contrib/providers/common.rb', line 25

def 
  @metadata
end

#sourceString (readonly)

Returns:

  • (String)


22
23
24
# File 'lib/open_feature/sdk/contrib/providers/common.rb', line 22

def source
  @source
end

Instance Method Details

#expire_cache!Object



65
66
67
68
# File 'lib/open_feature/sdk/contrib/providers/common.rb', line 65

def expire_cache!
  @last_cache    = nil
  @flag_contents = nil
end

#fetch_boolean_value(flag_key:, default_value: nil, evaluation_context: nil) ⇒ Boolean, NilClass

Returns a boolean value for the key specified

Parameters:

  • flag_key (String)

    flag key to search for

  • default_value (Boolean) (defaults to: nil)

    optional default value if one is not found in the file

Returns:

  • (Boolean, NilClass)


80
81
82
83
84
# File 'lib/open_feature/sdk/contrib/providers/common.rb', line 80

def fetch_boolean_value(flag_key:, default_value: nil, evaluation_context: nil)
  source_value = read_value_with_cache(flag_key: flag_key, type: "boolean")

  assert_type(value: source_value, default_value: default_value, return_types: [TrueClass, FalseClass])
end

#fetch_float_value(flag_key:, default_value: nil, evaluation_context: nil) ⇒ Float?

Returns a Float value for the key specified

Parameters:

  • flag_key (String)

    flag key to search for

  • default_value (Float) (defaults to: nil)

    optional default value if one is not found in the file

Returns:

  • (Float, nil)


116
117
118
119
120
# File 'lib/open_feature/sdk/contrib/providers/common.rb', line 116

def fetch_float_value(flag_key:, default_value: nil, evaluation_context: nil)
  source_value = read_value_with_cache(flag_key: flag_key, type: "float")

  assert_type(value: source_value, default_value: default_value, return_types: [Float])
end

#fetch_number_value(flag_key:, default_value: nil, evaluation_context: nil) ⇒ Integer, NilClass

Returns an integer value for the key specified

Parameters:

  • flag_key (String)

    flag key to search for

  • default_value (Integer) (defaults to: nil)

    optional default value if one is not found in the file

Returns:

  • (Integer, NilClass)


104
105
106
107
108
# File 'lib/open_feature/sdk/contrib/providers/common.rb', line 104

def fetch_number_value(flag_key:, default_value: nil, evaluation_context: nil)
  source_value = read_value_with_cache(flag_key: flag_key, type: "number")

  assert_type(value: source_value, default_value: default_value, return_types: [Integer])
end

#fetch_object_value(flag_key:, default_value: nil, evaluation_context: nil) ⇒ Hash, NilClass

Returns a hash value for the key specified

Parameters:

  • flag_key (String)

    flag key to search for

  • default_value (Hash) (defaults to: nil)

    optional default value if one is not found in the file

Returns:

  • (Hash, NilClass)


128
129
130
131
132
# File 'lib/open_feature/sdk/contrib/providers/common.rb', line 128

def fetch_object_value(flag_key:, default_value: nil, evaluation_context: nil)
  source_value = read_value_with_cache(flag_key: flag_key, type: "float")

  assert_type(value: source_value, default_value: default_value, return_types: [Hash])
end

#fetch_raw_key(flag_key:) ⇒ Object



70
71
72
# File 'lib/open_feature/sdk/contrib/providers/common.rb', line 70

def fetch_raw_key(flag_key:)
  read_all_values_with_cache.detect { |f| f["name"] == flag_key }
end

#fetch_string_value(flag_key:, default_value: nil, evaluation_context: nil) ⇒ String, NilClass

Returns a String value for the key specified

Parameters:

  • flag_key (String)

    flag key to search for

  • default_value (String) (defaults to: nil)

    optional default value if one is not found in the file

Returns:

  • (String, NilClass)


92
93
94
95
96
# File 'lib/open_feature/sdk/contrib/providers/common.rb', line 92

def fetch_string_value(flag_key:, default_value: nil, evaluation_context: nil)
  source_value = read_value_with_cache(flag_key: flag_key, type: "string")

  assert_type(value: source_value, default_value: default_value, return_types: [String])
end

#initialize(source:, format: :yaml, deep_keys: [], cache_duration: Float::INFINITY, custom_parser: nil, extra_options: {}) ⇒ Object

Initialize the provider

Parameters:

  • source (String)

    a path to the file, will be evaluated with expand_path

  • file_format (:json, :yaml, :custom)

    format of the file. Can be one of [:yaml, :json]

  • deep_keys (Array<String>) (defaults to: [])

    heirarchy of keys to traverse in the parsed config to get to your feature flags Array. Defaults to [] which will evaluate to the root of the file

  • cache_duration (Integer, Float::INFINITY) (defaults to: Float::INFINITY)

    how long (in seconds) to cache the file contents before reading the file from disk again. If Float::INFINITY is passed, the file will not be reread.

  • custom_parser (#call<String>) (defaults to: nil)

    If your file is not JSON or YAML you can pass a custom parser as a lambda here which will be used to parse the file instead. Even if your file is YAML or JSON you can pass this option if you opt to use a parser other than YAML.load or JSON.parse. The raw file contents will be passed to this Proc.



50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/open_feature/sdk/contrib/providers/common.rb', line 50

def initialize(source:, format: :yaml, deep_keys: [], cache_duration: Float::INFINITY, custom_parser: nil, extra_options: {})
  @source         = source
  @format         = format
  @deep_keys      = deep_keys
  @cache_duration = cache_duration
  @extra_options  = extra_options
  @metadata       = Metadata.new(name: self.class::NAME).freeze

  if format == :yaml && !custom_parser
    require "yaml"
  elsif format == :json && !custom_parser
    require "json"
  end
end

#read_all_values_with_cacheObject



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/open_feature/sdk/contrib/providers/common.rb', line 134

def read_all_values_with_cache
  now = Time.now.to_i

  read_from_cache = if !@flag_contents || !@last_cache
                      false
                    elsif cache_duration == Float::INFINITY
                      true
                    else
                      now - @last_cache < cache_duration
                    end

  unless read_from_cache
    read_and_parse_flags
    @last_cache = Time.now.to_i
  end

  (deep_keys.empty? ? @flag_contents : @flag_contents.dig(*deep_keys) || [])
end