prefab-cloud-ruby 0.20.0 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc.sample +3 -0
  3. data/.github/workflows/ruby.yml +5 -1
  4. data/.gitmodules +3 -0
  5. data/Gemfile +14 -12
  6. data/Gemfile.lock +24 -14
  7. data/README.md +12 -10
  8. data/Rakefile +13 -14
  9. data/VERSION +1 -1
  10. data/lib/prefab/auth_interceptor.rb +2 -1
  11. data/lib/prefab/cancellable_interceptor.rb +8 -7
  12. data/lib/prefab/client.rb +52 -27
  13. data/lib/prefab/config_client.rb +59 -70
  14. data/lib/prefab/config_loader.rb +7 -114
  15. data/lib/prefab/config_resolver.rb +27 -57
  16. data/lib/prefab/config_value_unwrapper.rb +23 -0
  17. data/lib/prefab/criteria_evaluator.rb +96 -0
  18. data/lib/prefab/errors/invalid_api_key_error.rb +1 -1
  19. data/lib/prefab/feature_flag_client.rb +13 -145
  20. data/lib/prefab/internal_logger.rb +7 -6
  21. data/lib/prefab/local_config_parser.rb +110 -0
  22. data/lib/prefab/log_path_collector.rb +98 -0
  23. data/lib/prefab/logger_client.rb +46 -44
  24. data/lib/prefab/murmer3.rb +3 -4
  25. data/lib/prefab/noop_cache.rb +5 -7
  26. data/lib/prefab/noop_stats.rb +2 -3
  27. data/lib/prefab/options.rb +32 -11
  28. data/lib/prefab/ratelimit_client.rb +11 -13
  29. data/lib/prefab/sse_logger.rb +3 -2
  30. data/lib/prefab/weighted_value_resolver.rb +42 -0
  31. data/lib/prefab/yaml_config_parser.rb +32 -0
  32. data/lib/prefab-cloud-ruby.rb +7 -2
  33. data/lib/prefab_pb.rb +70 -43
  34. data/lib/prefab_services_pb.rb +14 -1
  35. data/prefab-cloud-ruby.gemspec +33 -19
  36. data/test/.prefab.unit_tests.config.yaml +3 -2
  37. data/test/integration_test.rb +98 -0
  38. data/test/integration_test_helpers.rb +37 -0
  39. data/test/test_client.rb +56 -31
  40. data/test/test_config_client.rb +21 -20
  41. data/test/test_config_loader.rb +48 -37
  42. data/test/test_config_resolver.rb +312 -135
  43. data/test/test_config_value_unwrapper.rb +83 -0
  44. data/test/test_criteria_evaluator.rb +533 -0
  45. data/test/test_feature_flag_client.rb +35 -347
  46. data/test/test_helper.rb +18 -14
  47. data/test/test_integration.rb +33 -0
  48. data/test/test_local_config_parser.rb +78 -0
  49. data/test/test_log_path_collector.rb +56 -0
  50. data/test/test_logger.rb +52 -51
  51. data/test/test_options.rb +32 -0
  52. data/test/test_weighted_value_resolver.rb +65 -0
  53. metadata +30 -16
  54. data/lib/prefab/config_helper.rb +0 -31
  55. data/run_test_harness_server.sh +0 -8
  56. data/test/harness_server.rb +0 -64
@@ -17,45 +17,53 @@ module Prefab
17
17
  attr_reader :prefab_config_override_dir
18
18
  attr_reader :prefab_config_classpath_dir
19
19
  attr_reader :prefab_envs
20
+ attr_reader :collect_sync_interval
20
21
 
21
22
  DEFAULT_LOG_FORMATTER = proc { |severity, datetime, progname, msg|
22
- "#{severity.ljust(5)} #{datetime}:#{" " if progname}#{progname} #{msg}\n"
23
+ "#{severity.ljust(5)} #{datetime}:#{' ' if progname}#{progname} #{msg}\n"
23
24
  }
24
25
 
25
26
  module ON_INITIALIZATION_FAILURE
26
27
  RAISE = 1
27
28
  RETURN = 2
28
29
  end
30
+
29
31
  module ON_NO_DEFAULT
30
32
  RAISE = 1
31
33
  RETURN_NIL = 2
32
34
  end
35
+
33
36
  module DATASOURCES
