configcat 5.0.2 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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