rox-rollout 4.1.0 → 5.0.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 +5 -5
- data/.circleci/config.yml +51 -23
- data/.editorconfig +12 -0
- data/.github/workflows/ruby.yml +20 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +17 -0
- data/Gemfile +2 -2
- data/README.md +32 -0
- data/Rakefile +12 -9
- data/bin/console +3 -4
- data/e2e-server/run_server.sh +12 -0
- data/e2e-server/server.rb +158 -0
- data/e2e/container.rb +11 -14
- data/e2e/custom_props.rb +9 -9
- data/e2e/rox_e2e_test.rb +18 -20
- data/e2e/test_vars.rb +3 -6
- data/example/local.rb +40 -0
- data/lib/rox/core/analytics.rb +18 -0
- data/lib/rox/core/client/buid.rb +9 -44
- data/lib/rox/core/client/device_properties.rb +8 -2
- data/lib/rox/core/client/dynamic_api.rb +53 -15
- data/lib/rox/core/client/internal_flags.rb +14 -2
- data/lib/rox/core/client/sdk_settings.rb +1 -1
- data/lib/rox/core/configuration/configuration.rb +1 -1
- data/lib/rox/core/configuration/configuration_fetched_args.rb +2 -2
- data/lib/rox/core/configuration/configuration_fetched_invoker.rb +8 -3
- data/lib/rox/core/configuration/configuration_parser.rb +39 -38
- data/lib/rox/core/configuration/fetcher_error.rb +1 -1
- data/lib/rox/core/configuration/fetcher_status.rb +1 -1
- data/lib/rox/core/configuration/models/experiment_model.rb +1 -1
- data/lib/rox/core/configuration/models/target_group_model.rb +1 -1
- data/lib/rox/core/consts/build.rb +3 -3
- data/lib/rox/core/consts/environment.rb +34 -10
- data/lib/rox/core/consts/property_type.rb +18 -17
- data/lib/rox/core/context/merged_context.rb +2 -1
- data/lib/rox/core/core.rb +101 -33
- data/lib/rox/core/entities/default_flag_values.rb +10 -0
- data/lib/rox/core/entities/flag.rb +22 -7
- data/lib/rox/core/entities/flag_setter.rb +6 -6
- data/lib/rox/core/entities/rox_double.rb +11 -0
- data/lib/rox/core/entities/rox_int.rb +11 -0
- data/lib/rox/core/entities/{variant.rb → rox_string.rb} +20 -13
- data/lib/rox/core/error_handling/exception_trigger.rb +10 -0
- data/lib/rox/core/error_handling/userspace_handler_exception.rb +12 -0
- data/lib/rox/core/error_handling/userspace_unhandled_error_invoker.rb +41 -0
- data/lib/rox/core/impression/impression_args.rb +2 -2
- data/lib/rox/core/impression/impression_invoker.rb +41 -7
- data/lib/rox/core/impression/models/experiment.rb +1 -1
- data/lib/rox/core/impression/models/reporting_value.rb +10 -2
- data/lib/rox/core/logging/logging.rb +3 -3
- data/lib/rox/core/logging/no_op_logger.rb +1 -1
- data/lib/rox/core/network/configuration_fetch_result.rb +1 -1
- data/lib/rox/core/network/configuration_fetcher.rb +9 -8
- data/lib/rox/core/network/configuration_fetcher_base.rb +1 -1
- data/lib/rox/core/network/configuration_fetcher_roxy.rb +4 -4
- data/lib/rox/core/network/configuration_fetcher_self_managed.rb +30 -0
- data/lib/rox/core/network/configuration_source.rb +1 -1
- data/lib/rox/core/network/request.rb +3 -3
- data/lib/rox/core/network/request_configuration_builder.rb +12 -9
- data/lib/rox/core/network/request_data.rb +1 -1
- data/lib/rox/core/network/response.rb +20 -4
- data/lib/rox/core/network/state_sender.rb +146 -0
- data/lib/rox/core/notifications/notification_listener.rb +4 -4
- data/lib/rox/core/properties/custom_property.rb +1 -1
- data/lib/rox/core/properties/custom_property_type.rb +1 -1
- data/lib/rox/core/properties/device_property.rb +2 -2
- data/lib/rox/core/properties/property_factory.rb +132 -0
- data/lib/rox/core/register/registerer.rb +13 -12
- data/lib/rox/core/reporting/error_reporter.rb +14 -13
- data/lib/rox/core/repositories/custom_property_repository.rb +1 -1
- data/lib/rox/core/repositories/experiment_repository.rb +2 -4
- data/lib/rox/core/repositories/flag_repository.rb +8 -8
- data/lib/rox/core/repositories/roxx/experiments_extensions.rb +8 -8
- data/lib/rox/core/repositories/roxx/properties_extensions.rb +32 -7
- data/lib/rox/core/repositories/target_group_repository.rb +2 -4
- data/lib/rox/core/roxx/evaluation_result.rb +2 -0
- data/lib/rox/core/roxx/node.rb +1 -1
- data/lib/rox/core/roxx/parser.rb +46 -20
- data/lib/rox/core/roxx/regular_expression_extensions.rb +6 -3
- data/lib/rox/core/roxx/string_tokenizer.rb +3 -1
- data/lib/rox/core/roxx/symbols.rb +1 -1
- data/lib/rox/core/roxx/token_type.rb +1 -1
- data/lib/rox/core/roxx/tokenized_expression.rb +16 -12
- data/lib/rox/core/roxx/value_compare_extensions.rb +49 -29
- data/lib/rox/core/security/signature_verifier.rb +3 -3
- data/lib/rox/core/security/signature_verifier_mock.rb +12 -0
- data/lib/rox/core/utils/debouncer.rb +18 -0
- data/lib/rox/core/utils/type_utils.rb +1 -1
- data/lib/rox/server/client/sdk_settings.rb +1 -1
- data/lib/rox/server/client/server_properties.rb +1 -1
- data/lib/rox/server/flags/normalize_flag_type.rb +25 -0
- data/lib/rox/server/flags/rox_double.rb +8 -0
- data/lib/rox/server/flags/rox_flag.rb +1 -1
- data/lib/rox/server/flags/rox_int.rb +8 -0
- data/lib/rox/server/flags/rox_string.rb +8 -0
- data/lib/rox/server/flags/server_entities_provider.rb +14 -4
- data/lib/rox/server/logging/server_logger.rb +2 -2
- data/lib/rox/server/rox_options.rb +39 -8
- data/lib/rox/server/rox_server.rb +81 -60
- data/lib/rox/version.rb +1 -1
- data/rox.gemspec +13 -9
- metadata +95 -36
- data/README_DEVELOP.md +0 -19
- data/_archive/.document +0 -5
- data/_archive/.rspec +0 -1
- data/_archive/Gemfile +0 -15
- data/_archive/Gemfile.lock +0 -87
- data/_archive/README.md +0 -32
- data/_archive/README.rdoc +0 -19
- data/_archive/Rakefile +0 -50
- data/_archive/lib/expr_function_definition.rb +0 -52
- data/_archive/lib/function_definition.rb +0 -48
- data/_archive/lib/function_token.rb +0 -12
- data/_archive/lib/object_extends.rb +0 -12
- data/_archive/lib/ruby_interpreter.rb +0 -292
- data/_archive/lib/stack.rb +0 -48
- data/_archive/lib/string_extends.rb +0 -14
- data/_archive/spec/ruby_interpreter_spec.rb +0 -203
- data/_archive/spec/spec_helper.rb +0 -30
- data/_archive/spec/stack_spec.rb +0 -77
- data/lib/rox/server/flags/rox_variant.rb +0 -8
data/e2e/custom_props.rb
CHANGED
@@ -2,31 +2,31 @@ module E2E
|
|
2
2
|
class CustomProps
|
3
3
|
def self.create_custom_props
|
4
4
|
Rox::Server::RoxServer.set_custom_string_property('string_prop1', 'Hello')
|
5
|
-
Rox::Server::RoxServer.set_custom_string_property('string_prop2') do |
|
5
|
+
Rox::Server::RoxServer.set_custom_string_property('string_prop2') do |_context|
|
6
6
|
TestVars.is_computed_string_prop_called = true
|
7
7
|
'World'
|
8
8
|
end
|
9
9
|
|
10
10
|
Rox::Server::RoxServer.set_custom_boolean_property('bool_prop1', true)
|
11
|
-
Rox::Server::RoxServer.set_custom_boolean_property('bool_prop2') do |
|
11
|
+
Rox::Server::RoxServer.set_custom_boolean_property('bool_prop2') do |_context|
|
12
12
|
TestVars.is_computed_boolean_prop_called = true
|
13
13
|
false
|
14
14
|
end
|
15
15
|
|
16
16
|
Rox::Server::RoxServer.set_custom_int_property('int_prop1', 6)
|
17
|
-
Rox::Server::RoxServer.set_custom_int_property('int_prop2') do |
|
17
|
+
Rox::Server::RoxServer.set_custom_int_property('int_prop2') do |_context|
|
18
18
|
TestVars.is_computed_int_prop_called = true
|
19
19
|
28
|
20
20
|
end
|
21
21
|
|
22
22
|
Rox::Server::RoxServer.set_custom_float_property('float_prop1', 3.14)
|
23
|
-
Rox::Server::RoxServer.set_custom_float_property('float_prop2') do |
|
23
|
+
Rox::Server::RoxServer.set_custom_float_property('float_prop2') do |_context|
|
24
24
|
TestVars.is_computed_float_prop_called = true
|
25
25
|
1.618
|
26
26
|
end
|
27
27
|
|
28
28
|
Rox::Server::RoxServer.set_custom_semver_property('smvr_prop1', '9.11.2001')
|
29
|
-
Rox::Server::RoxServer.set_custom_semver_property('smvr_prop2') do |
|
29
|
+
Rox::Server::RoxServer.set_custom_semver_property('smvr_prop2') do |_context|
|
30
30
|
TestVars.is_computed_semver_prop_called = true
|
31
31
|
'20.7.1969'
|
32
32
|
end
|
@@ -35,15 +35,15 @@ module E2E
|
|
35
35
|
context['isDuckAndCover']
|
36
36
|
end
|
37
37
|
|
38
|
-
Rox::Server::RoxServer.set_custom_boolean_property('bool_prop_target_group_operand1') do |
|
38
|
+
Rox::Server::RoxServer.set_custom_boolean_property('bool_prop_target_group_operand1') do |_context|
|
39
39
|
TestVars.target_group1
|
40
40
|
end
|
41
41
|
|
42
|
-
Rox::Server::RoxServer.set_custom_boolean_property('bool_prop_target_group_operand2') do |
|
42
|
+
Rox::Server::RoxServer.set_custom_boolean_property('bool_prop_target_group_operand2') do |_context|
|
43
43
|
TestVars.target_group2
|
44
44
|
end
|
45
45
|
|
46
|
-
Rox::Server::RoxServer.set_custom_boolean_property('bool_prop_target_group_for_dependency') do |
|
46
|
+
Rox::Server::RoxServer.set_custom_boolean_property('bool_prop_target_group_for_dependency') do |_context|
|
47
47
|
TestVars.is_prop_for_target_group_for_dependency
|
48
48
|
end
|
49
49
|
|
@@ -52,4 +52,4 @@ module E2E
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
55
|
-
end
|
55
|
+
end
|
data/e2e/rox_e2e_test.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'minitest/autorun'
|
2
2
|
require 'rox/server/rox_options'
|
3
3
|
require 'rox/server/rox_server'
|
4
4
|
require_relative 'container'
|
@@ -7,7 +7,7 @@ require_relative 'test_vars'
|
|
7
7
|
|
8
8
|
module E2E
|
9
9
|
class Logger
|
10
|
-
def debug(message,
|
10
|
+
def debug(message, _ex = nil)
|
11
11
|
puts 'Before Rox.Setup', message
|
12
12
|
end
|
13
13
|
|
@@ -15,7 +15,7 @@ module E2E
|
|
15
15
|
puts 'Before Rox.Setup', message, ex
|
16
16
|
end
|
17
17
|
|
18
|
-
def warn(message,
|
18
|
+
def warn(message, _ex = nil)
|
19
19
|
puts 'Before Rox.Setup', message
|
20
20
|
end
|
21
21
|
end
|
@@ -30,8 +30,8 @@ module E2E
|
|
30
30
|
end
|
31
31
|
|
32
32
|
impression_handler = proc do |e|
|
33
|
-
if !e.nil? && !e.reporting_value.nil?
|
34
|
-
TestVars.is_impression_raised = true
|
33
|
+
if !e.nil? && !e.reporting_value.nil? && (e.reporting_value.name == 'flag_for_impression')
|
34
|
+
TestVars.is_impression_raised = true
|
35
35
|
end
|
36
36
|
TestVars.impression_returned_args = e
|
37
37
|
end
|
@@ -44,7 +44,7 @@ module E2E
|
|
44
44
|
)
|
45
45
|
|
46
46
|
@@container = Container.new
|
47
|
-
Rox::Server::RoxServer.register(
|
47
|
+
Rox::Server::RoxServer.register(@@container)
|
48
48
|
CustomProps.create_custom_props
|
49
49
|
Rox::Server::RoxServer.setup('5b82864ebc3aec37aff1fdd5', option).join
|
50
50
|
|
@@ -56,7 +56,7 @@ module E2E
|
|
56
56
|
assert_equal false, @@container.simple_flag_overwritten.enabled?
|
57
57
|
end
|
58
58
|
|
59
|
-
def
|
59
|
+
def test_string
|
60
60
|
assert_equal 'red', @@container.variant.value
|
61
61
|
end
|
62
62
|
|
@@ -87,9 +87,9 @@ module E2E
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
-
def
|
91
|
-
some_positive_context = {'isDuckAndCover' => true}
|
92
|
-
some_negative_context = {'isDuckAndCover' => false}
|
90
|
+
def test_string_with_context
|
91
|
+
some_positive_context = { 'isDuckAndCover' => true }
|
92
|
+
some_negative_context = { 'isDuckAndCover' => false }
|
93
93
|
|
94
94
|
assert_equal 'red', @@container.variant_with_context.value
|
95
95
|
|
@@ -121,18 +121,16 @@ module E2E
|
|
121
121
|
assert_equal true, TestVars.is_impression_raised
|
122
122
|
TestVars.is_impression_raised = false
|
123
123
|
|
124
|
-
context = {'var' => 'val'}
|
124
|
+
context = { 'var' => 'val' }
|
125
125
|
flag_impression_value = @@container.flag_for_impression_with_experiment_and_context.enabled?(context)
|
126
126
|
refute_nil TestVars.impression_returned_args
|
127
127
|
refute_nil TestVars.impression_returned_args.reporting_value
|
128
|
-
assert_equal
|
128
|
+
assert_equal true, TestVars.impression_returned_args.reporting_value.value
|
129
129
|
assert_equal true, flag_impression_value
|
130
|
-
assert_equal 'flag_for_impression_with_experiment_and_context',
|
130
|
+
assert_equal 'flag_for_impression_with_experiment_and_context',
|
131
|
+
TestVars.impression_returned_args.reporting_value.name
|
131
132
|
|
132
133
|
refute_nil TestVars.impression_returned_args
|
133
|
-
refute_nil TestVars.impression_returned_args.experiment
|
134
|
-
assert_equal '5b8f85ecbc3aec37aff20841', TestVars.impression_returned_args.experiment.identifier
|
135
|
-
assert_equal 'flag for impression with experiment and context', TestVars.impression_returned_args.experiment.name
|
136
134
|
|
137
135
|
assert_equal 'val', TestVars.impression_returned_args.context['var']
|
138
136
|
end
|
@@ -147,13 +145,13 @@ module E2E
|
|
147
145
|
assert_equal false, @@container.flag_for_dependency.enabled?
|
148
146
|
end
|
149
147
|
|
150
|
-
def
|
151
|
-
some_positive_context = {'isDuckAndCover' => true}
|
152
|
-
some_negative_context = {'isDuckAndCover' => false}
|
148
|
+
def test_string_dependency_with_context
|
149
|
+
some_positive_context = { 'isDuckAndCover' => true }
|
150
|
+
some_negative_context = { 'isDuckAndCover' => false }
|
153
151
|
|
154
152
|
assert_equal 'White', @@container.flag_color_dependent_with_context.value
|
155
153
|
assert_equal 'White', @@container.flag_color_dependent_with_context.value(some_negative_context)
|
156
154
|
assert_equal 'Yellow', @@container.flag_color_dependent_with_context.value(some_positive_context)
|
157
155
|
end
|
158
156
|
end
|
159
|
-
end
|
157
|
+
end
|
data/e2e/test_vars.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
module E2E
|
2
2
|
module TestVars
|
3
3
|
class << self
|
4
|
-
attr_accessor :is_computed_boolean_prop_called, :is_computed_string_prop_called, :is_computed_int_prop_called,
|
5
|
-
|
6
|
-
attr_accessor :is_impression_raised, :is_prop_for_target_group_for_dependency
|
7
|
-
|
8
|
-
attr_accessor :configuration_fetched_count, :impression_returned_args
|
4
|
+
attr_accessor :is_computed_boolean_prop_called, :is_computed_string_prop_called, :is_computed_int_prop_called,
|
5
|
+
:is_computed_float_prop_called, :is_computed_semver_prop_called, :target_group1, :target_group2, :is_impression_raised, :is_prop_for_target_group_for_dependency, :configuration_fetched_count, :impression_returned_args
|
9
6
|
end
|
10
7
|
|
11
8
|
@is_computed_boolean_prop_called = false
|
@@ -21,4 +18,4 @@ module E2E
|
|
21
18
|
@configuration_fetched_count = 0
|
22
19
|
@impression_returned_args = nil
|
23
20
|
end
|
24
|
-
end
|
21
|
+
end
|
data/example/local.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
|
2
|
+
|
3
|
+
require 'rox/server/rox_server'
|
4
|
+
require 'rox/server/rox_options'
|
5
|
+
|
6
|
+
API_HOST = 'http://localhost:8557'.freeze
|
7
|
+
APP_KEY = '600571e330819d4842999e4f'.freeze
|
8
|
+
DEV_MODE_SECRET = 'e56cda16749d8d0a9b91d34c'.freeze
|
9
|
+
|
10
|
+
class Flags
|
11
|
+
attr_accessor :boolean_flag, :string_flag, :int_flag, :double_flag
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
# Define the feature flags
|
15
|
+
@boolean_flag = Rox::Server::RoxFlag.new(true)
|
16
|
+
@string_flag = Rox::Server::RoxString.new('option 1', ['option 1', 'option 2', 'option 3'])
|
17
|
+
@int_flag = Rox::Server::RoxInt.new(1, [1, 2, 3])
|
18
|
+
@double_flag = Rox::Server::RoxDouble.new(4.0, [5.0, 6.0])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
flags = Flags.new
|
23
|
+
Rox::Server::RoxServer.register(flags)
|
24
|
+
|
25
|
+
options = Rox::Server::RoxOptions.new(
|
26
|
+
self_managed_options: Rox::Server::SelfManagedOptions.new(
|
27
|
+
server_url: API_HOST,
|
28
|
+
analytics_url: 'http://127.0.0.1:8787'
|
29
|
+
),
|
30
|
+
dev_mode_key: DEV_MODE_SECRET
|
31
|
+
)
|
32
|
+
|
33
|
+
Rox::Server::RoxServer.setup(APP_KEY, options)
|
34
|
+
|
35
|
+
puts "boolean_flag is #{flags.boolean_flag.enabled?}"
|
36
|
+
puts "boolean_flag is #{Rox::Server::RoxServer.dynamic_api.enabled?('boolean_flag', true)} (dynamic api)"
|
37
|
+
puts "boolean_flag is #{Rox::Server::RoxServer.dynamic_api.enabled?('boolean_flag', true)} (dynamic api)"
|
38
|
+
puts "string_flag is #{flags.string_flag.value}"
|
39
|
+
puts "int_flag is #{flags.int_flag.value}"
|
40
|
+
puts "double_flag is #{flags.double_flag.value}"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'segment/analytics'
|
2
|
+
|
3
|
+
module Rox
|
4
|
+
module Core
|
5
|
+
# Analytics based on segment client
|
6
|
+
# https://segment.com/docs/connections/sources/catalog/libraries/server/ruby/
|
7
|
+
class Analytics
|
8
|
+
attr_reader :client
|
9
|
+
|
10
|
+
def initialize(key)
|
11
|
+
@client = Segment::Analytics.new({
|
12
|
+
write_key: key,
|
13
|
+
on_error: proc { |_status, msg| print msg }
|
14
|
+
})
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/rox/core/client/buid.rb
CHANGED
@@ -6,20 +6,15 @@ module Rox
|
|
6
6
|
module Core
|
7
7
|
class BUID
|
8
8
|
BUID_GENERATORS = [
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
PropertyType::CUSTOM_PROPERTIES,
|
14
|
-
PropertyType::FEATURE_FLAGS,
|
15
|
-
PropertyType::REMOTE_VARIABLES
|
9
|
+
PropertyType::PLATFORM,
|
10
|
+
PropertyType::APP_KEY,
|
11
|
+
PropertyType::LIB_VERSION,
|
12
|
+
PropertyType::API_VERSION
|
16
13
|
].freeze
|
17
14
|
|
18
|
-
def initialize(sdk_settings, device_properties,
|
15
|
+
def initialize(sdk_settings, device_properties, _flag_repository, _custom_property_repository)
|
19
16
|
@sdk_settings = sdk_settings
|
20
17
|
@device_properties = device_properties
|
21
|
-
@flag_repository = flag_repository
|
22
|
-
@custom_property_repository = custom_property_repository
|
23
18
|
@buid = nil
|
24
19
|
end
|
25
20
|
|
@@ -30,53 +25,23 @@ module Rox
|
|
30
25
|
values << properties[pt.name] if properties.include?(pt.name)
|
31
26
|
end
|
32
27
|
|
33
|
-
values << serialize_feature_flags
|
34
|
-
values << serialize_custom_properties
|
35
|
-
|
36
28
|
hash = Digest::MD5.hexdigest(values.join('|'))
|
37
29
|
|
38
30
|
@buid = hash.upcase
|
39
31
|
end
|
40
32
|
|
41
33
|
def query_string_parts
|
42
|
-
generators = BUID::BUID_GENERATORS.map {|pt, _| pt.name}
|
34
|
+
generators = BUID::BUID_GENERATORS.map { |pt, _| pt.name }
|
43
35
|
|
44
36
|
{
|
45
|
-
|
46
|
-
|
47
|
-
PropertyType::FEATURE_FLAGS.name => serialize_feature_flags,
|
48
|
-
PropertyType::REMOTE_VARIABLES.name => '[]',
|
49
|
-
PropertyType::CUSTOM_PROPERTIES.name => serialize_custom_properties,
|
37
|
+
PropertyType::BUID.name => value,
|
38
|
+
PropertyType::BUID_GENERATORS_LIST.name => generators.join(',')
|
50
39
|
}
|
51
40
|
end
|
52
41
|
|
53
|
-
def serialize_feature_flags
|
54
|
-
flags = []
|
55
|
-
@flag_repository.all_flags.each do |f|
|
56
|
-
flags << {
|
57
|
-
name: f.name,
|
58
|
-
defaultValue: f.default_value,
|
59
|
-
options: f.options
|
60
|
-
}
|
61
|
-
end
|
62
|
-
JSON.dump(flags)
|
63
|
-
end
|
64
|
-
|
65
|
-
def serialize_custom_properties
|
66
|
-
properties = []
|
67
|
-
@custom_property_repository.all_custom_properties.each do |p|
|
68
|
-
properties << {
|
69
|
-
name: p.name,
|
70
|
-
type: p.type.type,
|
71
|
-
externalType: p.type.external_type
|
72
|
-
}
|
73
|
-
end
|
74
|
-
JSON.dump(properties)
|
75
|
-
end
|
76
|
-
|
77
42
|
def to_s
|
78
43
|
@buid
|
79
44
|
end
|
80
45
|
end
|
81
46
|
end
|
82
|
-
end
|
47
|
+
end
|
@@ -4,11 +4,17 @@ require 'rox/core/consts/build'
|
|
4
4
|
module Rox
|
5
5
|
module Core
|
6
6
|
class DeviceProperties
|
7
|
+
attr_reader :rox_options
|
8
|
+
|
7
9
|
def initialize(sdk_settings, rox_options)
|
8
10
|
@sdk_settings = sdk_settings
|
9
11
|
@rox_options = rox_options
|
10
12
|
end
|
11
13
|
|
14
|
+
def get(property)
|
15
|
+
all_properties[property.name]
|
16
|
+
end
|
17
|
+
|
12
18
|
def all_properties
|
13
19
|
{
|
14
20
|
PropertyType::PACKAGE_NAME.name => @rox_options.version,
|
@@ -20,7 +26,7 @@ module Rox
|
|
20
26
|
PropertyType::APP_RELEASE.name => @rox_options.version,
|
21
27
|
PropertyType::DISTINCT_ID.name => distinct_id,
|
22
28
|
PropertyType::APP_KEY.name => @sdk_settings.api_key,
|
23
|
-
PropertyType::PLATFORM.name => Build::PLATFORM
|
29
|
+
PropertyType::PLATFORM.name => Build::PLATFORM
|
24
30
|
}
|
25
31
|
end
|
26
32
|
|
@@ -42,4 +48,4 @@ module Rox
|
|
42
48
|
end
|
43
49
|
end
|
44
50
|
end
|
45
|
-
end
|
51
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rox/core/entities/flag'
|
2
|
+
require 'rox/server/flags/normalize_flag_type'
|
2
3
|
|
3
4
|
module Rox
|
4
5
|
module Core
|
@@ -9,28 +10,65 @@ module Rox
|
|
9
10
|
end
|
10
11
|
|
11
12
|
def enabled?(name, default_value, context = nil)
|
12
|
-
|
13
|
-
|
14
|
-
variant = @entities_provider.create_flag(default_value)
|
15
|
-
@flag_repository.add_flag(variant, name)
|
16
|
-
end
|
13
|
+
raise ArgumentError, 'flag name should be a string' unless name.is_a?(String)
|
14
|
+
raise ArgumentError, 'default value should be boolean' unless [true, false].include?(default_value)
|
17
15
|
|
18
|
-
|
16
|
+
string = @flag_repository.flag(name)
|
17
|
+
if string.nil?
|
18
|
+
string = @entities_provider.create_flag(default_value)
|
19
|
+
@flag_repository.add_flag(string, name)
|
20
|
+
end
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
+
merged_context = MergedContext.new(string.parser&.global_context, context)
|
23
|
+
return_value = unless string.is_a?(Flag)
|
24
|
+
default_value
|
25
|
+
else
|
26
|
+
is_enabled = string.internal_enabled?(context, nil_instead_of_default: true)
|
27
|
+
is_enabled.nil? ? default_value : is_enabled
|
28
|
+
end
|
29
|
+
string.send_impressions(return_value, merged_context)
|
30
|
+
return_value
|
22
31
|
end
|
23
32
|
|
24
33
|
def value(name, default_value, context = nil, options = [])
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
34
|
+
generic_value(name, default_value, context, options)
|
35
|
+
end
|
36
|
+
|
37
|
+
def int_value(name, default_value, context = nil, options = [])
|
38
|
+
create_method = @entities_provider.method(:create_int)
|
39
|
+
normalize_method = Rox::Server::NormalizeFlagType.method(:normalize_int)
|
40
|
+
generic_value(name, default_value, context, options, Integer, create_method, normalize_method)
|
41
|
+
end
|
42
|
+
|
43
|
+
def double_value(name, default_value, context = nil, options = [])
|
44
|
+
create_method = @entities_provider.method(:create_double)
|
45
|
+
normalize_method = Rox::Server::NormalizeFlagType.method(:normalize_float)
|
46
|
+
generic_value(name, default_value, context, options, Float, create_method, normalize_method)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def generic_value(name, default_value, context, options, flag_type = String, create_method = nil, normalize_method = Rox::Server::NormalizeFlagType.method(:normalize_string))
|
52
|
+
unless name.is_a?(String)
|
53
|
+
raise ArgumentError, 'DynamicApi error - name must be string'
|
54
|
+
end
|
55
|
+
|
56
|
+
unless default_value.is_a?(flag_type)
|
57
|
+
raise ArgumentError, "DynamicApi default value must be of #{flag_type} type. Received #{default_value}"
|
58
|
+
end
|
59
|
+
|
60
|
+
string = @flag_repository.flag(name)
|
61
|
+
if string.nil?
|
62
|
+
string = create_method.nil? ? @entities_provider.create_string(default_value, options) : create_method.call(default_value, options)
|
63
|
+
@flag_repository.add_flag(string, name)
|
29
64
|
end
|
30
65
|
|
31
|
-
|
32
|
-
value
|
66
|
+
merged_context = MergedContext.new(string.parser&.global_context, context)
|
67
|
+
value = string.internal_value(context, nil_instead_of_default: true)
|
68
|
+
return_value = value.nil? ? normalize_method.call(default_value) : normalize_method.call(value)
|
69
|
+
string.send_impressions(return_value, merged_context)
|
70
|
+
return_value
|
33
71
|
end
|
34
72
|
end
|
35
73
|
end
|
36
|
-
end
|
74
|
+
end
|