34
37
  ALL = 1
35
38
  LOCAL_ONLY = 2
36
39
  end
37
40
 
38
- def initialize(
41
+ DEFAULT_MAX_PATHS = 1_000
42
+ DEFAULT_SYNC_INTERVAL = 60
43
+
44
+ private def init(
39
45
  api_key: ENV['PREFAB_API_KEY'],
40
46
  logdev: $stdout,
41
47
  stats: NoopStats.new, # receives increment("prefab.limitcheck", {:tags=>["policy_group:page_view", "pass:true"]})
42
48
  shared_cache: NoopCache.new, # Something that quacks like Rails.cache ideally memcached
43
- namespace: "",
49
+ namespace: '',
44
50
  log_formatter: DEFAULT_LOG_FORMATTER,
45
51
  log_prefix: nil,
46
- prefab_api_url: ENV["PREFAB_API_URL"] || 'https://api.prefab.cloud',
47
- prefab_grpc_url: ENV["PREFAB_GRPC_URL"] || 'grpc.prefab.cloud:443',
52
+ prefab_api_url: ENV['PREFAB_API_URL'] || 'https://api.prefab.cloud',
53
+ prefab_grpc_url: ENV['PREFAB_GRPC_URL'] || 'grpc.prefab.cloud:443',
48
54
  on_no_default: ON_NO_DEFAULT::RAISE, # options :raise, :warn_and_return_nil,
49
55
  initialization_timeout_sec: 10, # how long to wait before on_init_failure
50
- on_init_failure: ON_INITIALIZATION_FAILURE::RAISE, #options :unlock_and_continue, :lock_and_keep_trying, :raise
56
+ on_init_failure: ON_INITIALIZATION_FAILURE::RAISE, # options :unlock_and_continue, :lock_and_keep_trying, :raise
51
57
  # new_config_callback: nil, #callback method
52
58
  # live_override_url: nil,
53
- prefab_datasources: ENV['PREFAB_DATASOURCES'] == "LOCAL_ONLY" ? DATASOURCES::LOCAL_ONLY : DATASOURCES::ALL,
59
+ prefab_datasources: ENV['PREFAB_DATASOURCES'] == 'LOCAL_ONLY' ? DATASOURCES::LOCAL_ONLY : DATASOURCES::ALL,
54
60
  prefab_config_override_dir: Dir.home,
55
- prefab_config_classpath_dir: ".",
56
- prefab_envs: ENV['PREFAB_ENVS'].nil? ? [] : ENV['PREFAB_ENVS'].split(",")
61
+ prefab_config_classpath_dir: '.',
62
+ prefab_envs: ENV['PREFAB_ENVS'].nil? ? [] : ENV['PREFAB_ENVS'].split(','),
63
+ collect_logs: true,
64
+ collect_max_paths: DEFAULT_MAX_PATHS,
65
+ collect_sync_interval: DEFAULT_SYNC_INTERVAL
57
66
  )
58
- # debugger
59
67
  @api_key = api_key
60
68
  @logdev = logdev
61
69
  @stats = stats
@@ -72,15 +80,28 @@ module Prefab
72
80
  @prefab_config_classpath_dir = prefab_config_classpath_dir
73
81
  @prefab_config_override_dir = prefab_config_override_dir
74
82
  @prefab_envs = Array(prefab_envs)
83
+ @collect_logs = collect_logs
84
+ @collect_max_paths = collect_max_paths
85
+ @collect_sync_interval = collect_sync_interval
86
+ end
87
+
88
+ def initialize(options = {})
89
+ init(**options)
75
90
  end
76
91
 
77
92
  def local_only?
78
93
  @prefab_datasources == DATASOURCES::LOCAL_ONLY
79
94
  end
80
95
 
96
+ def collect_max_paths
97
+ return 0 if !@collect_logs || local_only?
98
+
99
+ @collect_max_paths
100
+ end
101
+
81
102
  # https://api.prefab.cloud -> https://api-prefab-cloud.global.ssl.fastly.net
82
103
  def url_for_api_cdn
83
- ENV['PREFAB_CDN_URL'] || "#{@prefab_api_url.gsub(/\./, "-")}.global.ssl.fastly.net"
104
+ ENV['PREFAB_CDN_URL'] || "#{@prefab_api_url.gsub(/\./, '-')}.global.ssl.fastly.net"
84
105
  end
85
106
  end
86
107
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Prefab
3
4
  class RateLimitClient
4
-
5
5
  def initialize(base_client, timeout)
6
6
  @timeout = timeout
7
7
  @base_client = base_client
@@ -9,14 +9,14 @@ module Prefab
9
9
 
10
10
  def pass?(group)
11
11
  result = acquire([group], 1)
12
- return result.passed
12
+ result.passed
13
13
  end
14
14
 
15
15
  def acquire(groups, acquire_amount, allow_partial_response: false, on_error: :log_and_pass)
16
- expiry_cache_key = "prefab.ratelimit.expiry:#{groups.join(".")}"
16
+ expiry_cache_key = "prefab.ratelimit.expiry:#{groups.join('.')}"
17
17
  expiry = @base_client.shared_cache.read(expiry_cache_key)
18
18
  if !expiry.nil? && Integer(expiry) > Time.now.utc.to_f * 1000
19
- @base_client.stats.increment("prefab.ratelimit.limitcheck.expirycache.hit", tags: [])
19
+ @base_client.stats.increment('prefab.ratelimit.limitcheck.expirycache.hit', tags: [])
20
20
  return Prefab::LimitResponse.new(passed: false, amount: 0)
21
21
  end
22
22
 
@@ -27,16 +27,17 @@ module Prefab
27
27
  allow_partial_response: allow_partial_response
28
28
  )
