prefab-cloud-ruby 0.2.0 → 0.6.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
  SHA1:
3
- metadata.gz: 57dd1f5909bf80cd820396d039c2d1560faf55e6
4
- data.tar.gz: d2e6192bf1126aadc4aaa49e23728cfbaaf2a689
3
+ metadata.gz: fa80ee91d95324b503253f95a12deb9b0db91291
4
+ data.tar.gz: 0315d992eb2a87073998e1d7db4864a8c3da289c
5
5
  SHA512:
6
- metadata.gz: 61ff17aeda32522ed65ace11b48b955f87eeb69cc9ccc781c3dfecca66161469a93a96db42559919f347e4998b3d42038890dd22219e2ec722a01eb61323b6cf
7
- data.tar.gz: 87b2c0a1a2544cd9c7f93fdda3d1e96028424642e5d6fd9dd8fd3c9c334ef5f146d5ba0fe006ebb6fa27ad6e7bee6488d92dedcb2546b516e2dec61e71121509
6
+ metadata.gz: e43a7a8dafbfd3a9e6c12cd93b57bed2ee8fd738406fdba166c5eddad03154de66d9150285961f8c08da58d0754fde385b8b68e0bb22f9a27de8441f231a429a
7
+ data.tar.gz: c3586f0e6b689e0ee5b1fd86e621d79ffab5a2263cf977c004fd7a4618cea403059f075f719a86d5a0b4533a16e398e3acb35dff9ca0930082fb81266ef1e545
data/.envrc ADDED
@@ -0,0 +1,2 @@
1
+ export AWS_ACCESS_KEY_ID=
2
+ export AWS_SECRET_ACCESS_KEY=
data/Gemfile CHANGED
@@ -1,8 +1,8 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem 'grpc', '~> 1.17.1'
4
3
  gem 'concurrent-ruby', '~> 1.0', '>= 1.0.5'
5
- gem 'aws-sdk-s3', '~> 1'
4
+ gem 'faraday'
5
+ gem 'grpc'
6
6
 
7
7
  group :development do
8
8
  gem 'grpc-tools', '~> 1.17.1'
data/Gemfile.lock CHANGED
@@ -1,52 +1,42 @@
1
1
  GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
- activesupport (5.2.0)
4
+ activesupport (5.2.4.5)
5
5
  concurrent-ruby (~> 1.0, >= 1.0.2)
6
6
  i18n (>= 0.7, < 2)
7
7
  minitest (~> 5.1)
8
8
  tzinfo (~> 1.1)
9
- addressable (2.6.0)
10
- public_suffix (>= 2.0.2, < 4.0)
11
- aws-partitions (1.86.0)
12
- aws-sdk-core (3.20.2)
13
- aws-partitions (~> 1.0)
14
- aws-sigv4 (~> 1.0)
15
- jmespath (~> 1.0)
16
- aws-sdk-kms (1.5.0)
17
- aws-sdk-core (~> 3)
18
- aws-sigv4 (~> 1.0)
19
- aws-sdk-s3 (1.10.0)
20
- aws-sdk-core (~> 3)
21
- aws-sdk-kms (~> 1)
22
- aws-sigv4 (~> 1.0)
23
- aws-sigv4 (1.0.2)
24
- builder (3.2.3)
25
- concurrent-ruby (1.0.5)
9
+ addressable (2.7.0)
10
+ public_suffix (>= 2.0.2, < 5.0)
11
+ builder (3.2.4)
12
+ concurrent-ruby (1.1.8)
26
13
  descendants_tracker (0.0.4)
27
14
  thread_safe (~> 0.3, >= 0.3.1)
28
- docile (1.3.0)
29
- faraday (0.15.4)
15
+ docile (1.3.5)
16
+ faraday (1.3.0)
17
+ faraday-net_http (~> 1.0)
30
18
  multipart-post (>= 1.2, < 3)
