configcat 1.2.3 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b1a942248d64106cb8d048e1b036bb0d9533ddec927e6c40de53792c7cb50a2
4
- data.tar.gz: 1fc92424f560cb36f8fc272fca29c7fbeba155f734cd9269bcba75614d632e78
3
+ metadata.gz: b842d2ff2f62e6a6c3dbe2ddab53c561e4b1db93f3928ce805044127cd2d7819
4
+ data.tar.gz: 6d64d084c4a732d26d54879d914f4e9ce1722b9e73fee2aa4161cc5503e152d7
5
5
  SHA512:
6
- metadata.gz: dfcb859602316a2c538230088fd3b49739173ed2edaf927886b000a497d18a4c9c2857c06fdb40280a22715f6cf2c9d5390a5697c3aedbc95e0e697aff3f3fbf
7
- data.tar.gz: 2d9dc0884143badeee4a246037abb80c09bd2cae1247241ca7d750647f67951bb45b23d3be17768468968ac9ea81f1e66156b5e2b152a678dbaf943274aade27
6
+ metadata.gz: 83a7d19dc642e492bb5443a1fc42f0f35db8f5278f02582848e8677133f4450faa41a1a30b158ccdca58bc5396cad109b914fa4851e4db74dcf03df1f5129d00
7
+ data.tar.gz: 2e79ed9965f3c9da2f8afd9fed4636b6d349b0bda09fdfb0d8398b6e4334a458713114d23083fc5f611878ea02801c5e8ea1e73fad54f6e580ef1c098e8f9d7c
@@ -10,16 +10,16 @@ module ConfigCat
10
10
  attr_accessor :logger
11
11
  end
12
12
 
13
- def ConfigCat.create_client(api_key)
13
+ def ConfigCat.create_client(sdk_key)
14
14
  #
15
15
  # Create an instance of ConfigCatClient and setup Auto Poll mode with default options
16
16
  #
17
- # :param api_key: ConfigCat ApiKey to access your configuration.
17
+ # :param sdk_key: ConfigCat SDK Key to access your configuration.
18
18
  #
19
- return create_client_with_auto_poll(api_key)
19
+ return create_client_with_auto_poll(sdk_key)
20
20
  end
21
21
 