29
29
 
30
- result = @base_client.request Prefab::RateLimitService, :limit_check, req_options: {timeout: @timeout}, params: req
30
+ result = @base_client.request Prefab::RateLimitService, :limit_check, req_options: { timeout: @timeout },
31
+ params: req
31
32
 
32
33
  reset = result.limit_reset_at
33
34
  @base_client.shared_cache.write(expiry_cache_key, reset) unless reset < 1 # protobuf default int to 0
34
35
 
35
- @base_client.stats.increment("prefab.ratelimit.limitcheck", tags: ["policy_group:#{result.policy_group}", "pass:#{result.passed}"])
36
+ @base_client.stats.increment('prefab.ratelimit.limitcheck',
37
+ tags: ["policy_group:#{result.policy_group}", "pass:#{result.passed}"])
36
38
 
37
39
  result
38
-
39
- rescue => e
40
+ rescue StandardError => e
40
41
  handle_error(e, on_error, groups)
41
42
  end
42
43
 
@@ -48,9 +49,7 @@ module Prefab
48
49
  limit: limit,
49
50
  burst: burst
50
51
  )
51
- unless safety_level.nil?
52
- limit_definition.safety_level = safety_level
53
- end
52
+ limit_definition.safety_level = safety_level unless safety_level.nil?
54
53
  config_value = Prefab::ConfigValue.new(limit_definition: limit_definition)
55
54
  config_delta = Prefab::ConfigClient.value_to_delta(key, config_value)
56
55
  upsert_req = Prefab::UpsertRequest.new(config_delta: config_delta)
@@ -61,7 +60,7 @@ module Prefab
61
60
  private
62
61
 
63
62
  def handle_error(e, on_error, groups)
64
- @base_client.stats.increment("prefab.ratelimit.error", tags: ["type:limit"])
63
+ @base_client.stats.increment('prefab.ratelimit.error', tags: ['type:limit'])
65
64
 
66
65
  message = "ratelimit for #{groups} error: #{e.message}"
67
66
  case on_error
@@ -77,4 +76,3 @@ module Prefab
77
76
  end
78
77
  end
79
78
  end
80
-
@@ -1,12 +1,13 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Prefab
3
4
  class SseLogger < InternalLogger
4
5
  def initialize(logger)
5
- super("sse", logger)
6
+ super('sse', logger)
6
7
  end
7
8
 
8
9
  # The SSE::Client warns on a perfectly normal stream disconnect, recast to info
9
- def warn(progname = nil, &block)
10
+ def warn(progname = nil)
10
11
  @logger.log_internal yield, @path, progname, INFO
11
12
  end