31
- git (1.5.0)
32
- github_api (0.18.2)
19
+ ruby2_keywords
20
+ faraday-net_http (1.0.1)
21
+ git (1.8.1)
22
+ rchardet (~> 1.8)
23
+ github_api (0.19.0)
33
24
  addressable (~> 2.4)
34
25
  descendants_tracker (~> 0.0.4)
35
- faraday (~> 0.8)
26
+ faraday (>= 0.8, < 2)
36
27
  hashie (~> 3.5, >= 3.5.2)
37
28
  oauth2 (~> 1.0)
38
- google-protobuf (3.6.1)
39
- googleapis-common-protos-types (1.0.2)
40
- google-protobuf (~> 3.0)
41
- grpc (1.17.1)
42
- google-protobuf (~> 3.1)
43
- googleapis-common-protos-types (~> 1.0.0)
29
+ google-protobuf (3.15.6)
30
+ googleapis-common-protos-types (1.0.6)
31
+ google-protobuf (~> 3.14)
32
+ grpc (1.36.0)
33
+ google-protobuf (~> 3.14)
34
+ googleapis-common-protos-types (~> 1.0)
44
35
  grpc-tools (1.17.1)
45
36
  hashie (3.6.0)
46
- highline (2.0.1)
47
- i18n (1.0.1)
37
+ highline (2.0.3)
38
+ i18n (1.8.9)
48
39
  concurrent-ruby (~> 1.0)
49
- jmespath (1.4.0)
50
40
  json (1.8.6)
51
41
  juwelier (2.4.9)
52
42
  builder
@@ -60,52 +50,53 @@ GEM
60
50
  rake
61
51
  rdoc
62
52
  semver2
63
- jwt (2.1.0)
53
+ jwt (2.2.2)
64
54
  kamelcase (0.0.2)
65
55
  semver2 (~> 3)
66
56
  mini_portile2 (2.4.0)
67
- minitest (5.11.3)
68
- multi_json (1.13.1)
57
+ minitest (5.14.4)
58
+ multi_json (1.15.0)
69
59
  multi_xml (0.6.0)
70
- multipart-post (2.0.0)
71
- nokogiri (1.10.1)
60
+ multipart-post (2.1.1)
61
+ nokogiri (1.10.10)
72
62
  mini_portile2 (~> 2.4.0)
73
- oauth2 (1.4.1)
74
- faraday (>= 0.8, < 0.16.0)
63
+ oauth2 (1.4.7)
64
+ faraday (>= 0.8, < 2.0)
75
65
  jwt (>= 1.0, < 3.0)
76
66
  multi_json (~> 1.3)
77
67
  multi_xml (~> 0.5)
78
68
  rack (>= 1.2, < 3)
79
- psych (3.1.0)
80
- public_suffix (3.0.3)
81
- rack (2.0.6)
82
- rake (12.3.2)
69
+ psych (3.3.1)
70
+ public_suffix (4.0.6)
71
+ rack (2.2.3)
72
+ rake (13.0.3)
73
+ rchardet (1.8.0)
83
74
  rdoc (3.12.2)
84
75
  json (~> 1.4)
76
+ ruby2_keywords (0.0.4)
85
77
  semver2 (3.4.2)
86
- shoulda (3.5.0)
87
- shoulda-context (~> 1.0, >= 1.0.1)
88
- shoulda-matchers (>= 1.4.1, < 3.0)
89
- shoulda-context (1.2.2)
90
- shoulda-matchers (2.8.0)
91
- activesupport (>= 3.0.0)
92
- simplecov (0.16.1)
78
+ shoulda (4.0.0)
79
+ shoulda-context (~> 2.0)
80
+ shoulda-matchers (~> 4.0)
81
+ shoulda-context (2.0.0)
82
+ shoulda-matchers (4.5.1)
83
+ activesupport (>= 4.2.0)
84
+ simplecov (0.18.5)
93
85
  docile (~> 1.1)
94
- json (>= 1.8, < 3)
95
- simplecov-html (~> 0.10.0)
96
- simplecov-html (0.10.2)
86
+ simplecov-html (~> 0.11)
87
+ simplecov-html (0.12.3)
97
88
  thread_safe (0.3.6)