22
- def ConfigCat.create_client_with_auto_poll(api_key,
22
+ def ConfigCat.create_client_with_auto_poll(sdk_key,
23
23
  poll_interval_seconds: 60,
24
24
  max_init_wait_time_seconds: 5,
25
25
  on_configuration_changed_callback: nil,
@@ -32,7 +32,7 @@ module ConfigCat
32
32
  #
33
33
  # Create an instance of ConfigCatClient and setup Auto Poll mode with custom options
34
34
  #
35
- # :param api_key: ConfigCat ApiKey to access your configuration.
35
+ # :param sdk_key: ConfigCat SDK Key to access your configuration.
36
36
  # :param poll_interval_seconds: The client's poll interval in seconds. Default: 60 seconds.
37
37
  # :param on_configuration_changed_callback: You can subscribe to configuration changes with this callback
38
38
  # :param max_init_wait_time_seconds: maximum waiting time for first configuration fetch in polling mode.
@@ -44,8 +44,8 @@ module ConfigCat
44
44
  # :param proxy_user: username for proxy authentication
45
45
  # :param proxy_pass: password for proxy authentication
46
46
  #
47
- if api_key === nil
48
- raise ConfigCatClientException, "API Key is required."
47
+ if sdk_key === nil
48
+ raise ConfigCatClientException, "SDK Key is required."
49
49
  end
50
50
  if poll_interval_seconds < 1
51
51
  poll_interval_seconds = 1
@@ -53,7 +53,7 @@ module ConfigCat
53
53
  if max_init_wait_time_seconds < 0
54
54
  max_init_wait_time_seconds = 0
55
55
  end
56
- return ConfigCatClient.new(api_key,
56
+ return ConfigCatClient.new(sdk_key,
57
57
  poll_interval_seconds: poll_interval_seconds,
58
58
  max_init_wait_time_seconds: max_init_wait_time_seconds,
59
59
  on_configuration_changed_callback: on_configuration_changed_callback,
@@ -66,7 +66,7 @@ module ConfigCat
66
66
  proxy_pass: proxy_pass)
67
67
  end
68
68
 
69
- def ConfigCat.create_client_with_lazy_load(api_key,
69
+ def ConfigCat.create_client_with_lazy_load(sdk_key,
70
70
  cache_time_to_live_seconds: 60,
71
71
  config_cache_class: nil,
72
72
  base_url: nil,
@@ -77,7 +77,7 @@ module ConfigCat
77
77
  #
78
78
  # Create an instance of ConfigCatClient and setup Lazy Load mode with custom options
79
79
  #
80
- # :param api_key: ConfigCat ApiKey to access your configuration.
80
+ # :param sdk_key: ConfigCat SDK Key to access your configuration.
81
81
  # :param cache_time_to_live_seconds: The cache TTL.
82
82
  # :param config_cache_class: If you want to use custom caching instead of the client's default InMemoryConfigCache,
83
83
  # You can provide an implementation of ConfigCache.
@@ -87,13 +87,13 @@ module ConfigCat
87
87
  # :param proxy_user: username for proxy authentication
88
88
  # :param proxy_pass: password for proxy authentication
89
89
  #
90
- if api_key === nil
91
- raise ConfigCatClientException, "API Key is required."
90
+ if sdk_key === nil
91
+ raise ConfigCatClientException, "SDK Key is required."
92
92
  end
93
93
  if cache_time_to_live_seconds < 1
94
94
  cache_time_to_live_seconds = 1
95
95
  end
96
- return ConfigCatClient.new(api_key,
96
+ return ConfigCatClient.new(sdk_key,
97
97
  poll_interval_seconds: 0,
98
98
  max_init_wait_time_seconds: 0,
99
99
  on_configuration_changed_callback: nil,
@@ -106,7 +106,7 @@ module ConfigCat
106
106
  proxy_pass: proxy_pass)
107
107
  end
108
108
 
109
- def ConfigCat.create_client_with_manual_poll(api_key,
109
+ def ConfigCat.create_client_with_manual_poll(sdk_key,
110
110
  config_cache_class: nil,
111
111
  base_url: nil,
112
112
  proxy_address:nil,
@@ -116,7 +116,7 @@ module ConfigCat
116
116
  #
117
117
  # Create an instance of ConfigCatClient and setup Manual Poll mode with custom options
118
118
  #
119
- # :param api_key: ConfigCat ApiKey to access your configuration.
119
+ # :param sdk_key: ConfigCat SDK Key to access your configuration.
120
120
  # :param config_cache_class: If you want to use custom caching instead of the client's default InMemoryConfigCache,
121
121
  # You can provide an implementation of ConfigCache.
122
122
  # :param base_url: You can set a base_url if you want to use a proxy server between your application and ConfigCat
@@ -125,10 +125,10 @@ module ConfigCat
125
125
  # :param proxy_user: username for proxy authentication
126
126
  # :param proxy_pass: password for proxy authentication
127
127
  #
128
- if api_key === nil
129
- raise ConfigCatClientException, "API Key is required."
128
+ if sdk_key === nil
129
+ raise ConfigCatClientException, "SDK Key is required."
130
130
  end
131
- return ConfigCatClient.new(api_key,
131
+ return ConfigCatClient.new(sdk_key,
132
132
  poll_interval_seconds: 0,
133
133
  max_init_wait_time_seconds: 0,
134
134
  on_configuration_changed_callback: nil,
@@ -48,7 +48,7 @@ module ConfigCat
48
48
 
49
49
  def force_refresh()
50
50
  begin
51
- configuration = @_config_fetcher.get_configuration_json()
51
+ configuration_response = @_config_fetcher.get_configuration_json()
52
52
 
53
53
  begin
54
54
  @_lock.acquire_read_lock()
@@ -57,20 +57,23 @@ module ConfigCat
57
57
  @_lock.release_read_lock()
58
58
  end
59
59
 
60
- if configuration != old_configuration
61
- begin
62
- @_lock.acquire_write_lock()
63
- @_config_cache.set(configuration)
64
- @_initialized = true
65
- ensure
66
- @_lock.release_write_lock()
67
- end
68
- begin
69
- if !@_on_configuration_changed_callback.equal?(nil)
70
- @_on_configuration_changed_callback.()
60
+ if configuration_response.is_fetched()
61
+ configuration = configuration_response.json()
62
+ if configuration != old_configuration
63
+ begin
64
+ @_lock.acquire_write_lock()
65
+ @_config_cache.set(configuration)
66
+ @_initialized = true
67
+ ensure
68
+ @_lock.release_write_lock()
69
+ end
70
+ begin
71
+ if !@_on_configuration_changed_callback.equal?(nil)
72
+ @_on_configuration_changed_callback.()
73
+ end
74
+ rescue Exception => e
75
+ ConfigCat.logger.error("Exception in on_configuration_changed_callback: #{e.class}:'#{e}'")
71
76
  end
72
- rescue Exception => e
73
- ConfigCat.logger.error("Exception in on_configuration_changed_callback: #{e.class}:'#{e}'")
74
77
  end
75
78
  end
76
79
 
@@ -78,7 +81,7 @@ module ConfigCat
78
81
  @_initialized = true
79
82
  end
80
83
  rescue Exception => e
81
- ConfigCat.logger.error("Double-check your API KEY at https://app.configcat.com/apikey.")
84
+ ConfigCat.logger.error("Double-check your SDK Key at https://app.configcat.com/sdkkey.")
82
85
  ConfigCat.logger.error "threw exception #{e.class}:'#{e}'"
83
86
  ConfigCat.logger.error "stacktrace: #{e.backtrace}"
84
87
  end
@@ -7,8 +7,9 @@ require 'configcat/lazyloadingcachepolicy'
7
7
  require 'configcat/rolloutevaluator'
8
8
 
9
9
  module ConfigCat
10
+ KeyValue = Struct.new(:key, :value)
10
11
  class ConfigCatClient
11
- def initialize(api_key,
12
+ def initialize(sdk_key,
12
13
  poll_interval_seconds:60,
13
14
  max_init_wait_time_seconds:5,
14
15
  on_configuration_changed_callback:nil,
@@ -19,10 +20,10 @@ module ConfigCat
19
20
  proxy_port:nil,
20
21
  proxy_user:nil,
21
22
  proxy_pass:nil)
22
- if api_key === nil
23
- raise ConfigCatClientException, "API Key is required."
23
+ if sdk_key === nil
24
+ raise ConfigCatClientException, "SDK Key is required."
24
25
  end
25
- @_api_key = api_key
26
+ @_sdk_key = sdk_key
26
27
 
27
28
  if config_cache_class
28
29
  @_config_cache = config_cache_class.new()
@@ -31,14 +32,14 @@ module ConfigCat
31
32
  end
32
33
 
33
34
  if poll_interval_seconds > 0
34
- @_config_fetcher = CacheControlConfigFetcher.new(api_key, "p", base_url, proxy_address, proxy_port, proxy_user, proxy_pass)
35
+ @_config_fetcher = CacheControlConfigFetcher.new(sdk_key, "p", base_url, proxy_address, proxy_port, proxy_user, proxy_pass)
35
36
  @_cache_policy = AutoPollingCachePolicy.new(@_config_fetcher, @_config_cache, poll_interval_seconds, max_init_wait_time_seconds, on_configuration_changed_callback)
36
37
  else
37
38
  if cache_time_to_live_seconds > 0
38
- @_config_fetcher = CacheControlConfigFetcher.new(api_key, "l", base_url, proxy_address, proxy_port, proxy_user, proxy_pass)
39
+ @_config_fetcher = CacheControlConfigFetcher.new(sdk_key, "l", base_url, proxy_address, proxy_port, proxy_user, proxy_pass)
39
40
  @_cache_policy = LazyLoadingCachePolicy.new(@_config_fetcher, @_config_cache, cache_time_to_live_seconds)
40
41
  else
41
- @_config_fetcher = CacheControlConfigFetcher.new(api_key, "m", base_url, proxy_address, proxy_port, proxy_user, proxy_pass)
42
+ @_config_fetcher = CacheControlConfigFetcher.new(sdk_key, "m", base_url, proxy_address, proxy_port, proxy_user, proxy_pass)
42
43
  @_cache_policy = ManualPollingCachePolicy.new(@_config_fetcher, @_config_cache)
43
44
  end
44
45
  end
@@ -49,7 +50,8 @@ module ConfigCat
49
50
  if config === nil
50
51
  return default_value
51
52
  end
52
- return RolloutEvaluator.evaluate(key, user, default_value, config)
53
+ value, variation_id = RolloutEvaluator.evaluate(key, user, default_value, nil, config)
54
+ return value
53
55
  end
54
56
 
55
57
  def get_all_keys()
@@ -60,6 +62,57 @@ module ConfigCat
60
62
  return config.keys
61
63
  end
62
64
 
65
+ def get_variation_id(key, default_variation_id, user=nil)
66
+ config = @_cache_policy.get()
67
+ if config === nil
68
+ ConfigCat.logger.warn("Evaluating get_variation_id('%s') failed. Cache is empty. "\
69
+ "Returning default_variation_id in your get_variation_id call: [%s]." %
70
+ [key, default_variation_id.to_s])
71
+ return default_variation_id
72
+ end
73
+ value, variation_id = RolloutEvaluator.evaluate(key, user, nil, default_variation_id, config)
74
+ return variation_id
75
+ end
76
+
77
+ def get_all_variation_ids(user: nil)
78
+ keys = get_all_keys()
79
+ variation_ids = []
80
+ for key in keys
81
+ variation_id = get_variation_id(key, nil, user)
82
+ if !variation_id.equal?(nil)
83
+ variation_ids.push(variation_id)
84
+ end
85
+ end
86
+ return variation_ids
87
+ end
88
+
89
+ def get_key_and_value(variation_id)
90
+ config = @_cache_policy.get()
91
+ if config === nil
92
+ ConfigCat.logger.warn("Evaluating get_variation_id('%s') failed. Cache is empty. Returning nil." % variation_id)
93
+ return nil
94
+ end
95
+ for key, value in config
96
+ if variation_id == value.fetch(RolloutEvaluator::VARIATION_ID, nil)
97
+ return KeyValue.new(key, value[RolloutEvaluator::VALUE])
98
+ end
99
+
100
+ rollout_rules = value.fetch(RolloutEvaluator::ROLLOUT_RULES, [])
101
+ for rollout_rule in rollout_rules
102
+ if variation_id == rollout_rule.fetch(RolloutEvaluator::VARIATION_ID, nil)
103
+ return KeyValue.new(key, rollout_rule[RolloutEvaluator::VALUE])
104
+ end
105
+ end
106
+
107
+ rollout_percentage_items = value.fetch(RolloutEvaluator::ROLLOUT_PERCENTAGE_ITEMS, [])
108
+ for rollout_percentage_item in rollout_percentage_items
109
+ if variation_id == rollout_percentage_item.fetch(RolloutEvaluator::VARIATION_ID, nil)
110
+ return KeyValue.new(key, rollout_percentage_item[RolloutEvaluator::VALUE])
111
+ end
112
+ end
113
+ end
114
+ end
115
+
63
116
  def force_refresh()
64
117
  @_cache_policy.force_refresh()
65
118
  end
@@ -7,12 +7,34 @@ require 'json'
7
7
  module ConfigCat
8
8
  BASE_URL = "https://cdn.configcat.com"
9
9
  BASE_PATH = "configuration-files/"
10
- BASE_EXTENSION = "/config_v3.json"
10
+ BASE_EXTENSION = "/config_v4.json"
11
+
12
+ class FetchResponse
13
+ def initialize(response)
14
+ @_response = response
15
+ end
16
+
17
+ # Returns the json-encoded content of a response, if any
18
+ def json()
19
+ return JSON.parse(@_response.body)
20
+ end
21
+
22
+ # Gets whether a new configuration value was fetched or not
23
+ def is_fetched()
24
+ code = @_response.code.to_i
25
+ return 200 <= code && code < 300
26
+ end
27
+
28
+ # Gets whether the fetch resulted a '304 Not Modified' or not
29
+ def is_not_modified()
30
+ return @_response.code == "304"
31
+ end
32
+ end
11
33
 
12
34
  class CacheControlConfigFetcher < ConfigFetcher
13
- def initialize(api_key, mode, base_url=nil, proxy_address=nil, proxy_port=nil, proxy_user=nil, proxy_pass=nil)
14
- @_api_key = api_key
15
- @_etag = nil
35
+ def initialize(sdk_key, mode, base_url=nil, proxy_address=nil, proxy_port=nil, proxy_user=nil, proxy_pass=nil)
36
+ @_sdk_key = sdk_key
37
+ @_etag = ""
16
38
  @_headers = {"User-Agent" => ((("ConfigCat-Ruby/") + mode) + ("-")) + VERSION, "X-ConfigCat-UserAgent" => ((("ConfigCat-Ruby/") + mode) + ("-")) + VERSION, "Content-Type" => "application/json"}
17
39
  if !base_url.equal?(nil)
18
40
  @_base_url = base_url.chomp("/")
@@ -26,16 +48,18 @@ module ConfigCat
26
48
  @_http.read_timeout = 30 # in seconds
27
49
  end
28
50
 
51
+ # Returns the FetchResponse object contains configuration json Dictionary
29
52
  def get_configuration_json()
30
53
  ConfigCat.logger.debug "Fetching configuration from ConfigCat"
31
- uri = URI.parse((((@_base_url + ("/")) + BASE_PATH) + @_api_key) + BASE_EXTENSION)
32
- @_headers["If-None-Match"] = @_etag unless @_etag.nil?
33
- request = Net::HTTP::Get.new(uri.request_uri, @_headers)
54
+ uri = URI.parse((((@_base_url + ("/")) + BASE_PATH) + @_sdk_key) + BASE_EXTENSION)
55
+ headers = @_headers
56
+ headers["If-None-Match"] = @_etag unless @_etag.empty?
57
+ request = Net::HTTP::Get.new(uri.request_uri, headers)
34
58
  response = @_http.request(request)
35
- json = JSON.parse(response.body)
36
- @_etag = response["ETag"]
59
+ etag = response["ETag"]
60
+ @_etag = etag unless etag.nil? || etag.empty?
37
61
  ConfigCat.logger.debug "ConfigCat configuration json fetch response code:#{response.code} Cached:#{response['ETag']}"
38
- return json
62
+ return FetchResponse.new(response)
39
63
  end
40
64
 
41
65
  def close()
@@ -40,16 +40,19 @@ module ConfigCat
40
40
 
41
41
  def force_refresh()
42
42
  begin
43
- configuration = @_config_fetcher.get_configuration_json()
44
- begin
45
- @_lock.acquire_write_lock()
46
- @_config_cache.set(configuration)
47
- @_last_updated = Time.now.utc
48
- ensure
49
- @_lock.release_write_lock()
43
+ configuration_response = @_config_fetcher.get_configuration_json()
44
+ if configuration_response.is_fetched()
45
+ configuration = configuration_response.json()
46
+ begin
47
+ @_lock.acquire_write_lock()
48
+ @_config_cache.set(configuration)
49
+ @_last_updated = Time.now.utc
50
+ ensure
51
+ @_lock.release_write_lock()
52
+ end
50
53
  end
51
54
  rescue StandardError => e
52
- ConfigCat.logger.error("Double-check your API KEY at https://app.configcat.com/apikey.")
55
+ ConfigCat.logger.error("Double-check your SDK Key at https://app.configcat.com/sdkkey.")
53
56
  ConfigCat.logger.error "threw exception #{e.class}:'#{e}'"
54
57
  ConfigCat.logger.error "stacktrace: #{e.backtrace}"
55
58
  end
@@ -21,15 +21,18 @@ module ConfigCat
21
21
 
22
22
  def force_refresh()
23
23
  begin
24
- configuration = @_config_fetcher.get_configuration_json()
25
- begin
26
- @_lock.acquire_write_lock()
27
- @_config_cache.set(configuration)
28
- ensure
29
- @_lock.release_write_lock()
24
+ configuration_response = @_config_fetcher.get_configuration_json()
25
+ if configuration_response.is_fetched()
26
+ configuration = configuration_response.json()
27
+ begin
28
+ @_lock.acquire_write_lock()
29
+ @_config_cache.set(configuration)
30
+ ensure
31
+ @_lock.release_write_lock()
32
+ end
30
33
  end
31
34
  rescue StandardError => e
32
- ConfigCat.logger.error("Double-check your API KEY at https://app.configcat.com/apikey.")
35
+ ConfigCat.logger.error("Double-check your SDK Key at https://app.configcat.com/sdkkey.")
33
36
  ConfigCat.logger.error "threw exception #{e.class}:'#{e}'"
34
37
  ConfigCat.logger.error "stacktrace: #{e.backtrace}"
35
38
  end
@@ -13,14 +13,15 @@ module ConfigCat
13
13
  ROLLOUT_PERCENTAGE_ITEMS = "p"
14
14
  PERCENTAGE = "p"
15
15
  ROLLOUT_RULES = "r"
16
+ VARIATION_ID = "i"
16
17
 
17
- def self.evaluate(key, user, default_value, config)
18
+ def self.evaluate(key, user, default_value, default_variation_id, config)
18
19
  ConfigCat.logger.info("Evaluating get_value('%s')." % key)
19
20
 
20
21
  setting_descriptor = config.fetch(key, nil)
21
22
  if setting_descriptor === nil
22
23
  ConfigCat.logger.error("Evaluating get_value('%s') failed. Value not found for key '%s'. Returning default_value: [%s]. Here are the available keys: %s" % [key, key, default_value.to_s, config.keys.join(", ")])
23
- return default_value
24
+ return default_value, default_variation_id
24
25
  end
25
26
 
26
27
  rollout_rules = setting_descriptor.fetch(ROLLOUT_RULES, [])
@@ -35,8 +36,9 @@ module ConfigCat
35
36
  ConfigCat.logger.warn("Evaluating get_value('%s'). UserObject missing! You should pass a UserObject to get_value(), in order to make targeting work properly. Read more: https://configcat.com/docs/advanced/user-object/" % key)
36
37
  end
37
38
  return_value = setting_descriptor.fetch(VALUE, default_value)
39
+ return_variation_id = setting_descriptor.fetch(VARIATION_ID, default_variation_id)
38
40
  ConfigCat.logger.info("Returning [%s]" % return_value.to_s)
39
- return return_value
41
+ return return_value, return_variation_id
40
42
  end
41
43
 
42
44
  ConfigCat.logger.info("User object:\n%s" % user.to_s)
@@ -54,30 +56,31 @@ module ConfigCat
54
56
  end
55
57
 
56
58
  value = rollout_rule.fetch(VALUE, nil)
59
+ variation_id = rollout_rule.fetch(VARIATION_ID, default_variation_id)
57
60
 
58
61
  # IS ONE OF
59
62
  if comparator == 0
60
63
  if comparison_value.to_s.split(",").map { |x| x.strip() }.include?(user_value.to_s)
61
64
  ConfigCat.logger.info(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
62
- return value
65
+ return value, variation_id
63
66
  end
64
67
  # IS NOT ONE OF
65
68
  elsif comparator == 1
66
69
  if !comparison_value.to_s.split(",").map { |x| x.strip() }.include?(user_value.to_s)
67
70
  ConfigCat.logger.info(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
68
- return value
71
+ return value, variation_id
69
72
  end
70
73
  # CONTAINS
71
74
  elsif comparator == 2
72
75
  if user_value.to_s.include?(comparison_value.to_s)
73
76
  ConfigCat.logger.info(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
74
- return value
77
+ return value, variation_id
75
78
  end
76
79
  # DOES NOT CONTAIN
77
80
  elsif comparator == 3
78
81
  if !user_value.to_s.include?(comparison_value.to_s)
79
82
  ConfigCat.logger.info(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
80
- return value
83
+ return value, variation_id
81
84
  end
82
85
  # IS ONE OF, IS NOT ONE OF (Semantic version)
83
86
  elsif (4 <= comparator) && (comparator <= 5)
@@ -90,7 +93,7 @@ module ConfigCat
90
93
  }
91
94
  if match && comparator == 4 || !match && comparator == 5
92
95
  ConfigCat.logger.info(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
93
- return value
96
+ return value, variation_id
94
97
  end
95
98
  rescue ArgumentError => e
96
99
  ConfigCat.logger.warn(format_validation_error_rule(comparison_attribute, user_value, comparator, comparison_value, e.to_s))
@@ -106,7 +109,7 @@ module ConfigCat
106
109
  (comparator == 8 && user_value_version > comparison_value_version) ||
107
110
  (comparator == 9 && user_value_version >= comparison_value_version)
108
111
  ConfigCat.logger.info(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
109
- return value
112
+ return value, variation_id
110
113
  end
111
114
  rescue ArgumentError => e
112
115
  ConfigCat.logger.warn(format_validation_error_rule(comparison_attribute, user_value, comparator, comparison_value, e.to_s))
@@ -123,14 +126,25 @@ module ConfigCat
123
126
  (comparator == 14 && user_value_float > comparison_value_float) ||
124
127
  (comparator == 15 && user_value_float >= comparison_value_float)
125
128
  ConfigCat.logger.info(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
126
- return value
129
+ return value, variation_id
127
130
  end
128
131
  rescue Exception => e
129
132
  ConfigCat.logger.warn(format_validation_error_rule(comparison_attribute, user_value, comparator, comparison_value, e.to_s))
130
133
  next
131
134
  end
135
+ # IS ONE OF (Sensitive)
136
+ elsif comparator == 16
137
+ if comparison_value.to_s.split(",").map { |x| x.strip() }.include?(Digest::SHA1.hexdigest(user_value).to_s)
138
+ ConfigCat.logger.info(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
139
+ return value, variation_id
140
+ end
141
+ # IS NOT ONE OF (Sensitive)
142
+ elsif comparator == 17
143
+ if !comparison_value.to_s.split(",").map { |x| x.strip() }.include?(Digest::SHA1.hexdigest(user_value).to_s)
144
+ ConfigCat.logger.info(format_match_rule(comparison_attribute, user_value, comparator, comparison_value, value))
145
+ return value, variation_id
146
+ end
132
147
  end
133
-
134
148
  ConfigCat.logger.info(format_no_match_rule(comparison_attribute, user_value, comparator, comparison_value))
135
149
  end
136
150
 
@@ -143,14 +157,16 @@ module ConfigCat
143
157
  bucket += rollout_percentage_item.fetch(PERCENTAGE, 0)
144
158
  if hash_val < bucket
145
159
  percentage_value = rollout_percentage_item.fetch(VALUE, nil)
160
+ variation_id = rollout_percentage_item.fetch(VARIATION_ID, default_variation_id)
146
161
  ConfigCat.logger.info("Evaluating %% options. Returning %s" % percentage_value)
147
- return percentage_value
162
+ return percentage_value, variation_id
148
163
  end
149
164
  end
150
165
  end
151
- def_value = setting_descriptor.fetch(VALUE, default_value)
152
- ConfigCat.logger.info("Returning %s" % def_value)
153
- return def_value
166
+ return_value = setting_descriptor.fetch(VALUE, default_value)
167
+ return_variation_id = setting_descriptor.fetch(VARIATION_ID, default_variation_id)
168
+ ConfigCat.logger.info("Returning %s" % return_value)
169
+ return return_value, return_variation_id
154
170
  end
155
171
 
156
172
  private
@@ -5,11 +5,11 @@ module ConfigCat
5
5
  # The user object for variation evaluation
6
6
  #
7
7
 
8
- PREDEFINED = ["identifier", "email", "country"]
8
+ PREDEFINED = ["Identifier", "Email", "Country"]
9
9
 
10
10
  def initialize(identifier, email: nil, country: nil, custom: nil)
11
- @__identifier = identifier
12
- @__data = {"identifier" => identifier, "email" => email, "country" => country}
11
+ @__identifier = (!identifier.equal?(nil)) ? identifier : ""
12
+ @__data = {"Identifier" => identifier, "Email" => email, "Country" => country}
13
13
  @__custom = custom
14
14
  end
15
15
 
@@ -18,14 +18,14 @@ module ConfigCat
18
18
  end
19
19
 
20
20
  def get_attribute(attribute)
21
- attribute = attribute.to_s.downcase()
21
+ attribute = attribute.to_s
22
22
  if PREDEFINED.include?(attribute)
23
23
  return @__data[attribute]
24
24
  end
25
25
 
26
26
  if !@__custom.equal?(nil)
27
27
  @__custom.each do |customField, customValue|
28
- if customField.to_s.downcase() == attribute
28
+ if customField.to_s == attribute
29
29
  return customValue
30
30
  end
31
31
  end
@@ -1,3 +1,3 @@
1
1
  module ConfigCat
2
- VERSION = "1.2.3"
2
+ VERSION = "3.1.0"
3
3
  end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: configcat
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ConfigCat
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-15 00:00:00.000000000 Z
11
+ date: 2020-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '1.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '1.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: semantic
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '1.6'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '1.6'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -56,30 +56,44 @@ dependencies:
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '12.3'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '12.3'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: coveralls
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.8'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.8'
83
+ - !ruby/object:Gem::Dependency
84
+ name: webmock
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '0'
89
+ version: '3.0'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - ">="
94
+ - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '0'
96
+ version: '3.0'
83
97
  description: Feature Flags created by developers for developers with ❤️. ConfigCat
84
98
  lets you manage feature flags across frontend, backend, mobile, and desktop apps
85
99
  without (re)deploying code. % rollouts, user targeting, segmentation. Feature toggle
@@ -112,7 +126,7 @@ require_paths:
112
126
  - lib
113
127
  required_ruby_version: !ruby/object:Gem::Requirement
114
128
  requirements:
115
- - - "~>"
129
+ - - ">="
116
130
  - !ruby/object:Gem::Version
117
131
  version: '2.2'
118
132
  required_rubygems_version: !ruby/object:Gem::Requirement
@@ -121,8 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
135
  - !ruby/object:Gem::Version
122
136
  version: '0'
123
137
  requirements: []
124
- rubyforge_project:
125
- rubygems_version: 2.7.7
138
+ rubygems_version: 3.0.8
126
139
  signing_key:
127
140
  specification_version: 4
128
141
  summary: ConfigCat SDK for Ruby.