12
13
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Prefab
4
+ class WeightedValueResolver
5
+ MAX_32_FLOAT = 4_294_967_294.0
6
+
7
+ def initialize(weights, config_key, lookup_key)
8
+ @weights = weights
9
+ @config_key = config_key
10
+ @lookup_key = lookup_key
11
+ end
12
+
13
+ def resolve
14
+ percent = @lookup_key ? user_percent : rand
15
+
16
+ index = variant_index(percent)
17
+
18
+ @weights[index]
19
+ end
20
+
21
+ def user_percent
22
+ to_hash = "#{@config_key}#{@lookup_key}"
23
+ int_value = Murmur3.murmur3_32(to_hash)
24
+ int_value / MAX_32_FLOAT
25
+ end
26
+
27
+ def variant_index(percent_through_distribution)
28
+ distribution_space = @weights.inject(0) { |sum, v| sum + v.weight }
29
+ bucket = distribution_space * percent_through_distribution
30
+
31
+ sum = 0
32
+ @weights.each_with_index do |variant_weight, index|
33
+ return index if bucket < sum + variant_weight.weight
34
+
35
+ sum += variant_weight.weight
36
+ end
37
+
38
+ # In the event that all weights are zero, return the last variant
39
+ @weights.size - 1
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,32 @@
1
+ require 'yaml'
2
+
3
+ module Prefab
4
+ class YAMLConfigParser
5
+ def initialize(file, client)
6
+ @file = file
7
+ @client = client
8
+ end
9
+
10
+ def merge(config)
11
+ yaml = load
12
+
13
+ yaml.each do |k, v|
14
+ config = Prefab::LocalConfigParser.parse(k, v, config, @file)
15
+ end
16
+
17
+ config
18
+ end
19
+
20
+ private
21
+
22
+ def load
23
+ if File.exist?(@file)
24
+ @client.log_internal ::Logger::INFO, "Load #{@file}"
25
+ YAML.load_file(@file)
26
+ else
27
+ @client.log_internal ::Logger::INFO, "No file #{@file}"
28
+ {}
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
- require "concurrent/atomics"
2
+
3
+ require 'concurrent/atomics'
3
4
  require 'concurrent'
4
5
  require 'faraday'
5
6
  require 'openssl'
@@ -14,8 +15,12 @@ require 'prefab_services_pb'
14
15
  require 'prefab/options'
15
16
  require 'prefab/internal_logger'
16
17
  require 'prefab/sse_logger'
17
- require 'prefab/config_helper'
18
+ require 'prefab/weighted_value_resolver'
19
+ require 'prefab/config_value_unwrapper'
20
+ require 'prefab/criteria_evaluator'
18
21
  require 'prefab/config_loader'
22
+ require 'prefab/local_config_parser'
23
+ require 'prefab/yaml_config_parser'
19
24
  require 'prefab/config_resolver'
20
25
  require 'prefab/client'
21
26
  require 'prefab/ratelimit_client'
data/lib/prefab_pb.rb CHANGED
@@ -17,12 +17,22 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
17
17
  optional :bytes, :bytes, 3
18
18
  optional :double, :double, 4
19
19
  optional :bool, :bool, 5
20
- optional :feature_flag, :message, 6, "prefab.FeatureFlag"
20
+ optional :weighted_values, :message, 6, "prefab.WeightedValues"
21
21
  optional :limit_definition, :message, 7, "prefab.LimitDefinition"
22
- optional :segment, :message, 8, "prefab.Segment"
23
22
  optional :log_level, :enum, 9, "prefab.LogLevel"
23
+ optional :string_list, :message, 10, "prefab.StringList"
24
24
  end
25
25
  end
26
+ add_message "prefab.StringList" do
27
+ repeated :values, :string, 1
28
+ end
29
+ add_message "prefab.WeightedValue" do
30
+ optional :weight, :int32, 1
31
+ optional :value, :message, 2, "prefab.ConfigValue"
32
+ end
33
+ add_message "prefab.WeightedValues" do
34
+ repeated :weighted_values, :message, 1, "prefab.WeightedValue"
35
+ end
26
36
  add_message "prefab.Configs" do
27
37
  repeated :configs, :message, 1, "prefab.Config"
28
38
  optional :config_service_pointer, :message, 2, "prefab.ConfigServicePointer"
@@ -31,14 +41,24 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
31
41
  optional :id, :int64, 1
32
42
  optional :project_id, :int64, 2
33
43
  optional :key, :string, 3