98
- tzinfo (1.2.5)
89
+ tzinfo (1.2.9)
99
90
  thread_safe (~> 0.1)
100
91
 
101
92
  PLATFORMS
102
93
  ruby
103
94
 
104
95
  DEPENDENCIES
105
- aws-sdk-s3 (~> 1)
106
96
  bundler (~> 1.0)
107
97
  concurrent-ruby (~> 1.0, >= 1.0.5)
108
- grpc (~> 1.17.1)
98
+ faraday
99
+ grpc
109
100
  grpc-tools (~> 1.17.1)
110
101
  juwelier (~> 2.4.9)
111
102
  rdoc (~> 3.12)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.6.0
@@ -1,5 +1,6 @@
1
1
  require "concurrent/atomics"
2
2
  require 'concurrent'
3
+ require 'faraday'
3
4
  require 'openssl'
4
5
  require 'prefab_pb'
5
6
  require 'prefab_services_pb'
@@ -11,7 +12,7 @@ require 'prefab/config_client'
11
12
  require 'prefab/feature_flag_client'
12
13
  require 'prefab/logger_client'
13
14
  require 'prefab/auth_interceptor'
15
+ require 'prefab/cancellable_interceptor'
14
16
  require 'prefab/noop_cache'
15
17
  require 'prefab/noop_stats'
16
18
  require 'prefab/murmer3'
17
- require 'aws-sdk-s3'
@@ -1,29 +1,31 @@
1
- class AuthInterceptor < GRPC::ClientInterceptor
2
- def initialize(api_key)
3
- version = File.exist?('VERSION') ? File.read('VERSION').chomp : ""
4
- @client = "prefab-cloud-ruby.#{version}".freeze
5
- @api_key = api_key
6
- end
1
+ module Prefab
2
+ class AuthInterceptor < GRPC::ClientInterceptor
3
+ def initialize(api_key)
4
+ version = File.exist?('VERSION') ? File.read('VERSION').chomp : ""
5
+ @client = "prefab-cloud-ruby.#{version}".freeze
6
+ @api_key = api_key
7
+ end
7
8
 
8
- def request_response(request:, call:, method:, metadata:, &block)
9
- shared(metadata, &block)
10
- end
9
+ def request_response(request:, call:, method:, metadata:, &block)
10
+ shared(metadata, &block)
11
+ end
11
12
 
12
- def client_streamer(requests:, call:, method:, metadata:, &block)
13
- shared(metadata, &block)
14
- end
13
+ def client_streamer(requests:, call:, method:, metadata:, &block)
14
+ shared(metadata, &block)
15
+ end
15
16
 
16
- def server_streamer(request:, call:, method:, metadata:, &block)
17
- shared(metadata, &block)
18
- end
17
+ def server_streamer(request:, call:, method:, metadata:, &block)
18
+ shared(metadata, &block)
19
+ end
19
20
 
20
- def bidi_streamer(requests:, call:, method:, metadata:, &block)
21
- shared(metadata, &block)
22
- end
21
+ def bidi_streamer(requests:, call:, method:, metadata:, &block)
22
+ shared(metadata, &block)
23
+ end
23
24
 
24
- def shared(metadata)
25
- metadata['auth'] = @api_key
26
- metadata['client'] = @client
27
- yield
25
+ def shared(metadata)
26
+ metadata['auth'] = @api_key
27
+ metadata['client'] = @client
28
+ yield
29
+ end
28
30
  end
29
31
  end
