prefab-cloud-ruby 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/prefab/client.rb +3 -3
- data/lib/prefab/config_resolver.rb +10 -6
- data/lib/prefab_pb.rb +17 -2
- data/lib/prefab_services_pb.rb +14 -0
- data/prefab-cloud-ruby.gemspec +3 -3
- data/test/harness_server.rb +6 -3
- data/test/test_config_resolver.rb +14 -9
- data/test/test_feature_flag_client.rb +3 -3
- data/test/test_helper.rb +24 -8
- data/test/test_logger.rb +0 -10
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c18d5a31a2f535269b3faf262b82a57e67b75ceee5581c5ef6f8cea7bbdb416b
|
|
4
|
+
data.tar.gz: d7125da40abab76dc25e37459cdde3a891801dc4f630c3f3f2f22f7f65ef2f5d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 38e1ad427078327f05b01b869d5f0879819271b372d8373996d5d592e3d4efa92bed6b59d061d92dc2a21eb49c6c529140ae9f9b5d8825fc2b828840d1b23a7f
|
|
7
|
+
data.tar.gz: 88cf63bf9dfdc9c103660240a5d2b35f27103eda55c28a96cb16943da41adf4ffa85928533fd739a868b3b5f5bb5ef565b80073f75712f3bb62305921694d1b2
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.10.0
|
data/lib/prefab/client.rb
CHANGED
|
@@ -8,7 +8,7 @@ module Prefab
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
attr_reader :project_id, :shared_cache, :stats, :namespace, :interceptor, :api_key, :
|
|
11
|
+
attr_reader :project_id, :shared_cache, :stats, :namespace, :interceptor, :api_key, :project_env_id, :prefab_api_url
|
|
12
12
|
|
|
13
13
|
def initialize(api_key: ENV['PREFAB_API_KEY'],
|
|
14
14
|
logdev: nil,
|
|
@@ -27,13 +27,13 @@ module Prefab
|
|
|
27
27
|
@shared_cache = (shared_cache || NoopCache.new)
|
|
28
28
|
@api_key = api_key
|
|
29
29
|
@project_id = api_key.split("-")[0].to_i
|
|
30
|
-
@
|
|
30
|
+
@project_env_id = api_key.split("-")[1].to_i
|
|
31
31
|
@namespace = namespace
|
|
32
32
|
@interceptor = Prefab::AuthInterceptor.new(api_key)
|
|
33
33
|
@stubs = {}
|
|
34
34
|
@prefab_api_url = ENV["PREFAB_API_URL"] || 'https://api.prefab.cloud'
|
|
35
35
|
@prefab_grpc_url = ENV["PREFAB_GRPC_URL"] || 'grpc.prefab.cloud:443'
|
|
36
|
-
log_internal Logger::INFO, "Prefab Initializing in environment: '#{@
|
|
36
|
+
log_internal Logger::INFO, "Prefab Initializing in environment: '#{@project_env_id}' and namespace: '#{@namespace}'"
|
|
37
37
|
log_internal Logger::INFO, "Prefab Connecting to: #{@prefab_api_url} and #{@prefab_grpc_url} Secure: #{http_secure?}"
|
|
38
38
|
at_exit do
|
|
39
39
|
channel.destroy
|
|
@@ -6,7 +6,7 @@ module Prefab
|
|
|
6
6
|
def initialize(base_client, config_loader)
|
|
7
7
|
@lock = Concurrent::ReadWriteLock.new
|
|
8
8
|
@local_store = {}
|
|
9
|
-
@
|
|
9
|
+
@project_env_id = base_client.project_env_id
|
|
10
10
|
@namespace = base_client.namespace
|
|
11
11
|
@config_loader = config_loader
|
|
12
12
|
make_local
|
|
@@ -16,8 +16,12 @@ module Prefab
|
|
|
16
16
|
str = ""
|
|
17
17
|
@lock.with_read_lock do
|
|
18
18
|
@local_store.each do |k, v|
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
if v.nil?
|
|
20
|
+
str<< "|#{k}| tombstone\n"
|
|
21
|
+
else
|
|
22
|
+
value = v[:value]
|
|
23
|
+
str << "|#{k}| from #{v[:match]} |#{value_of(value)}|#{value_of(value).class}\n"
|
|
24
|
+
end
|
|
21
25
|
end
|
|
22
26
|
end
|
|
23
27
|
str
|
|
@@ -60,14 +64,14 @@ module Prefab
|
|
|
60
64
|
store = {}
|
|
61
65
|
@config_loader.calc_config.each do |key, config|
|
|
62
66
|
sortable = config.rows.map do |row|
|
|
63
|
-
if
|
|
64
|
-
if row.
|
|
67
|
+
if row.project_env_id != 0
|
|
68
|
+
if row.project_env_id == @project_env_id
|
|
65
69
|
if !row.namespace.empty?
|
|
66
70
|
(starts_with, count) = starts_with_ns?(row.namespace, @namespace)
|
|
67
71
|
# rubocop:disable BlockNesting
|
|
68
72
|
{ sortable: 2 + count, match: row.namespace, value: row.value, config: config} if starts_with
|
|
69
73
|
else
|
|
70
|
-
{ sortable: 1, match: row.
|
|
74
|
+
{ sortable: 1, match: row.project_env_id, value: row.value, config: config}
|
|
71
75
|
end
|
|
72
76
|
end
|
|
73
77
|
else
|
data/lib/prefab_pb.rb
CHANGED
|
@@ -8,7 +8,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
|
8
8
|
add_message "prefab.ConfigServicePointer" do
|
|
9
9
|
optional :project_id, :int64, 1
|
|
10
10
|
optional :start_at_id, :int64, 2
|
|
11
|
-
optional :
|
|
11
|
+
optional :project_env_id, :int64, 3
|
|
12
12
|
end
|
|
13
13
|
add_message "prefab.ConfigValue" do
|
|
14
14
|
oneof :type do
|
|
@@ -34,7 +34,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
|
34
34
|
repeated :variants, :message, 6, "prefab.FeatureFlagVariant"
|
|
35
35
|
end
|
|
36
36
|
add_message "prefab.ConfigRow" do
|
|
37
|
-
optional :
|
|
37
|
+
optional :project_env_id, :int64, 1
|
|
38
38
|
optional :namespace, :string, 2
|
|
39
39
|
optional :value, :message, 3, "prefab.ConfigValue"
|
|
40
40
|
end
|
|
@@ -173,6 +173,19 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
|
173
173
|
optional :message, :string, 1
|
|
174
174
|
optional :new_id, :int64, 2
|
|
175
175
|
end
|
|
176
|
+
add_message "prefab.IdBlock" do
|
|
177
|
+
optional :project_id, :int64, 1
|
|
178
|
+
optional :project_env_id, :int64, 2
|
|
179
|
+
optional :sequence_name, :string, 3
|
|
180
|
+
optional :start, :int64, 4
|
|
181
|
+
optional :end, :int64, 5
|
|
182
|
+
end
|
|
183
|
+
add_message "prefab.IdBlockRequest" do
|
|
184
|
+
optional :project_id, :int64, 1
|
|
185
|
+
optional :project_env_id, :int64, 2
|
|
186
|
+
optional :sequence_name, :string, 3
|
|
187
|
+
optional :size, :int64, 4
|
|
188
|
+
end
|
|
176
189
|
add_enum "prefab.OnFailure" do
|
|
177
190
|
value :NOT_SET, 0
|
|
178
191
|
value :LOG_AND_PASS, 1
|
|
@@ -209,5 +222,7 @@ module Prefab
|
|
|
209
222
|
BatchRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.BatchRequest").msgclass
|
|
210
223
|
BasicResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.BasicResponse").msgclass
|
|
211
224
|
CreationResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.CreationResponse").msgclass
|
|
225
|
+
IdBlock = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.IdBlock").msgclass
|
|
226
|
+
IdBlockRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.IdBlockRequest").msgclass
|
|
212
227
|
OnFailure = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.OnFailure").enummodule
|
|
213
228
|
end
|
data/lib/prefab_services_pb.rb
CHANGED
|
@@ -33,6 +33,20 @@ module Prefab
|
|
|
33
33
|
rpc :Upsert, ::Prefab::Config, ::Prefab::CreationResponse
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
Stub = Service.rpc_stub_class
|
|
37
|
+
end
|
|
38
|
+
module IdService
|
|
39
|
+
class Service
|
|
40
|
+
|
|
41
|
+
include ::GRPC::GenericService
|
|
42
|
+
|
|
43
|
+
self.marshal_class_method = :encode
|
|
44
|
+
self.unmarshal_class_method = :decode
|
|
45
|
+
self.service_name = 'prefab.IdService'
|
|
46
|
+
|
|
47
|
+
rpc :GetBlock, ::Prefab::IdBlockRequest, ::Prefab::IdBlock
|
|
48
|
+
end
|
|
49
|
+
|
|
36
50
|
Stub = Service.rpc_stub_class
|
|
37
51
|
end
|
|
38
52
|
end
|
data/prefab-cloud-ruby.gemspec
CHANGED
|
@@ -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.
|
|
5
|
+
# stub: prefab-cloud-ruby 0.10.0 ruby lib
|
|
6
6
|
|
|
7
7
|
Gem::Specification.new do |s|
|
|
8
8
|
s.name = "prefab-cloud-ruby".freeze
|
|
9
|
-
s.version = "0.
|
|
9
|
+
s.version = "0.10.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-03-
|
|
14
|
+
s.date = "2022-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 = [
|
data/test/harness_server.rb
CHANGED
|
@@ -15,28 +15,31 @@ class RackApp
|
|
|
15
15
|
|
|
16
16
|
key = props["key"]
|
|
17
17
|
namespace = props["namespace"]
|
|
18
|
-
|
|
18
|
+
project_env_id = props["project_env_id"]
|
|
19
19
|
user_key = props["user_key"]
|
|
20
20
|
is_feature_flag = !props["feature_flag"].nil?
|
|
21
21
|
|
|
22
22
|
client = Prefab::Client.new(
|
|
23
|
-
api_key: "1-#{
|
|
23
|
+
api_key: "1-#{project_env_id}-local_development_api_key-SDK", #sets environment
|
|
24
24
|
namespace: namespace,
|
|
25
25
|
)
|
|
26
26
|
|
|
27
27
|
puts "Key #{key}"
|
|
28
28
|
puts "User #{user_key}"
|
|
29
|
-
puts "
|
|
29
|
+
puts "project_env_id #{project_env_id}"
|
|
30
30
|
puts "Namespace #{namespace}"
|
|
31
31
|
puts "Props! #{props}"
|
|
32
32
|
puts "is_feature_flag! #{is_feature_flag}"
|
|
33
33
|
|
|
34
|
+
puts client.config_client.to_s
|
|
35
|
+
|
|
34
36
|
if is_feature_flag
|
|
35
37
|
puts "EVALFF #{key} #{user_key}"
|
|
36
38
|
rtn = client.feature_flag_client.get(key, user_key, []).to_s
|
|
37
39
|
else
|
|
38
40
|
rtn = client.config_client.get(key).to_s
|
|
39
41
|
end
|
|
42
|
+
|
|
40
43
|
puts "return #{rtn}"
|
|
41
44
|
|
|
42
45
|
[200, { "Content-Type" => "text/plain" }, rtn]
|
|
@@ -2,6 +2,10 @@ require 'test_helper'
|
|
|
2
2
|
|
|
3
3
|
class TestConfigResolver < Minitest::Test
|
|
4
4
|
|
|
5
|
+
STAGING_ENV_ID = 1
|
|
6
|
+
PRODUCTION_ENV_ID = 2
|
|
7
|
+
TEST_ENV_ID = 3
|
|
8
|
+
|
|
5
9
|
def test_resolution
|
|
6
10
|
@loader = MockConfigLoader.new
|
|
7
11
|
|
|
@@ -13,26 +17,26 @@ class TestConfigResolver < Minitest::Test
|
|
|
13
17
|
value: Prefab::ConfigValue.new(string: "value_no_env_default"),
|
|
14
18
|
),
|
|
15
19
|
Prefab::ConfigRow.new(
|
|
16
|
-
|
|
20
|
+
project_env_id: TEST_ENV_ID,
|
|
17
21
|
value: Prefab::ConfigValue.new(string: "value_none"),
|
|
18
22
|
),
|
|
19
23
|
Prefab::ConfigRow.new(
|
|
20
|
-
|
|
24
|
+
project_env_id: TEST_ENV_ID,
|
|
21
25
|
namespace: "projectA",
|
|
22
26
|
value: Prefab::ConfigValue.new(string: "valueA"),
|
|
23
27
|
),
|
|
24
28
|
Prefab::ConfigRow.new(
|
|
25
|
-
|
|
29
|
+
project_env_id: TEST_ENV_ID,
|
|
26
30
|
namespace: "projectB",
|
|
27
31
|
value: Prefab::ConfigValue.new(string: "valueB"),
|
|
28
32
|
),
|
|
29
33
|
Prefab::ConfigRow.new(
|
|
30
|
-
|
|
34
|
+
project_env_id: TEST_ENV_ID,
|
|
31
35
|
namespace: "projectB.subprojectX",
|
|
32
36
|
value: Prefab::ConfigValue.new(string: "projectB.subprojectX"),
|
|
33
37
|
),
|
|
34
38
|
Prefab::ConfigRow.new(
|
|
35
|
-
|
|
39
|
+
project_env_id: TEST_ENV_ID,
|
|
36
40
|
namespace: "projectB.subprojectY",
|
|
37
41
|
value: Prefab::ConfigValue.new(string: "projectB.subprojectY"),
|
|
38
42
|
),
|
|
@@ -49,7 +53,7 @@ class TestConfigResolver < Minitest::Test
|
|
|
49
53
|
|
|
50
54
|
@loader.stub :calc_config, loaded_values do
|
|
51
55
|
|
|
52
|
-
@resolverA = resolver_for_namespace("", @loader,
|
|
56
|
+
@resolverA = resolver_for_namespace("", @loader, project_env_id: PRODUCTION_ENV_ID)
|
|
53
57
|
assert_equal "value_no_env_default", @resolverA.get("key")
|
|
54
58
|
|
|
55
59
|
## below here in the test env
|
|
@@ -100,6 +104,7 @@ class TestConfigResolver < Minitest::Test
|
|
|
100
104
|
end
|
|
101
105
|
|
|
102
106
|
def test_special_ff_variant_copying
|
|
107
|
+
|
|
103
108
|
@loader = MockConfigLoader.new
|
|
104
109
|
loaded_values = {
|
|
105
110
|
"ff" => Prefab::Config.new(
|
|
@@ -114,7 +119,7 @@ class TestConfigResolver < Minitest::Test
|
|
|
114
119
|
inactive_variant_idx: 0,
|
|
115
120
|
default: Prefab::VariantDistribution.new(variant_idx: 1)
|
|
116
121
|
)) },
|
|
117
|
-
{
|
|
122
|
+
{ project_env_id: TEST_ENV_ID,
|
|
118
123
|
value: Prefab::ConfigValue.new(feature_flag: Prefab::FeatureFlag.new(
|
|
119
124
|
inactive_variant_idx: 0,
|
|
120
125
|
default: Prefab::VariantDistribution.new(variant_idx: 2)
|
|
@@ -183,8 +188,8 @@ class TestConfigResolver < Minitest::Test
|
|
|
183
188
|
end
|
|
184
189
|
end
|
|
185
190
|
|
|
186
|
-
def resolver_for_namespace(namespace, loader,
|
|
187
|
-
Prefab::ConfigResolver.new(MockBaseClient.new(namespace: namespace,
|
|
191
|
+
def resolver_for_namespace(namespace, loader, project_env_id: TEST_ENV_ID)
|
|
192
|
+
Prefab::ConfigResolver.new(MockBaseClient.new(namespace: namespace, project_env_id: project_env_id), loader)
|
|
188
193
|
end
|
|
189
194
|
|
|
190
195
|
end
|
|
@@ -135,7 +135,7 @@ class TestFeatureFlagClient < Minitest::Test
|
|
|
135
135
|
|
|
136
136
|
def test_segments
|
|
137
137
|
segment_key = "prefab-segment-beta-group"
|
|
138
|
-
@mock_base_client.mock_this_config(segment_key,
|
|
138
|
+
@mock_base_client.config_client.mock_this_config(segment_key,
|
|
139
139
|
Prefab::Segment.new(
|
|
140
140
|
name: "Beta Group",
|
|
141
141
|
includes: ["user:1"]
|
|
@@ -170,7 +170,7 @@ class TestFeatureFlagClient < Minitest::Test
|
|
|
170
170
|
|
|
171
171
|
def test_in_multiple_segments_has_or_behavior
|
|
172
172
|
segment_key_one = "prefab-segment-segment-1"
|
|
173
|
-
@mock_base_client.mock_this_config(segment_key_one,
|
|
173
|
+
@mock_base_client.config_client.mock_this_config(segment_key_one,
|
|
174
174
|
Prefab::Segment.new(
|
|
175
175
|
name: "Segment-1",
|
|
176
176
|
includes: ["user:1", "user:2"],
|
|
@@ -178,7 +178,7 @@ class TestFeatureFlagClient < Minitest::Test
|
|
|
178
178
|
)
|
|
179
179
|
)
|
|
180
180
|
segment_key_two = "prefab-segment-segment-2"
|
|
181
|
-
@mock_base_client.mock_this_config(segment_key_two,
|
|
181
|
+
@mock_base_client.config_client.mock_this_config(segment_key_two,
|
|
182
182
|
Prefab::Segment.new(
|
|
183
183
|
name: "Segment-2",
|
|
184
184
|
includes: ["user:3", "user:4"],
|
data/test/test_helper.rb
CHANGED
|
@@ -2,33 +2,49 @@ require 'minitest/autorun'
|
|
|
2
2
|
require 'prefab-cloud-ruby'
|
|
3
3
|
|
|
4
4
|
class MockBaseClient
|
|
5
|
-
|
|
5
|
+
STAGING_ENV_ID = 1
|
|
6
|
+
PRODUCTION_ENV_ID = 2
|
|
7
|
+
TEST_ENV_ID = 3
|
|
8
|
+
attr_reader :namespace, :logger, :project_env_id, :config_client
|
|
6
9
|
|
|
7
|
-
def initialize(
|
|
8
|
-
@
|
|
10
|
+
def initialize(project_env_id: TEST_ENV_ID, namespace: "")
|
|
11
|
+
@project_env_id = project_env_id
|
|
9
12
|
@namespace = namespace
|
|
10
13
|
@logger = Logger.new($stdout)
|
|
11
|
-
@
|
|
14
|
+
@config_client = MockConfigClient.new
|
|
12
15
|
end
|
|
13
16
|
|
|
14
17
|
def project_id
|
|
15
18
|
1
|
|
16
19
|
end
|
|
17
20
|
|
|
21
|
+
def project_env_id
|
|
22
|
+
@project_env_id
|
|
23
|
+
end
|
|
24
|
+
|
|
18
25
|
def log_internal level, message
|
|
19
26
|
end
|
|
20
27
|
|
|
21
|
-
def
|
|
22
|
-
@config_values[key]
|
|
28
|
+
def config_value key
|
|
29
|
+
@config_values[key]
|
|
23
30
|
end
|
|
24
31
|
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class MockConfigClient
|
|
35
|
+
def initialize(config_values = {})
|
|
36
|
+
@config_values = config_values
|
|
37
|
+
end
|
|
25
38
|
def get(key)
|
|
26
39
|
@config_values[key]
|
|
27
40
|
end
|
|
28
41
|
|
|
29
42
|
def get_config(key)
|
|
30
|
-
|
|
31
|
-
|
|
43
|
+
Prefab::Config.new(value: @config_values[key], key: key)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def mock_this_config key, config_value
|
|
47
|
+
@config_values[key] = config_value
|
|
32
48
|
end
|
|
33
49
|
end
|
|
34
50
|
|
data/test/test_logger.rb
CHANGED
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.
|
|
4
|
+
version: 0.10.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jeff Dwyer
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-03-
|
|
11
|
+
date: 2022-03-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: concurrent-ruby
|