34
- optional :changed_by, :string, 4
44
+ optional :changed_by, :message, 4, "prefab.ChangedBy"
35
45
  repeated :rows, :message, 5, "prefab.ConfigRow"
36
- repeated :variants, :message, 6, "prefab.FeatureFlagVariant"
46
+ repeated :allowable_values, :message, 6, "prefab.ConfigValue"
47
+ optional :config_type, :enum, 7, "prefab.ConfigType"
48
+ proto3_optional :draftId, :int64, 8
49
+ end
50
+ add_message "prefab.ChangedBy" do
51
+ optional :user_id, :int64, 1
52
+ optional :email, :string, 2
37
53
  end
38
54
  add_message "prefab.ConfigRow" do
39
- optional :project_env_id, :int64, 1
40
- optional :namespace, :string, 2
41
- optional :value, :message, 3, "prefab.ConfigValue"
55
+ proto3_optional :project_env_id, :int64, 1
56
+ repeated :values, :message, 2, "prefab.ConditionalValue"
57
+ map :properties, :string, :message, 3, "prefab.ConfigValue"
58
+ end
59
+ add_message "prefab.ConditionalValue" do
60
+ repeated :criteria, :message, 1, "prefab.Criterion"
61
+ optional :value, :message, 2, "prefab.ConfigValue"
42
62
  end
43
63
  add_message "prefab.LimitResponse" do
44
64
  optional :passed, :bool, 1
@@ -75,20 +95,12 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
75
95
  value :MINIMUM, 1
76
96
  value :MAXIMUM, 2
77
97
  end
78
- add_message "prefab.FeatureFlagVariant" do
79
- proto3_optional :int, :int64, 1
80
- proto3_optional :string, :string, 2
81
- proto3_optional :double, :double, 3
82
- proto3_optional :bool, :bool, 4
83
- optional :name, :string, 5
84
- optional :description, :string, 6
85
- end
86
- add_message "prefab.Criteria" do
87
- optional :property, :string, 1
88
- optional :operator, :enum, 2, "prefab.Criteria.CriteriaOperator"
89
- repeated :values, :string, 3
98
+ add_message "prefab.Criterion" do
99
+ optional :property_name, :string, 1
100
+ optional :operator, :enum, 2, "prefab.Criterion.CriterionOperator"
101
+ optional :value_to_match, :message, 3, "prefab.ConfigValue"
90
102
  end
91
- add_enum "prefab.Criteria.CriteriaOperator" do
103
+ add_enum "prefab.Criterion.CriterionOperator" do
92
104
  value :NOT_SET, 0
93
105
  value :LOOKUP_KEY_IN, 1
94
106
  value :LOOKUP_KEY_NOT_IN, 2
@@ -99,22 +111,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
99
111
  value :PROP_IS_NOT_ONE_OF, 7
100
112
  value :PROP_ENDS_WITH_ONE_OF, 8
101
113
  value :PROP_DOES_NOT_END_WITH_ONE_OF, 9
102
- end
103
- add_message "prefab.Rule" do
104
- optional :criteria, :message, 1, "prefab.Criteria"
105
- repeated :variant_weights, :message, 2, "prefab.VariantWeight"
106
- end
107
- add_message "prefab.Segment" do
108
- repeated :criterion, :message, 1, "prefab.Criteria"
109
- end
110
- add_message "prefab.VariantWeight" do
111
- optional :weight, :int32, 1
112
- optional :variant_idx, :int32, 2
113
- end
114
- add_message "prefab.FeatureFlag" do
115
- optional :active, :bool, 1
116
- optional :inactive_variant_idx, :int32, 2
117
- repeated :rules, :message, 5, "prefab.Rule"
114
+ value :HIERARCHICAL_MATCH, 10
118
115
  end
119
116
  add_message "prefab.Identity" do
120
117
  proto3_optional :lookup, :string, 1
@@ -184,6 +181,32 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
184
181
  optional :sequence_name, :string, 3
185
182
  optional :size, :int64, 4
186
183
  end