@@ -0,0 +1,47 @@
1
+ module Prefab
2
+ class CancellableInterceptor < GRPC::ClientInterceptor
3
+ WAIT_SEC = 3
4
+
5
+ def initialize(base_client)
6
+ @base_client = base_client
7
+ end
8
+
9
+ def cancel
10
+ @call.instance_variable_get("@wrapped").instance_variable_get("@call").cancel
11
+ i = 0
12
+ while (i < WAIT_SEC) do
13
+ if @call.instance_variable_get("@wrapped").cancelled?
14
+ @base_client.log_internal Logger::DEBUG, "Cancelled streaming."
15
+ return
16
+ else
17
+ @base_client.log_internal Logger::DEBUG, "Unable to cancel streaming. Trying again"
18
+ @call.instance_variable_get("@wrapped").instance_variable_get("@call").cancel
19
+ i += 1
20
+ sleep(1)
21
+ end
22
+ end
23
+ @base_client.log_internal Logger::INFO, "Unable to cancel streaming."
24
+ end
25
+
26
+ def request_response(request:, call:, method:, metadata:, &block)
27
+ shared(call, &block)
28
+ end
29
+
30
+ def client_streamer(requests:, call:, method:, metadata:, &block)
31
+ shared(call, &block)
32
+ end
33
+
34
+ def server_streamer(request:, call:, method:, metadata:, &block)
35
+ shared(call, &block)
36
+ end
37
+
38
+ def bidi_streamer(requests:, call:, method:, metadata:, &block)
39
+ shared(call, &block)
40
+ end
41
+
42
+ def shared(call)
43
+ @call = call
44
+ yield
45
+ end
46
+ end
47
+ end
data/lib/prefab/client.rb CHANGED
@@ -27,7 +27,7 @@ module Prefab
27
27
  @api_key = api_key
28
28
  @account_id = api_key.split("|")[0].to_i
29
29
  @namespace = namespace
30
- @interceptor = AuthInterceptor.new(api_key)
30
+ @interceptor = Prefab::AuthInterceptor.new(api_key)
31
31
  @stubs = {}
32
32
 
33
33
  at_exit do
@@ -91,13 +91,13 @@ module Prefab
91
91
  "prefab:#{account_id}:#{post_fix}"
92
92
  end
93
93
 
94
- private
95
-
96
94
  def reset!
97
95
  @stubs.clear
98
96
  @_channel = nil
99
97
  end
100
98
 
99
+ private
100
+
101
101
  def stub_for(service, timeout)
102
102
  @stubs["#{service}_#{timeout}"] ||= service::Stub.new(nil,
103
103
  nil,
@@ -2,6 +2,7 @@ module Prefab
2
2
  class ConfigClient
3
3
  RECONNECT_WAIT = 5
4
4
  DEFAULT_CHECKPOINT_FREQ_SEC = 60
5
+ DEFAULT_S3CF_BUCKET = 'http://d2j4ed6ti5snnd.cloudfront.net'
5
6
 
6
7
  def initialize(base_client, timeout)
7
8
  @base_client = base_client
@@ -14,13 +15,16 @@ module Prefab
14
15
  @config_resolver = Prefab::ConfigResolver.new(@base_client, @config_loader)
15
16
 
16
17
  @initialization_lock.acquire_write_lock
17
- @s3 = Aws::S3::Resource.new(region: 'us-east-1')
18
18
 
19
+ @cancellable_interceptor = Prefab::CancellableInterceptor.new(@base_client)
20
+
21
+ @s3_cloud_front = ENV["PREFAB_S3CF_BUCKET"] || DEFAULT_S3CF_BUCKET
19
22
  load_checkpoint
20
23
  start_checkpointing_thread
21
24
  end
22
25
 
23
26
  def start_streaming
27
+ @streaming = true
24
28
  start_api_connection_thread(@config_loader.highwater_mark)
25
29
  end
26
30
 
@@ -64,13 +68,12 @@ module Prefab
64
68
  @_stub = Prefab::ConfigService::Stub.new(nil,
65
69
  nil,
66
70
  channel_override: @base_client.channel,
67
- interceptors: [@base_client.interceptor])
71
+ interceptors: [@base_client.interceptor, @cancellable_interceptor])
68
72
  end
69
73
 
70
74
  # Bootstrap out of the cache
71
75
  # returns the high-watermark of what was in the cache
72
76
  def load_checkpoint
73
-
74
77
  success = load_checkpoint_from_config
75
78
 
76
79
  if !success
