configcat 5.0.2 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/configcat/configcache.rb +19 -4
- data/lib/configcat/configcatclient.rb +278 -111
- data/lib/configcat/configcatlogger.rb +24 -0
- data/lib/configcat/configcatoptions.rb +153 -0
- data/lib/configcat/configentry.rb +40 -0
- data/lib/configcat/configfetcher.rb +99 -40
- data/lib/configcat/configservice.rb +219 -0
- data/lib/configcat/evaluationdetails.rb +23 -0
- data/lib/configcat/interfaces.rb +4 -59
- data/lib/configcat/localdictionarydatasource.rb +14 -4
- data/lib/configcat/localfiledatasource.rb +22 -11
- data/lib/configcat/overridedatasource.rb +8 -2
- data/lib/configcat/pollingmode.rb +62 -0
- data/lib/configcat/refreshresult.rb +3 -0
- data/lib/configcat/rolloutevaluator.rb +39 -39
- data/lib/configcat/user.rb +18 -39
- data/lib/configcat/utils.rb +10 -0
- data/lib/configcat/version.rb +1 -1
- data/lib/configcat.rb +128 -136
- metadata +24 -5
- data/lib/configcat/autopollingcachepolicy.rb +0 -99
- data/lib/configcat/lazyloadingcachepolicy.rb +0 -69
- data/lib/configcat/manualpollingcachepolicy.rb +0 -47
data/lib/configcat/interfaces.rb
CHANGED
@@ -1,71 +1,16 @@
|
|
1
1
|
module ConfigCat
|
2
|
-
|
3
|
-
class ConfigFetcher
|
4
|
-
#
|
5
|
-
# Config fetcher interface
|
6
|
-
#
|
7
|
-
|
8
|
-
def get_configuration_json()
|
9
|
-
#
|
10
|
-
# :return: Returns the configuration json Dictionary
|
11
|
-
#
|
12
|
-
end
|
13
|
-
|
14
|
-
def close()
|
15
|
-
#
|
16
|
-
# Closes the ConfigFetcher's resources
|
17
|
-
#
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
2
|
+
# Config cache interface
|
21
3
|
class ConfigCache
|
22
|
-
#
|
23
|
-
# Config cache interface
|
24
|
-
#
|
25
|
-
|
4
|
+
# :returns the config json object from the cache
|
26
5
|
def get(key)
|
27
|
-
#
|
28
|
-
# :returns the config json object from the cache
|
29
|
-
#
|
30
6
|
end
|
31
7
|
|
8
|
+
# Sets the config json cache.
|
32
9
|
def set(key, value)
|
33
|
-
#
|
34
|
-
# Sets the config json cache.
|
35
|
-
#
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
class CachePolicy
|
40
|
-
#
|
41
|
-
# Config cache interface
|
42
|
-
#
|
43
|
-
|
44
|
-
def get()
|
45
|
-
#
|
46
|
-
# :returns the config json object from the cache
|
47
|
-
#
|
48
|
-
end
|
49
|
-
|
50
|
-
def force_refresh()
|
51
|
-
#
|
52
|
-
#
|
53
|
-
# :return:
|
54
|
-
#
|
55
|
-
end
|
56
|
-
|
57
|
-
def stop()
|
58
|
-
#
|
59
|
-
#
|
60
|
-
# :return:
|
61
|
-
#
|
62
10
|
end
|
63
11
|
end
|
64
12
|
|
13
|
+
# Generic ConfigCatClientException
|
65
14
|
class ConfigCatClientException < Exception
|
66
|
-
#
|
67
|
-
# Generic ConfigCatClientException
|
68
|
-
#
|
69
15
|
end
|
70
|
-
|
71
16
|
end
|
@@ -3,17 +3,27 @@ require 'configcat/constants'
|
|
3
3
|
|
4
4
|
|
5
5
|
module ConfigCat
|
6
|
+
class LocalDictionaryFlagOverrides < FlagOverrides
|
7
|
+
def initialize(source, override_behaviour)
|
8
|
+
@source = source
|
9
|
+
@override_behaviour = override_behaviour
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_data_source(log)
|
13
|
+
return LocalDictionaryDataSource.new(@source, @override_behaviour)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
6
17
|
class LocalDictionaryDataSource < OverrideDataSource
|
7
18
|
def initialize(source, override_behaviour)
|
8
19
|
super(override_behaviour)
|
9
|
-
|
20
|
+
@_settings = {}
|
10
21
|
source.each do |key, value|
|
11
|
-
|
22
|
+
@_settings[key] = { VALUE => value }
|
12
23
|
end
|
13
|
-
@_settings = {FEATURE_FLAGS => dictionary}
|
14
24
|
end
|
15
25
|
|
16
|
-
def get_overrides
|
26
|
+
def get_overrides
|
17
27
|
return @_settings
|
18
28
|
end
|
19
29
|
end
|
@@ -3,25 +3,37 @@ require 'configcat/constants'
|
|
3
3
|
|
4
4
|
|
5
5
|
module ConfigCat
|
6
|
-
class
|
6
|
+
class LocalFileFlagOverrides < FlagOverrides
|
7
7
|
def initialize(file_path, override_behaviour)
|
8
|
+
@file_path = file_path
|
9
|
+
@override_behaviour = override_behaviour
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_data_source(log)
|
13
|
+
return LocalFileDataSource.new(@file_path, @override_behaviour, log)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class LocalFileDataSource < OverrideDataSource
|
18
|
+
def initialize(file_path, override_behaviour, log)
|
8
19
|
super(override_behaviour)
|
9
|
-
|
10
|
-
|
20
|
+
@log = log
|
21
|
+
if !File.exists?(file_path)
|
22
|
+
@log.error(1300, "Cannot find the local config file '#{file_path}'. This is a path that your application provided to the ConfigCat SDK by passing it to the `LocalFileFlagOverrides.new()` method. Read more: https://configcat.com/docs/sdk-reference/ruby/#json-file")
|
11
23
|
end
|
12
24
|
@_file_path = file_path
|
13
25
|
@_settings = nil
|
14
26
|
@_cached_file_stamp = 0
|
15
27
|
end
|
16
28
|
|
17
|
-
def get_overrides
|
29
|
+
def get_overrides
|
18
30
|
reload_file_content()
|
19
31
|
return @_settings
|
20
32
|
end
|
21
33
|
|
22
34
|
private
|
23
35
|
|
24
|
-
def reload_file_content
|
36
|
+
def reload_file_content
|
25
37
|
begin
|
26
38
|
stamp = File.mtime(@_file_path)
|
27
39
|
if stamp != @_cached_file_stamp
|
@@ -29,20 +41,19 @@ module ConfigCat
|
|
29
41
|
file = File.read(@_file_path)
|
30
42
|
data = JSON.parse(file)
|
31
43
|
if data.key?("flags")
|
32
|
-
|
44
|
+
@_settings = {}
|
33
45
|
source = data["flags"]
|
34
46
|
source.each do |key, value|
|
35
|
-
|
47
|
+
@_settings[key] = { VALUE => value }
|
36
48
|
end
|
37
|
-
@_settings = {FEATURE_FLAGS => dictionary}
|
38
49
|
else
|
39
|
-
@_settings = data
|
50
|
+
@_settings = data[FEATURE_FLAGS]
|
40
51
|
end
|
41
52
|
end
|
42
53
|
rescue JSON::ParserError => e
|
43
|
-
|
54
|
+
@log.error(2302, "Failed to decode JSON from the local config file '#{@_file_path}'. #{e}")
|
44
55
|
rescue Exception => e
|
45
|
-
|
56
|
+
@log.error(1302, "Failed to read the local config file '#{@_file_path}'. #{e}")
|
46
57
|
end
|
47
58
|
end
|
48
59
|
end
|
@@ -15,16 +15,22 @@ module ConfigCat
|
|
15
15
|
REMOTE_OVER_LOCAL = 2
|
16
16
|
end
|
17
17
|
|
18
|
+
class FlagOverrides
|
19
|
+
# :returns [OverrideDataSource] the created OverrideDataSource
|
20
|
+
def create_data_source(log)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
18
24
|
class OverrideDataSource
|
19
25
|
def initialize(override_behaviour)
|
20
26
|
@_override_behaviour = override_behaviour
|
21
27
|
end
|
22
28
|
|
23
|
-
def get_behaviour
|
29
|
+
def get_behaviour
|
24
30
|
return @_override_behaviour
|
25
31
|
end
|
26
32
|
|
27
|
-
def get_overrides
|
33
|
+
def get_overrides
|
28
34
|
# :returns the override dictionary
|
29
35
|
return {}
|
30
36
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module ConfigCat
|
2
|
+
class PollingMode
|
3
|
+
# Creates a configured auto polling configuration.
|
4
|
+
#
|
5
|
+
# :param poll_interval_seconds: sets at least how often this policy should fetch the latest configuration and refresh the cache.
|
6
|
+
# :param max_init_wait_time_seconds: sets the maximum waiting time between initialization and the first config acquisition in seconds.
|
7
|
+
# :return [AutoPollingMode]
|
8
|
+
def self.auto_poll(poll_interval_seconds: 60, max_init_wait_time_seconds: 5)
|
9
|
+
poll_interval_seconds = 1 if poll_interval_seconds < 1
|
10
|
+
max_init_wait_time_seconds = 0 if max_init_wait_time_seconds < 0
|
11
|
+
|
12
|
+
AutoPollingMode.new(poll_interval_seconds, max_init_wait_time_seconds)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Creates a configured lazy loading polling configuration.
|
16
|
+
#
|
17
|
+
# :param cache_refresh_interval_seconds: sets how long the cache will store its value before fetching the latest from the network again.
|
18
|
+
# :return [LazyLoadingMode]
|
19
|
+
def self.lazy_load(cache_refresh_interval_seconds: 60)
|
20
|
+
cache_refresh_interval_seconds = 1 if cache_refresh_interval_seconds < 1
|
21
|
+
|
22
|
+
LazyLoadingMode.new(cache_refresh_interval_seconds)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Creates a configured manual polling configuration.
|
26
|
+
# :return [ManualPollingMode]
|
27
|
+
def self.manual_poll
|
28
|
+
ManualPollingMode.new
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class AutoPollingMode < PollingMode
|
33
|
+
attr_reader :poll_interval_seconds, :max_init_wait_time_seconds
|
34
|
+
|
35
|
+
def initialize(poll_interval_seconds, max_init_wait_time_seconds)
|
36
|
+
@poll_interval_seconds = poll_interval_seconds
|
37
|
+
@max_init_wait_time_seconds = max_init_wait_time_seconds
|
38
|
+
end
|
39
|
+
|
40
|
+
def identifier
|
41
|
+
return "a"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class LazyLoadingMode < PollingMode
|
46
|
+
attr_reader :cache_refresh_interval_seconds
|
47
|
+
|
48
|
+
def initialize(cache_refresh_interval_seconds)
|
49
|
+
@cache_refresh_interval_seconds = cache_refresh_interval_seconds
|
50
|
+
end
|
51
|
+
|
52
|
+
def identifier
|
53
|
+
return "l"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class ManualPollingMode < PollingMode
|
58
|
+
def identifier
|
59
|
+
return "m"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -7,36 +7,39 @@ module ConfigCat
|
|
7
7
|
class RolloutEvaluator
|
8
8
|
COMPARATOR_TEXTS = ["IS ONE OF", "IS NOT ONE OF", "CONTAINS", "DOES NOT CONTAIN", "IS ONE OF (SemVer)", "IS NOT ONE OF (SemVer)", "< (SemVer)", "<= (SemVer)", "> (SemVer)", ">= (SemVer)", "= (Number)", "<> (Number)", "< (Number)", "<= (Number)", "> (Number)", ">= (Number)"]
|
9
9
|
|
10
|
-
def
|
11
|
-
|
12
|
-
|
13
|
-
feature_flags = config.fetch(FEATURE_FLAGS, nil)
|
14
|
-
if feature_flags === nil
|
15
|
-
ConfigCat.logger.error("Evaluating get_value('%s') failed. Value not found for key '%s' Returning default_value: [%s]." % [key, key, default_value.to_s])
|
16
|
-
return default_value, default_variation_id
|
17
|
-
end
|
10
|
+
def initialize(log)
|
11
|
+
@log = log
|
12
|
+
end
|
18
13
|
|
19
|
-
|
14
|
+
# :returns value, variation_id. matched_evaluation_rule, matched_evaluation_percentage_rule, error
|
15
|
+
def evaluate(key:, user:, default_value:, default_variation_id:, settings:)
|
16
|
+
setting_descriptor = settings[key]
|
20
17
|
if setting_descriptor === nil
|
21
|
-
|
22
|
-
|
18
|
+
error = "Failed to evaluate setting '#{key}' (the key was not found in config JSON). " \
|
19
|
+
"Returning the `default_value` parameter that you specified in your application: '#{default_value}'. " \
|
20
|
+
"Available keys: [#{settings.keys.map { |s| "'#{s}'" }.join(", ")}]."
|
21
|
+
@log.error(1001, error)
|
22
|
+
return default_value, default_variation_id, nil, nil, error
|
23
23
|
end
|
24
24
|
|
25
25
|
rollout_rules = setting_descriptor.fetch(ROLLOUT_RULES, [])
|
26
26
|
rollout_percentage_items = setting_descriptor.fetch(ROLLOUT_PERCENTAGE_ITEMS, [])
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
user_has_invalid_type = !user.equal?(nil) && !user.class.equal?(User)
|
29
|
+
if user_has_invalid_type
|
30
|
+
@log.warn(4001, "Cannot evaluate targeting rules and % options for setting '#{key}' (User Object is not an instance of User type).")
|
30
31
|
user = nil
|
31
32
|
end
|
32
33
|
if user === nil
|
33
|
-
if rollout_rules.size > 0 || rollout_percentage_items.size > 0
|
34
|
-
|
34
|
+
if !user_has_invalid_type && (rollout_rules.size > 0 || rollout_percentage_items.size > 0)
|
35
|
+
@log.warn(3001, "Cannot evaluate targeting rules and % options for setting '#{key}' (User Object is missing). " \
|
36
|
+
"You should pass a User Object to the evaluation methods like `get_value()` in order to make targeting work properly. " \
|
37
|
+
"Read more: https://configcat.com/docs/advanced/user-object/")
|
35
38
|
end
|
36
39
|
return_value = setting_descriptor.fetch(VALUE, default_value)
|
37
40
|
return_variation_id = setting_descriptor.fetch(VARIATION_ID, default_variation_id)
|
38
|
-
|
39
|
-
return return_value, return_variation_id
|
41
|
+
@log.info(5000, "Returning [#{return_value}]")
|
42
|
+
return return_value, return_variation_id, nil, nil, nil
|
40
43
|
end
|
41
44
|
|
42
45
|
log_entries = ["Evaluating get_value('%s')." % key, "User object:\n%s" % user.to_s]
|
@@ -61,25 +64,25 @@ module ConfigCat
|
|
61
64
|
if comparator == 0
|
62
65
|
if comparison_value.to_s.split(",").map { |x| x.strip() }.include?(user_value.to_s)
|
63
66
|
log_entries.push(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
|
64
|
-
return value, variation_id
|
67
|
+
return value, variation_id, rollout_rule, nil, nil
|
65
68
|
end
|
66
69
|
# IS NOT ONE OF
|
67
70
|
elsif comparator == 1
|
68
71
|
if !comparison_value.to_s.split(",").map { |x| x.strip() }.include?(user_value.to_s)
|
69
72
|
log_entries.push(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
|
70
|
-
return value, variation_id
|
73
|
+
return value, variation_id, rollout_rule, nil, nil
|
71
74
|
end
|
72
75
|
# CONTAINS
|
73
76
|
elsif comparator == 2
|
74
77
|
if user_value.to_s.include?(comparison_value.to_s)
|
75
78
|
log_entries.push(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
|
76
|
-
return value, variation_id
|
79
|
+
return value, variation_id, rollout_rule, nil, nil
|
77
80
|
end
|
78
81
|
# DOES NOT CONTAIN
|
79
82
|
elsif comparator == 3
|
80
83
|
if !user_value.to_s.include?(comparison_value.to_s)
|
81
84
|
log_entries.push(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
|
82
|
-
return value, variation_id
|
85
|
+
return value, variation_id, rollout_rule, nil, nil
|
83
86
|
end
|
84
87
|
# IS ONE OF, IS NOT ONE OF (Semantic version)
|
85
88
|
elsif (4 <= comparator) && (comparator <= 5)
|
@@ -92,11 +95,11 @@ module ConfigCat
|
|
92
95
|
}
|
93
96
|
if match && comparator == 4 || !match && comparator == 5
|
94
97
|
log_entries.push(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
|
95
|
-
return value, variation_id
|
98
|
+
return value, variation_id, rollout_rule, nil, nil
|
96
99
|
end
|
97
100
|
rescue ArgumentError => e
|
98
101
|
message = format_validation_error_rule(comparison_attribute, user_value, comparator, comparison_value, e.to_s)
|
99
|
-
|
102
|
+
@log.warn(0, message)
|
100
103
|
log_entries.push(message)
|
101
104
|
next
|
102
105
|
end
|
@@ -110,11 +113,11 @@ module ConfigCat
|
|
110
113
|
(comparator == 8 && user_value_version > comparison_value_version) ||
|
111
114
|
(comparator == 9 && user_value_version >= comparison_value_version)
|
112
115
|
log_entries.push(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
|
113
|
-
return value, variation_id
|
116
|
+
return value, variation_id, rollout_rule, nil, nil
|
114
117
|
end
|
115
118
|
rescue ArgumentError => e
|
116
119
|
message = format_validation_error_rule(comparison_attribute, user_value, comparator, comparison_value, e.to_s)
|
117
|
-
|
120
|
+
@log.warn(0, message)
|
118
121
|
log_entries.push(message)
|
119
122
|
next
|
120
123
|
end
|
@@ -129,11 +132,11 @@ module ConfigCat
|
|
129
132
|
(comparator == 14 && user_value_float > comparison_value_float) ||
|
130
133
|
(comparator == 15 && user_value_float >= comparison_value_float)
|
131
134
|
log_entries.push(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
|
132
|
-
return value, variation_id
|
135
|
+
return value, variation_id, rollout_rule, nil, nil
|
133
136
|
end
|
134
137
|
rescue Exception => e
|
135
138
|
message = format_validation_error_rule(comparison_attribute, user_value, comparator, comparison_value, e.to_s)
|
136
|
-
|
139
|
+
@log.warn(0, message)
|
137
140
|
log_entries.push(message)
|
138
141
|
next
|
139
142
|
end
|
@@ -141,13 +144,13 @@ module ConfigCat
|
|
141
144
|
elsif comparator == 16
|
142
145
|
if comparison_value.to_s.split(",").map { |x| x.strip() }.include?(Digest::SHA1.hexdigest(user_value).to_s)
|
143
146
|
log_entries.push(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
|
144
|
-
return value, variation_id
|
147
|
+
return value, variation_id, rollout_rule, nil, nil
|
145
148
|
end
|
146
149
|
# IS NOT ONE OF (Sensitive)
|
147
150
|
elsif comparator == 17
|
148
151
|
if !comparison_value.to_s.split(",").map { |x| x.strip() }.include?(Digest::SHA1.hexdigest(user_value).to_s)
|
149
152
|
log_entries.push(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
|
150
|
-
return value, variation_id
|
153
|
+
return value, variation_id, rollout_rule, nil, nil
|
151
154
|
end
|
152
155
|
end
|
153
156
|
log_entries.push(format_no_match_rule(comparison_attribute, user_value, comparator, comparison_value))
|
@@ -156,7 +159,7 @@ module ConfigCat
|
|
156
159
|
if rollout_percentage_items.size > 0
|
157
160
|
user_key = user.get_identifier()
|
158
161
|
hash_candidate = ("%s%s" % [key, user_key]).encode("utf-8")
|
159
|
-
hash_val = Digest::SHA1.hexdigest(hash_candidate)[0...7].to_i(base=16) % 100
|
162
|
+
hash_val = Digest::SHA1.hexdigest(hash_candidate)[0...7].to_i(base = 16) % 100
|
160
163
|
bucket = 0
|
161
164
|
for rollout_percentage_item in rollout_percentage_items || []
|
162
165
|
bucket += rollout_percentage_item.fetch(PERCENTAGE, 0)
|
@@ -164,34 +167,31 @@ module ConfigCat
|
|
164
167
|
percentage_value = rollout_percentage_item.fetch(VALUE, nil)
|
165
168
|
variation_id = rollout_percentage_item.fetch(VARIATION_ID, default_variation_id)
|
166
169
|
log_entries.push("Evaluating %% options. Returning %s" % percentage_value)
|
167
|
-
return percentage_value, variation_id
|
170
|
+
return percentage_value, variation_id, nil, rollout_percentage_item, nil
|
168
171
|
end
|
169
172
|
end
|
170
173
|
end
|
171
174
|
return_value = setting_descriptor.fetch(VALUE, default_value)
|
172
175
|
return_variation_id = setting_descriptor.fetch(VARIATION_ID, default_variation_id)
|
173
176
|
log_entries.push("Returning %s" % return_value)
|
174
|
-
return return_value, return_variation_id
|
177
|
+
return return_value, return_variation_id, nil, nil, nil
|
175
178
|
ensure
|
176
|
-
|
179
|
+
@log.info(5000, log_entries.join("\n"))
|
177
180
|
end
|
178
181
|
end
|
179
182
|
|
180
183
|
private
|
181
184
|
|
182
|
-
def
|
185
|
+
def format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value)
|
183
186
|
return "Evaluating rule: [%s:%s] [%s] [%s] => match, returning: %s" % [comparison_attribute, user_value, COMPARATOR_TEXTS[comparator], comparison_value, value]
|
184
187
|
end
|
185
188
|
|
186
|
-
def
|
189
|
+
def format_no_match_rule(comparison_attribute, user_value, comparator, comparison_value)
|
187
190
|
return "Evaluating rule: [%s:%s] [%s] [%s] => no match" % [comparison_attribute, user_value, COMPARATOR_TEXTS[comparator], comparison_value]
|
188
191
|
end
|
189
192
|
|
190
|
-
def
|
193
|
+
def format_validation_error_rule(comparison_attribute, user_value, comparator, comparison_value, error)
|
191
194
|
return "Evaluating rule: [%s:%s] [%s] [%s] => SKIP rule. Validation error: %s" % [comparison_attribute, user_value, COMPARATOR_TEXTS[comparator], comparison_value, error]
|
192
195
|
end
|
193
|
-
|
194
196
|
end
|
195
|
-
|
196
197
|
end
|
197
|
-
|
data/lib/configcat/user.rb
CHANGED
@@ -1,56 +1,35 @@
|
|
1
1
|
module ConfigCat
|
2
|
-
|
2
|
+
# The user object for variation evaluation
|
3
3
|
class User
|
4
|
-
#
|
5
|
-
# The user object for variation evaluation
|
6
|
-
#
|
7
|
-
|
8
4
|
PREDEFINED = ["Identifier", "Email", "Country"]
|
9
5
|
|
6
|
+
attr_reader :identifier
|
7
|
+
|
10
8
|
def initialize(identifier, email: nil, country: nil, custom: nil)
|
11
|
-
@
|
12
|
-
@
|
13
|
-
@
|
9
|
+
@identifier = (!identifier.equal?(nil)) ? identifier : ""
|
10
|
+
@data = { "Identifier" => identifier, "Email" => email, "Country" => country }
|
11
|
+
@custom = custom
|
14
12
|
end
|
15
13
|
|
16
|
-
def get_identifier
|
17
|
-
return @
|
14
|
+
def get_identifier
|
15
|
+
return @identifier
|
18
16
|
end
|
19
17
|
|
20
18
|
def get_attribute(attribute)
|
21
19
|
attribute = attribute.to_s
|
22
|
-
if PREDEFINED.include?(attribute)
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
if !@__custom.equal?(nil)
|
27
|
-
@__custom.each do |customField, customValue|
|
28
|
-
if customField.to_s == attribute
|
29
|
-
return customValue
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
20
|
+
return @data[attribute] if PREDEFINED.include?(attribute)
|
21
|
+
return @custom[attribute] if @custom
|
33
22
|
return nil
|
34
23
|
end
|
35
24
|
|
36
|
-
def to_s
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
if !@__custom.equal?(nil)
|
45
|
-
r += %Q(,\n "Custom": {)
|
46
|
-
for customField in @__custom
|
47
|
-
r += %Q(\n "#{customField}": "#{@__custom[customField]}",)
|
48
|
-
end
|
49
|
-
r += "\n }"
|
50
|
-
end
|
51
|
-
r += "\n}"
|
52
|
-
return r
|
25
|
+
def to_s
|
26
|
+
dump = {
|
27
|
+
'Identifier': @identifier,
|
28
|
+
'Email': @data['Email'],
|
29
|
+
'Country': @data['Country'],
|
30
|
+
'Custom': @custom,
|
31
|
+
}
|
32
|
+
return dump.to_json
|
53
33
|
end
|
54
34
|
end
|
55
|
-
|
56
35
|
end
|
data/lib/configcat/version.rb
CHANGED