184
+ add_message "prefab.Loggers" do
185
+ repeated :loggers, :message, 1, "prefab.Logger"
186
+ optional :start_at, :int64, 2
187
+ optional :end_at, :int64, 3
188
+ optional :instance_hash, :string, 4
189
+ proto3_optional :namespace, :string, 5
190
+ end
191
+ add_message "prefab.Logger" do
192
+ optional :logger_name, :string, 1
193
+ proto3_optional :traces, :int64, 2
194
+ proto3_optional :debugs, :int64, 3
195
+ proto3_optional :infos, :int64, 4
196
+ proto3_optional :warns, :int64, 5
197
+ proto3_optional :errors, :int64, 6
198
+ proto3_optional :fatals, :int64, 7
199
+ end
200
+ add_message "prefab.LoggerReportResponse" do
201
+ end
202
+ add_enum "prefab.ConfigType" do
203
+ value :NOT_SET_CONFIG_TYPE, 0
204
+ value :CONFIG, 1
205
+ value :FEATURE_FLAG, 2
206
+ value :LOG_LEVEL, 3
207
+ value :SEGMENT, 4
208
+ value :LIMIT_DEFINITION, 5
209
+ end
187
210
  add_enum "prefab.LogLevel" do
188
211
  value :NOT_SET_LOG_LEVEL, 0
189
212
  value :TRACE, 1
@@ -205,20 +228,20 @@ end
205
228
  module Prefab
206
229
  ConfigServicePointer = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigServicePointer").msgclass
207
230
  ConfigValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigValue").msgclass
231
+ StringList = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.StringList").msgclass
232
+ WeightedValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.WeightedValue").msgclass
233
+ WeightedValues = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.WeightedValues").msgclass
208
234
  Configs = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Configs").msgclass
209
235
  Config = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Config").msgclass
236
+ ChangedBy = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ChangedBy").msgclass
210
237
  ConfigRow = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigRow").msgclass
238
+ ConditionalValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConditionalValue").msgclass
211
239
  LimitResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.LimitResponse").msgclass
212
240
  LimitResponse::LimitPolicyNames = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.LimitResponse.LimitPolicyNames").enummodule
213
241
  LimitRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.LimitRequest").msgclass
214
242
  LimitRequest::LimitCombiner = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.LimitRequest.LimitCombiner").enummodule
215
- FeatureFlagVariant = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.FeatureFlagVariant").msgclass
216
- Criteria = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Criteria").msgclass
217
- Criteria::CriteriaOperator = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Criteria.CriteriaOperator").enummodule
218
- Rule = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Rule").msgclass
219
- Segment = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Segment").msgclass
220
- VariantWeight = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.VariantWeight").msgclass
221
- FeatureFlag = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.FeatureFlag").msgclass
243
+ Criterion = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Criterion").msgclass
244
+ Criterion::CriterionOperator = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Criterion.CriterionOperator").enummodule
222
245
  Identity = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Identity").msgclass
223
246
  ClientConfigValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ClientConfigValue").msgclass
224
247
  ConfigEvaluations = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigEvaluations").msgclass
@@ -231,6 +254,10 @@ module Prefab
231
254
  CreationResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.CreationResponse").msgclass
232
255
  IdBlock = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.IdBlock").msgclass
233
256
  IdBlockRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.IdBlockRequest").msgclass
257
+ Loggers = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Loggers").msgclass
258
+ Logger = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Logger").msgclass
259
+ LoggerReportResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.LoggerReportResponse").msgclass
260
+ ConfigType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigType").enummodule
234
261
  LogLevel = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.LogLevel").enummodule
235
262
  OnFailure = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.OnFailure").enummodule
236
263
  end
@@ -1,4 +1,3 @@
1
- # frozen_string_literal: true
2
1
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
2
  # Source: prefab.proto for package 'prefab'
4
3
 
@@ -62,6 +61,20 @@ module Prefab
62
61
  rpc :GetAll, ::Prefab::Identity, ::Prefab::ConfigEvaluations
63
62
  end
64
63
 
64
+ Stub = Service.rpc_stub_class
65
+ end
66
+ module LoggerReportingService
67
+ class Service
68
+
69
+ include ::GRPC::GenericService
70
+
71
+ self.marshal_class_method = :encode
72
+ self.unmarshal_class_method = :decode
73
+ self.service_name = 'prefab.LoggerReportingService'
74
+
75
+ rpc :Send, ::Prefab::Loggers, ::Prefab::LoggerReportResponse
76
+ end
77
+
65
78
  Stub = Service.rpc_stub_class