@@ -99,11 +102,14 @@ module Prefab
99
102
  end
100
103
 
101
104
  def load_checkpoint_from_s3
102
- resp = @s3.bucket('prefab-cloud-checkpoints-prod').object(@base_client.api_key.gsub("|", "/")).get
103
- deltas = Prefab::ConfigDeltas.decode(resp.body.read)
104
- load_deltas(deltas, :s3)
105
- rescue Aws::S3::Errors::NoSuchKey
106
- @base_client.log_internal Logger::INFO, "No S3 checkpoint. Plan may not support this."
105
+ url = "#{@s3_cloud_front}/#{@base_client.api_key.gsub("|", "/")}"
106
+ resp = Faraday.get url
107
+ if resp.status == 200
108
+ deltas = Prefab::ConfigDeltas.decode(resp.body)
109
+ load_deltas(deltas, :s3)
110
+ else
111
+ @base_client.log_internal Logger::INFO, "No S3 checkpoint. Response #{resp.status} Plan may not support this."
112
+ end
107
113
  end
108
114
 
109
115
 
@@ -151,8 +157,14 @@ module Prefab
151
157
  start_at_id: start_at_id)
152
158
  @base_client.log_internal Logger::DEBUG, "start api connection thread #{start_at_id}"
153
159
  @base_client.stats.increment("prefab.config.api.start")
160
+
154
161
  @api_connection_thread = Thread.new do
155
- while true do
162
+ at_exit do
163
+ @streaming = false
164
+ @cancellable_interceptor.cancel
165
+ end
166
+
167
+ while @streaming do
156
168
  begin
157
169
  resp = stub.get_config(config_req)
158
170
  resp.each do |r|
@@ -163,12 +175,16 @@ module Prefab
163
175
  finish_init!(:streaming)
164
176
  end
165
177
  rescue => e
166
- @base_client.log_internal Logger::INFO, ("config client encountered #{e.message} pausing #{RECONNECT_WAIT}")
167
- reset
168
- sleep(RECONNECT_WAIT)
178
+ if @streaming
179
+ level = e.code == 1 ? Logger::DEBUG : Logger::INFO
180
+ @base_client.log_internal level, ("config client encountered #{e.message} pausing #{RECONNECT_WAIT}")
181
+ reset
182
+ sleep(RECONNECT_WAIT)
183
+ end
169
184
  end
170
185
  end
171
186
  end
187
+
172
188
  end
173
189
  end
174
190
  end
@@ -55,7 +55,7 @@ module Prefab
55
55
 
56
56
  def load_local_overrides
57
57
  override_dir = ENV['PREFAB_CONFIG_OVERRIDE_DIR'] || Dir.home
58
- load_glob(File.join(override_dir, ".prefab*config-overrides.yaml"))
58
+ load_glob(File.join(override_dir, ".prefab*config.yaml"))
59
59
  end
60
60
 
61
61
  def load_glob(glob)
@@ -1,5 +1,7 @@
1
1
  module Prefab
2
2
  class ConfigResolver
3
+ NAMESPACE_DELIMITER = ".".freeze
4
+ NAME_KEY_DELIMITER = ":".freeze
3
5
 
4
6
  def initialize(base_client, config_loader)
5
7
  @lock = Concurrent::ReadWriteLock.new
@@ -14,7 +16,7 @@ module Prefab
14
16
  @lock.with_read_lock do
15
17
  @local_store.each do |k, v|
16
18
  value = v[:value]
17
- str << "|#{k}| |#{value_of(value)}|#{value_of(value).class}\n"
19
+ str << "|#{k}| in #{v[:namespace]} |#{value_of(value)}|#{value_of(value).class}\n"
18
20
  end
19
21
  end
20
22
  str
@@ -52,24 +54,37 @@ module Prefab
52
54
  end
53
55
  end
54
56
 