66
79
  end
67
80
  end
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: prefab-cloud-ruby 0.20.0 ruby lib
5
+ # stub: prefab-cloud-ruby 0.22.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "prefab-cloud-ruby".freeze
9
- s.version = "0.20.0"
9
+ s.version = "0.22.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Jeff Dwyer".freeze]
14
- s.date = "2022-12-02"
14
+ s.date = "2023-03-15"
15
15
  s.description = "RateLimits & Config as a service".freeze
16
16
  s.email = "jdwyer@prefab.cloud".freeze
17
17
  s.extra_rdoc_files = [
@@ -20,7 +20,9 @@ Gem::Specification.new do |s|
20
20
  ]
21
21
  s.files = [
22
22
  ".envrc",
23
+ ".envrc.sample",
23
24
  ".github/workflows/ruby.yml",
25
+ ".gitmodules",
24
26
  ".tool-versions",
25
27
  "CODEOWNERS",
26
28
  "Gemfile",
@@ -35,15 +37,18 @@ Gem::Specification.new do |s|
35
37
  "lib/prefab/cancellable_interceptor.rb",
36
38
  "lib/prefab/client.rb",
37
39
  "lib/prefab/config_client.rb",
38
- "lib/prefab/config_helper.rb",
39
40
  "lib/prefab/config_loader.rb",
40
41
  "lib/prefab/config_resolver.rb",
42
+ "lib/prefab/config_value_unwrapper.rb",
43
+ "lib/prefab/criteria_evaluator.rb",
41
44
  "lib/prefab/error.rb",
42
45
  "lib/prefab/errors/initialization_timeout_error.rb",
43
46
  "lib/prefab/errors/invalid_api_key_error.rb",
44
47
  "lib/prefab/errors/missing_default_error.rb",
45
48
  "lib/prefab/feature_flag_client.rb",
46
49
  "lib/prefab/internal_logger.rb",
50
+ "lib/prefab/local_config_parser.rb",
51
+ "lib/prefab/log_path_collector.rb",
47
52
  "lib/prefab/logger_client.rb",
48
53
  "lib/prefab/murmer3.rb",
49
54
  "lib/prefab/noop_cache.rb",
@@ -51,20 +56,29 @@ Gem::Specification.new do |s|
51
56
  "lib/prefab/options.rb",
52
57
  "lib/prefab/ratelimit_client.rb",
53
58
  "lib/prefab/sse_logger.rb",
59
+ "lib/prefab/weighted_value_resolver.rb",
60
+ "lib/prefab/yaml_config_parser.rb",
54
61
  "lib/prefab_pb.rb",
55
62
  "lib/prefab_services_pb.rb",
56
63
  "prefab-cloud-ruby.gemspec",
57
- "run_test_harness_server.sh",
58
64
  "test/.prefab.default.config.yaml",
59
65
  "test/.prefab.unit_tests.config.yaml",
60
- "test/harness_server.rb",
66
+ "test/integration_test.rb",
67
+ "test/integration_test_helpers.rb",
61
68
  "test/test_client.rb",
62
69
  "test/test_config_client.rb",
63
70
  "test/test_config_loader.rb",
64
71
  "test/test_config_resolver.rb",
72
+ "test/test_config_value_unwrapper.rb",
73
+ "test/test_criteria_evaluator.rb",
65
74
  "test/test_feature_flag_client.rb",
66
75
  "test/test_helper.rb",
67
- "test/test_logger.rb"
76
+ "test/test_integration.rb",
77
+ "test/test_local_config_parser.rb",
78
+ "test/test_log_path_collector.rb",
79
+ "test/test_logger.rb",
80
+ "test/test_options.rb",
81
+ "test/test_weighted_value_resolver.rb"
68
82
  ]
69
83
  s.homepage = "http://github.com/prefab-cloud/prefab-cloud-ruby".freeze
70
84
  s.licenses = ["MIT".freeze]
@@ -78,31 +92,31 @@ Gem::Specification.new do |s|
78
92
  if s.respond_to? :add_runtime_dependency then
79
93
  s.add_runtime_dependency(%q<concurrent-ruby>.freeze, ["~> 1.0", ">= 1.0.5"])
80
94
  s.add_runtime_dependency(%q<faraday>.freeze, [">= 0"])