57
+ # Should client a.b.c see key in namespace a.b? yes
58
+ # Should client a.b.c see key in namespace a.b.c? yes
59
+ # Should client a.b.c see key in namespace a.b.d? no
60
+ # Should client a.b.c see key in namespace ""? yes
61
+ #
62
+ def starts_with_ns?(key_namespace, client_namespace)
63
+ zipped = key_namespace.split(NAMESPACE_DELIMITER).zip(client_namespace.split(NAMESPACE_DELIMITER))
64
+ zipped.map do |k, c|
65
+ (k.nil? || k.empty?) || c == k
66
+ end.all?
67
+ end
68
+
55
69
  def make_local
56
70
  store = {}
57
71
  @config_loader.calc_config.each do |prop, value|
58
72
  property = prop
59
- namespace = ""
60
- split = prop.split(":")
73
+ key_namespace = ""
74
+
75
+ split = prop.split(NAME_KEY_DELIMITER)
61
76
 
62
77
  if split.size > 1
63
- property = split[1..-1].join
64
- namespace = split[0]
78
+ property = split[1..-1].join(NAME_KEY_DELIMITER)
79
+ key_namespace = split[0]
65
80
  end
66
81
 
67
- if (namespace == "") || @namespace.start_with?(namespace)
82
+ if starts_with_ns?(key_namespace, @namespace)
68
83
  existing = store[property]
69
84
  if existing.nil?
70
- store[property] = { namespace: namespace, value: value }
71
- elsif existing[:namespace].split(".").size < namespace.split(".").size
72
- store[property] = { namespace: namespace, value: value }
85
+ store[property] = { namespace: key_namespace, value: value }
86
+ elsif existing[:namespace].split(NAMESPACE_DELIMITER).size < key_namespace.split(NAMESPACE_DELIMITER).size
87
+ store[property] = { namespace: key_namespace, value: value }
73
88
  end
74
89
  end
75
90
  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.2.0 ruby lib
5
+ # stub: prefab-cloud-ruby 0.6.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "prefab-cloud-ruby".freeze
9
- s.version = "0.2.0"
9
+ s.version = "0.6.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 = "2019-01-30"
14
+ s.date = "2021-03-23"
15
15
  s.description = "RateLimits & Config as a service".freeze
16
16
  s.email = "jdwyer@prefab.cloud".freeze
17
17
  s.extra_rdoc_files = [
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
19
19
  "README.md"
20
20
  ]
21
21
  s.files = [
22
+ ".envrc",
22
23
  ".ruby-version",
23
24
  "Gemfile",
24
25
  "Gemfile.lock",
@@ -29,6 +30,7 @@ Gem::Specification.new do |s|
29
30
  "compile_protos.sh",
30
31
  "lib/prefab-cloud-ruby.rb",
31
32
  "lib/prefab/auth_interceptor.rb",
33
+ "lib/prefab/cancellable_interceptor.rb",
32
34
  "lib/prefab/client.rb",
33
35
  "lib/prefab/config_client.rb",
34
36
  "lib/prefab/config_loader.rb",
@@ -60,7 +62,7 @@ Gem::Specification.new do |s|
60
62
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
61
63
  s.add_runtime_dependency(%q<concurrent-ruby>.freeze, [">= 1.0.5", "~> 1.0"])
62
64
  s.add_runtime_dependency(%q<faraday>.freeze, [">= 0"])
63
- s.add_runtime_dependency(%q<grpc>.freeze, ["~> 1.17.1"])
65
+ s.add_runtime_dependency(%q<grpc>.freeze, [">= 0"])
64
66
  s.add_development_dependency(%q<grpc-tools>.freeze, ["~> 1.17.1"])
65
67
  s.add_development_dependency(%q<shoulda>.freeze, [">= 0"])
66
68
  s.add_development_dependency(%q<rdoc>.freeze, ["~> 3.12"])
@@ -70,7 +72,7 @@ Gem::Specification.new do |s|
70
72
  else
71
73
  s.add_dependency(%q<concurrent-ruby>.freeze, [">= 1.0.5", "~> 1.0"])
72
74
  s.add_dependency(%q<faraday>.freeze, [">= 0"])
73
- s.add_dependency(%q<grpc>.freeze, ["~> 1.17.1"])
75
+ s.add_dependency(%q<grpc>.freeze, [">= 0"])
74
76
  s.add_dependency(%q<grpc-tools>.freeze, ["~> 1.17.1"])
75
77
  s.add_dependency(%q<shoulda>.freeze, [">= 0"])
76
78
  s.add_dependency(%q<rdoc>.freeze, ["~> 3.12"])
@@ -81,7 +83,7 @@ Gem::Specification.new do |s|
81
83
  else
82
84
  s.add_dependency(%q<concurrent-ruby>.freeze, [">= 1.0.5", "~> 1.0"])
83
85
  s.add_dependency(%q<faraday>.freeze, [">= 0"])
84
- s.add_dependency(%q<grpc>.freeze, ["~> 1.17.1"])
86
+ s.add_dependency(%q<grpc>.freeze, [">= 0"])
85
87
  s.add_dependency(%q<grpc-tools>.freeze, ["~> 1.17.1"])
86
88
  s.add_dependency(%q<shoulda>.freeze, [">= 0"])
87
89
  s.add_dependency(%q<rdoc>.freeze, ["~> 3.12"])
@@ -25,8 +25,6 @@ class TestConfigLoader < Minitest::Test
25
25
  assert_equal 5, @loader.highwater_mark
26
26
  end
27
27
 
28
-
29
-
30
28
  def test_keeps_most_recent
31
29
  assert_equal 0, @loader.highwater_mark
32
30
  @loader.set(Prefab::ConfigDelta.new(id: 1, key: "sample_int", value: Prefab::ConfigValue.new(int: 1)))
@@ -18,7 +18,6 @@ class TestConfigResolver < Minitest::Test
18
18
  @resolver = Prefab::ConfigResolver.new(MockBaseClient.new, @loader)
19
19
  assert_equal "value_none", @resolver.get("key")
20
20
 
21
-
22
21
  @resolverA = resolver_for_namespace("projectA", @loader)
23
22
  assert_equal "valueA", @resolverA.get("key")
24
23
 
@@ -37,6 +36,71 @@ class TestConfigResolver < Minitest::Test
37
36
  end
38
37
  end
39
38
 
39
+ def test_starts_with_ns
40
+ @loader = MockConfigLoader.new
41
+ @loader.stub :calc_config, {} do
42
+ resolver = Prefab::ConfigResolver.new(MockBaseClient.new, @loader)
43
+ assert resolver.send(:starts_with_ns?, "", "a")
44
+ assert resolver.send(:starts_with_ns?, "a", "a")
45
+ assert resolver.send(:starts_with_ns?, "a", "a.b")
46
+ assert !resolver.send(:starts_with_ns?, "a.b", "a")
47
+
48
+ assert resolver.send(:starts_with_ns?, "corp", "corp.proj.proja")
49
+ assert resolver.send(:starts_with_ns?, "corp.proj", "corp.proj.proja")
50
+ assert resolver.send(:starts_with_ns?, "corp.proj.proja", "corp.proj.proja")
51
+ assert !resolver.send(:starts_with_ns?, "corp.proj.projb", "corp.proj.proja")
52
+
53
+ # corp:a:b is not a real delimited namespace
54
+ assert !resolver.send(:starts_with_ns?, "corp", "corp:a:b")
55
+ assert resolver.send(:starts_with_ns?, "foo", "foo.baz")
56
+ assert resolver.send(:starts_with_ns?, "foo.baz", "foo.baz")
57
+ assert !resolver.send(:starts_with_ns?, "foo.baz", "foo.bazz")
58
+ end
59
+ end
60
+
61
+ # colons are not allowed in keys, but verify behavior anyway
62
+ def test_keys_with_colons
63
+ @loader = MockConfigLoader.new
64
+ loaded_values = {
65
+ "Key:With:Colons" => Prefab::ConfigValue.new(string: "value"),
66
+ "proj:apikey" => Prefab::ConfigValue.new(string: "v2")
67
+ }
68
+
69
+ @loader.stub :calc_config, loaded_values do
70
+
71
+ r = resolver_for_namespace("foo", @loader)
72
+ assert_nil r.get("apikey")
73
+
74
+ r = resolver_for_namespace("proj", @loader)
75
+ assert_equal "v2", r.get("apikey")
76
+
77
+ r = resolver_for_namespace("", @loader)
78
+ assert_nil r.get("apikey")
79
+
80
+
81
+ @resolverKeyWith = resolver_for_namespace("Ket:With", @loader)
82
+ assert_nil @resolverKeyWith.get("Colons")
83
+ assert_nil @resolverKeyWith.get("With:Colons")
84
+ assert_nil @resolverKeyWith.get("Key:With:Colons")
85
+
86
+ @resolverKeyWithExtra = resolver_for_namespace("Key:With:Extra", @loader)
87
+ puts @resolverKeyWithExtra.to_s
88
+ assert_nil @resolverKeyWithExtra.get("Colons")
89
+ assert_nil @resolverKeyWithExtra.get("With:Colons")
90
+ assert_nil @resolverKeyWithExtra.get("Key:With:Colons")
91
+
92
+ @resolverKey = resolver_for_namespace("Key", @loader)
93
+ assert_equal "value", @resolverKey.get("With:Colons")
94
+ assert_nil @resolverKey.get("Colons")
95
+ assert_nil @resolverKey.get("Key:With:Colons")
96
+
97
+ @resolverWithProperlySegmentedNamespace = resolver_for_namespace("Key.With.Extra", @loader)
98
+ assert_nil @resolverWithProperlySegmentedNamespace.get("Colons")
99
+ assert_equal "value", @resolverWithProperlySegmentedNamespace.get("With:Colons")
100
+ assert_nil @resolverWithProperlySegmentedNamespace.get("Key:With:Colons")
101
+ end
102
+ end
103
+
40
104
  def resolver_for_namespace(namespace, loader)
41
105
  Prefab::ConfigResolver.new(MockBaseClient.new(namespace: namespace), loader)
42
106
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prefab-cloud-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Dwyer
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-30 00:00:00.000000000 Z
11
+ date: 2021-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -48,16 +48,16 @@ dependencies:
48
48
  name: grpc
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - "~>"
51
+ - - ">="
52
52
  - !ruby/object:Gem::Version
53
- version: 1.17.1
53
+ version: '0'
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - "~>"
58
+ - - ">="
59
59
  - !ruby/object:Gem::Version
60
- version: 1.17.1
60
+ version: '0'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: grpc-tools
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +150,7 @@ extra_rdoc_files:
150
150
  - LICENSE.txt
151
151
  - README.md
152
152
  files:
153
+ - ".envrc"
153
154
  - ".ruby-version"
154
155
  - Gemfile
155
156
  - Gemfile.lock
@@ -160,6 +161,7 @@ files:
160
161
  - compile_protos.sh
161
162
  - lib/prefab-cloud-ruby.rb
162
163
  - lib/prefab/auth_interceptor.rb
164
+ - lib/prefab/cancellable_interceptor.rb
163
165
  - lib/prefab/client.rb
164
166
  - lib/prefab/config_client.rb
165
167
  - lib/prefab/config_loader.rb
@@ -183,7 +185,7 @@ homepage: http://github.com/prefab-cloud/prefab-cloud-ruby
183
185
  licenses:
184
186
  - MIT
185
187
  metadata: {}
186
- post_install_message:
188
+ post_install_message:
187
189
  rdoc_options: []
188
190
  require_paths:
189
191
  - lib
@@ -198,9 +200,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
198
200
  - !ruby/object:Gem::Version
199
201
  version: '0'
200
202
  requirements: []
201
- rubyforge_project:
203
+ rubyforge_project:
202
204
  rubygems_version: 2.6.14
203
- signing_key:
205
+ signing_key:
204
206
  specification_version: 4
205
207
  summary: Prefab Ruby Infrastructure
206
208
  test_files: []