81
- s.add_runtime_dependency(%q<ld-eventsource>.freeze, [">= 0"])
82
- s.add_runtime_dependency(%q<grpc>.freeze, [">= 0"])
83
- s.add_runtime_dependency(%q<google-protobuf>.freeze, [">= 0"])
84
95
  s.add_runtime_dependency(%q<googleapis-common-protos-types>.freeze, [">= 0"])
96
+ s.add_runtime_dependency(%q<google-protobuf>.freeze, [">= 0"])
97
+ s.add_runtime_dependency(%q<grpc>.freeze, [">= 0"])
98
+ s.add_runtime_dependency(%q<ld-eventsource>.freeze, [">= 0"])
99
+ s.add_runtime_dependency(%q<uuid>.freeze, [">= 0"])
85
100
  s.add_development_dependency(%q<benchmark-ips>.freeze, [">= 0"])
86
- s.add_development_dependency(%q<grpc-tools>.freeze, [">= 0"])
87
- s.add_development_dependency(%q<rdoc>.freeze, [">= 0"])
88
101
  s.add_development_dependency(%q<bundler>.freeze, [">= 0"])
102
+ s.add_development_dependency(%q<grpc-tools>.freeze, [">= 0"])
89
103
  s.add_development_dependency(%q<juwelier>.freeze, ["~> 2.4.9"])
104
+ s.add_development_dependency(%q<rdoc>.freeze, [">= 0"])
90
105
  s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
91
- s.add_development_dependency(%q<thin>.freeze, [">= 0"])
92
106
  else
93
107
  s.add_dependency(%q<concurrent-ruby>.freeze, ["~> 1.0", ">= 1.0.5"])
94
108
  s.add_dependency(%q<faraday>.freeze, [">= 0"])
95
- s.add_dependency(%q<ld-eventsource>.freeze, [">= 0"])
96
- s.add_dependency(%q<grpc>.freeze, [">= 0"])
97
- s.add_dependency(%q<google-protobuf>.freeze, [">= 0"])
98
109
  s.add_dependency(%q<googleapis-common-protos-types>.freeze, [">= 0"])
110
+ s.add_dependency(%q<google-protobuf>.freeze, [">= 0"])
111
+ s.add_dependency(%q<grpc>.freeze, [">= 0"])
112
+ s.add_dependency(%q<ld-eventsource>.freeze, [">= 0"])
113
+ s.add_dependency(%q<uuid>.freeze, [">= 0"])
99
114
  s.add_dependency(%q<benchmark-ips>.freeze, [">= 0"])
100
- s.add_dependency(%q<grpc-tools>.freeze, [">= 0"])
101
- s.add_dependency(%q<rdoc>.freeze, [">= 0"])
102
115
  s.add_dependency(%q<bundler>.freeze, [">= 0"])
116
+ s.add_dependency(%q<grpc-tools>.freeze, [">= 0"])
103
117
  s.add_dependency(%q<juwelier>.freeze, ["~> 2.4.9"])
118
+ s.add_dependency(%q<rdoc>.freeze, [">= 0"])
104
119
  s.add_dependency(%q<simplecov>.freeze, [">= 0"])
105
- s.add_dependency(%q<thin>.freeze, [">= 0"])
106
120
  end
107
121
  end
108
122
 
@@ -9,8 +9,9 @@ sample: test sample value
9
9
  enabled_flag: true
10
10
  disabled_flag: false
11
11
  flag_with_a_value: { "feature_flag": "true", value: "all-features" }
12
- in_lookup_key: { "feature_flag": "true", value: true, criteria: { operator: LOOKUP_KEY_IN, values: [ "abc123", "xyz987" ] } }
13
- just_my_domain: { "feature_flag": "true", value: "new-version", criteria: { operator: PROP_IS_ONE_OF, property: "domain", values: [ "prefab.cloud", "example.com" ] } }
12
+ in_lookup_key: { "feature_flag": "true", value: true, criterion: { operator: LOOKUP_KEY_IN, values: [ "abc123", "xyz987" ] } }
13
+ just_my_domain: { "feature_flag": "true", value: "new-version", criterion: { operator: PROP_IS_ONE_OF, property: "domain", values: [ "prefab.cloud", "example.com" ] } }
14
+
14
15
  nested:
15
16
  values:
16
17
  _: top level