rox-rollout 4.7.1 → 5.0.2

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.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +34 -13
  3. data/.editorconfig +12 -0
  4. data/.github/workflows/ruby.yml +20 -0
  5. data/.rubocop.yml +17 -0
  6. data/Gemfile +2 -2
  7. data/README.md +32 -0
  8. data/Rakefile +12 -9
  9. data/bin/console +3 -4
  10. data/e2e/container.rb +11 -14
  11. data/e2e/custom_props.rb +9 -9
  12. data/e2e/rox_e2e_test.rb +17 -19
  13. data/e2e/test_vars.rb +3 -6
  14. data/e2e-server/run_server.sh +12 -0
  15. data/e2e-server/server.rb +158 -0
  16. data/example/local.rb +40 -0
  17. data/lib/rox/core/analytics.rb +18 -0
  18. data/lib/rox/core/client/buid.rb +8 -8
  19. data/lib/rox/core/client/device_properties.rb +7 -1
  20. data/lib/rox/core/client/dynamic_api.rb +53 -15
  21. data/lib/rox/core/client/internal_flags.rb +14 -2
  22. data/lib/rox/core/client/sdk_settings.rb +1 -1
  23. data/lib/rox/core/configuration/configuration.rb +1 -1
  24. data/lib/rox/core/configuration/configuration_fetched_args.rb +2 -2
  25. data/lib/rox/core/configuration/configuration_fetched_invoker.rb +8 -3
  26. data/lib/rox/core/configuration/configuration_parser.rb +38 -37
  27. data/lib/rox/core/configuration/fetcher_error.rb +1 -1
  28. data/lib/rox/core/configuration/fetcher_status.rb +1 -1
  29. data/lib/rox/core/configuration/models/experiment_model.rb +1 -1
  30. data/lib/rox/core/configuration/models/target_group_model.rb +1 -1
  31. data/lib/rox/core/consts/build.rb +2 -2
  32. data/lib/rox/core/consts/environment.rb +10 -8
  33. data/lib/rox/core/consts/property_type.rb +16 -17
  34. data/lib/rox/core/context/merged_context.rb +2 -1
  35. data/lib/rox/core/core.rb +89 -38
  36. data/lib/rox/core/entities/default_flag_values.rb +10 -0
  37. data/lib/rox/core/entities/flag.rb +22 -7
  38. data/lib/rox/core/entities/flag_setter.rb +6 -6
  39. data/lib/rox/core/entities/rox_double.rb +11 -0
  40. data/lib/rox/core/entities/rox_int.rb +11 -0
  41. data/lib/rox/core/entities/{variant.rb → rox_string.rb} +20 -13
  42. data/lib/rox/core/error_handling/exception_trigger.rb +10 -0
  43. data/lib/rox/core/error_handling/userspace_handler_exception.rb +12 -0
  44. data/lib/rox/core/error_handling/userspace_unhandled_error_invoker.rb +41 -0
  45. data/lib/rox/core/impression/impression_args.rb +2 -2
  46. data/lib/rox/core/impression/impression_invoker.rb +41 -7
  47. data/lib/rox/core/impression/models/experiment.rb +1 -1
  48. data/lib/rox/core/impression/models/reporting_value.rb +10 -2
  49. data/lib/rox/core/logging/logging.rb +3 -3
  50. data/lib/rox/core/logging/no_op_logger.rb +1 -1
  51. data/lib/rox/core/network/configuration_fetcher.rb +2 -2
  52. data/lib/rox/core/network/configuration_fetcher_roxy.rb +2 -2
  53. data/lib/rox/core/network/configuration_fetcher_self_managed.rb +30 -0
  54. data/lib/rox/core/network/configuration_source.rb +1 -1
  55. data/lib/rox/core/network/request.rb +1 -1
  56. data/lib/rox/core/network/request_configuration_builder.rb +5 -5
  57. data/lib/rox/core/network/request_data.rb +1 -1
  58. data/lib/rox/core/network/response.rb +6 -8
  59. data/lib/rox/core/network/state_sender.rb +63 -19
  60. data/lib/rox/core/notifications/notification_listener.rb +4 -4
  61. data/lib/rox/core/properties/custom_property.rb +1 -1
  62. data/lib/rox/core/properties/custom_property_type.rb +1 -1
  63. data/lib/rox/core/properties/device_property.rb +2 -2
  64. data/lib/rox/core/properties/property_factory.rb +132 -0
  65. data/lib/rox/core/register/registerer.rb +13 -12
  66. data/lib/rox/core/reporting/error_reporter.rb +14 -13
  67. data/lib/rox/core/repositories/experiment_repository.rb +2 -4
  68. data/lib/rox/core/repositories/flag_repository.rb +7 -7
  69. data/lib/rox/core/repositories/roxx/experiments_extensions.rb +8 -8
  70. data/lib/rox/core/repositories/roxx/properties_extensions.rb +32 -7
  71. data/lib/rox/core/repositories/target_group_repository.rb +2 -4
  72. data/lib/rox/core/roxx/evaluation_result.rb +2 -0
  73. data/lib/rox/core/roxx/node.rb +1 -1
  74. data/lib/rox/core/roxx/parser.rb +35 -21
  75. data/lib/rox/core/roxx/regular_expression_extensions.rb +6 -3
  76. data/lib/rox/core/roxx/string_tokenizer.rb +3 -1
  77. data/lib/rox/core/roxx/symbols.rb +1 -1
  78. data/lib/rox/core/roxx/token_type.rb +1 -1
  79. data/lib/rox/core/roxx/tokenized_expression.rb +16 -12
  80. data/lib/rox/core/roxx/value_compare_extensions.rb +49 -29
  81. data/lib/rox/core/security/signature_verifier.rb +3 -3
  82. data/lib/rox/core/security/signature_verifier_mock.rb +12 -0
  83. data/lib/rox/core/utils/type_utils.rb +1 -1
  84. data/lib/rox/server/client/server_properties.rb +1 -1
  85. data/lib/rox/server/flags/normalize_flag_type.rb +25 -0
  86. data/lib/rox/server/flags/rox_double.rb +8 -0
  87. data/lib/rox/server/flags/rox_flag.rb +1 -1
  88. data/lib/rox/server/flags/rox_int.rb +8 -0
  89. data/lib/rox/server/flags/rox_string.rb +8 -0
  90. data/lib/rox/server/flags/server_entities_provider.rb +14 -4
  91. data/lib/rox/server/logging/server_logger.rb +2 -2
  92. data/lib/rox/server/rox_options.rb +39 -8
  93. data/lib/rox/server/rox_server.rb +84 -59
  94. data/lib/rox/version.rb +1 -1
  95. data/rox.gemspec +11 -9
  96. metadata +62 -33
  97. data/CODEOWNERS +0 -1
  98. data/README_DEVELOP.md +0 -25
  99. data/_archive/.document +0 -5
  100. data/_archive/.rspec +0 -1
  101. data/_archive/Gemfile +0 -15
  102. data/_archive/Gemfile.lock +0 -87
  103. data/_archive/README.md +0 -32
  104. data/_archive/README.rdoc +0 -19
  105. data/_archive/Rakefile +0 -50
  106. data/_archive/lib/expr_function_definition.rb +0 -52
  107. data/_archive/lib/function_definition.rb +0 -48
  108. data/_archive/lib/function_token.rb +0 -12
  109. data/_archive/lib/object_extends.rb +0 -12
  110. data/_archive/lib/ruby_interpreter.rb +0 -292
  111. data/_archive/lib/stack.rb +0 -48
  112. data/_archive/lib/string_extends.rb +0 -14
  113. data/_archive/spec/ruby_interpreter_spec.rb +0 -203
  114. data/_archive/spec/spec_helper.rb +0 -30
  115. data/_archive/spec/stack_spec.rb +0 -77
  116. data/lib/rox/server/flags/rox_variant.rb +0 -8
@@ -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
@@ -6,13 +6,13 @@ module Rox
6
6
  module Core
7
7
  class BUID
8
8
  BUID_GENERATORS = [
9
- PropertyType::PLATFORM,
10
- PropertyType::APP_KEY,
11
- PropertyType::LIB_VERSION,
12
- PropertyType::API_VERSION
9
+ PropertyType::PLATFORM,
10
+ PropertyType::APP_KEY,
11
+ PropertyType::LIB_VERSION,
12
+ PropertyType::API_VERSION
13
13
  ].freeze
14
14
 
15
- def initialize(sdk_settings, device_properties, flag_repository, custom_property_repository)
15
+ def initialize(sdk_settings, device_properties, _flag_repository, _custom_property_repository)
16
16
  @sdk_settings = sdk_settings
17
17
  @device_properties = device_properties
18
18
  @buid = nil
@@ -31,11 +31,11 @@ module Rox
31
31
  end
32
32
 
33
33
  def query_string_parts
34
- generators = BUID::BUID_GENERATORS.map {|pt, _| pt.name}
34
+ generators = BUID::BUID_GENERATORS.map { |pt, _| pt.name }
35
35
 
36
36
  {
37
- PropertyType::BUID.name => value,
38
- PropertyType::BUID_GENERATORS_LIST.name => generators.join(','),
37
+ PropertyType::BUID.name => value,
38
+ PropertyType::BUID_GENERATORS_LIST.name => generators.join(',')
39
39
  }
40
40
  end
41
41
 
@@ -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
 
@@ -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
- variant = @flag_repository.flag(name)
13
- if variant.nil?
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
- return default_value unless variant.is_a?(Flag)
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
- is_enabled = variant.internal_enabled?(context, nil_instead_of_default: true)
21
- is_enabled.nil? ? default_value : is_enabled
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
- variant = @flag_repository.flag(name)
26
- if variant.nil?
27
- variant = @entities_provider.create_variant(default_value, options)
28
- @flag_repository.add_flag(variant, name)
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
- value = variant.internal_value(context, nil_instead_of_default: true)
32
- value.nil? ? default_value : 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
@@ -3,12 +3,24 @@ require 'rox/core/entities/flag'
3
3
  module Rox
4
4
  module Core
5
5
  class InternalFlags
6
- def initialize(experiment_repository, parser)
6
+ @@defaults_self_managed = {
7
+ 'rox.internal.pushUpdates' => false,
8
+ 'rox.internal.considerThrottleInPush' => false,
9
+ 'rox.internal.throttleFetchInSeconds' => 0
10
+ }
11
+
12
+ def initialize(experiment_repository, parser, rox_options)
7
13
  @experiment_repository = experiment_repository
8
14
  @parser = parser
15
+ @rox_options = rox_options
9
16
  end
10
17
 
11
18
  def enabled?(flag_name)
19
+ if @rox_options.self_managed?
20
+ value = @@defaults_self_managed[flag_name]
21
+ return value unless value.nil?
22
+ end
23
+
12
24
  internal_experiment = @experiment_repository.experiment_by_flag(flag_name)
13
25
  return false if internal_experiment.nil?
14
26
 
@@ -17,4 +29,4 @@ module Rox
17
29
  end
18
30
  end
19
31
  end
20
- end
32
+ end
@@ -2,4 +2,4 @@ module Rox
2
2
  module Core
3
3
  SdkSettings = Struct.new(:api_key, :dev_mode_secret)
4
4
  end
5
- end
5
+ end
@@ -2,4 +2,4 @@ module Rox
2
2
  module Core
3
3
  Configuration = Struct.new(:experiments, :target_groups, :signature_date)
4
4
  end
5
- end
5
+ end
@@ -14,10 +14,10 @@ module Rox
14
14
  end
15
15
 
16
16
  def self.error(error_details)
17
- args = ConfigurationFetchedArgs.new(FetcherStatus::ERROR_FETCHED_FAILED, nil, false )
17
+ args = ConfigurationFetchedArgs.new(FetcherStatus::ERROR_FETCHED_FAILED, nil, false)
18
18
  args.error_details = error_details
19
19
  args
20
20
  end
21
21
  end
22
22
  end
23
- end
23
+ end
@@ -3,9 +3,10 @@ require 'rox/core/configuration/configuration_fetched_args'
3
3
  module Rox
4
4
  module Core
5
5
  class ConfigurationFetchedInvoker
6
- def initialize
6
+ def initialize(user_unhandled_error_invoker)
7
7
  @fetched_handlers = []
8
8
  @mutex = Mutex.new
9
+ @user_unhandled_error_invoker = user_unhandled_error_invoker
9
10
  end
10
11
 
11
12
  def invoke(fetcher_status, creation_date, has_changes)
@@ -29,9 +30,13 @@ module Rox
29
30
  end
30
31
 
31
32
  handlers.each do |handler|
32
- handler.call(args)
33
+ begin
34
+ handler.call(args)
35
+ rescue StandardError => e
36
+ user_unhandled_error_invoker.invoke(handler, Rox::Core::CONFIGURATION_FETCHED_HANDLER, e)
37
+ end
33
38
  end
34
39
  end
35
40
  end
36
41
  end
37
- end
42
+ end
@@ -17,50 +17,51 @@ module Rox
17
17
  end
18
18
 
19
19
  def parse(fetch_result, sdk_settings)
20
- begin
21
- if fetch_result.nil? || fetch_result.data.nil? || fetch_result.data.empty?
22
- @configuration_fetched_invoker.invoke_error(FetcherError::EMPTY_JSON)
23
- @error_reporter.report('Failed to parse JSON configuration - Null Or Empty', ArgumentError.new('data'))
24
- return nil
25
- end
26
-
27
- begin
28
- json_obj = JSON.parse(fetch_result.data)
29
- rescue StandardError => ex
30
- @configuration_fetched_invoker.invoke_error(FetcherError::CORRUPTED_JSON)
31
- @error_reporter.report('Failed to parse JSON configuration', ex)
32
- return nil
33
- end
34
-
35
- if fetch_result.source != ConfigurationSource::ROXY && !@signature_verifier.verify(json_obj['data'], json_obj['signature_v0'])
36
- @configuration_fetched_invoker.invoke_error(FetcherError::SIGNATURE_VERIFICATION_ERROR)
37
- @error_reporter.report('Failed to validate signature', StandardError.new("Data : #{json_obj['data']} Signature : #{json_obj['signature_v0']}"))
38
- return nil
39
- end
20
+ if fetch_result.nil? || fetch_result.data.nil? || fetch_result.data.empty?
21
+ @configuration_fetched_invoker.invoke_error(FetcherError::EMPTY_JSON)
22
+ @error_reporter.report('Failed to parse JSON configuration - Null Or Empty', ArgumentError.new('data'))
23
+ return nil
24
+ end
40
25
 
41
- signature_date = DateTime.rfc3339(json_obj['signed_date']).to_time
42
- internal_data_string = json_obj['data']
43
- internal_data_object = JSON.parse(internal_data_string)
26
+ begin
27
+ json_obj = JSON.parse(fetch_result.data)
28
+ rescue StandardError => e
29
+ @configuration_fetched_invoker.invoke_error(FetcherError::CORRUPTED_JSON)
30
+ @error_reporter.report('Failed to parse JSON configuration', e)
31
+ return nil
32
+ end
44
33
 
45
- if fetch_result.source != ConfigurationSource::ROXY && internal_data_object['application'] != sdk_settings.api_key
46
- @configuration_fetched_invoker.invoke_error(FetcherError::MISMATCH_APP_KEY)
47
- @error_reporter.report('Failed to parse JSON configuration - ', StandardError.new("Internal Data: #{internal_data_object['application']} SdkSettings: #{sdk_settings.api_key}"))
48
- return nil
49
- end
34
+ if fetch_result.source != ConfigurationSource::ROXY && !@signature_verifier.verify(json_obj['data'],
35
+ json_obj['signature_v0'])
36
+ @configuration_fetched_invoker.invoke_error(FetcherError::SIGNATURE_VERIFICATION_ERROR)
37
+ @error_reporter.report('Failed to validate signature',
38
+ StandardError.new("Data : #{json_obj['data']} Signature : #{json_obj['signature_v0']}"))
39
+ return nil
40
+ end
50
41
 
51
- experiments = parse_experiments(internal_data_object)
52
- target_groups = parse_target_groups(internal_data_object)
42
+ signature_date = DateTime.rfc3339(json_obj['signed_date']).to_time
43
+ internal_data_string = json_obj['data']
44
+ internal_data_object = JSON.parse(internal_data_string)
53
45
 
54
- Configuration.new(experiments, target_groups, signature_date)
55
- rescue StandardError => ex
56
- Logging.logger.error('Failed to parse configurations', ex)
57
- @configuration_fetched_invoker.invoke_error(FetcherError::UNKNOWN)
46
+ if fetch_result.source != ConfigurationSource::ROXY && internal_data_object['application'] != sdk_settings.api_key
47
+ @configuration_fetched_invoker.invoke_error(FetcherError::MISMATCH_APP_KEY)
48
+ @error_reporter.report('Failed to parse JSON configuration - ',
49
+ StandardError.new("Internal Data: #{internal_data_object['application']} SdkSettings: #{sdk_settings.api_key}"))
58
50
  return nil
59
51
  end
52
+
53
+ experiments = parse_experiments(internal_data_object)
54
+ target_groups = parse_target_groups(internal_data_object)
55
+
56
+ Configuration.new(experiments, target_groups, signature_date)
57
+ rescue StandardError => e
58
+ Logging.logger.error('Failed to parse configurations', e)
59
+ @configuration_fetched_invoker.invoke_error(FetcherError::UNKNOWN)
60
+ nil
60
61
  end
61
62
 
62
63
  def parse_experiments(data)
63
- data['experiments'].map { |e| parse_experiment(e)}
64
+ data['experiments'].map { |e| parse_experiment(e) }
64
65
  end
65
66
 
66
67
  def parse_experiment(data)
@@ -69,12 +70,12 @@ module Rox
69
70
  name = data['name']
70
71
  id = data['_id']
71
72
  labels = data['labels'] || []
72
- flags = data['featureFlags'].map {|f| f['name']}
73
+ flags = data['featureFlags'].map { |f| f['name'] }
73
74
  ExperimentModel.new(id, name, condition, is_archived, flags, labels)
74
75
  end
75
76
 
76
77
  def parse_target_groups(data)
77
- data['targetGroups'].map { |g| parse_target_group(g)}
78
+ data['targetGroups'].map { |g| parse_target_group(g) }
78
79
  end
79
80
 
80
81
  def parse_target_group(data)
@@ -10,4 +10,4 @@ module Rox
10
10
  NO_ERROR = 'NoError'.freeze
11
11
  end
12
12
  end
13
- end
13
+ end
@@ -7,4 +7,4 @@ module Rox
7
7
  ERROR_FETCHED_FAILED = 'ErrorFetchedFailed'.freeze
8
8
  end
9
9
  end
10
- end
10
+ end
@@ -2,4 +2,4 @@ module Rox
2
2
  module Core
3
3
  ExperimentModel = Struct.new(:id, :name, :condition, :is_archived, :flags, :labels)
4
4
  end
5
- end
5
+ end
@@ -2,4 +2,4 @@ module Rox
2
2
  module Core
3
3
  TargetGroupModel = Struct.new(:id, :condition)
4
4
  end
5
- end
5
+ end
@@ -1,8 +1,8 @@
1
1
  module Rox
2
2
  module Core
3
3
  module Build
4
- PLATFORM = 'Ruby'
5
- API_VERSION = '1.8.0'
4
+ PLATFORM = 'Ruby'.freeze
5
+ API_VERSION = '1.9.0'.freeze
6
6
  end
7
7
  end
8
8
  end
@@ -16,14 +16,15 @@ module Rox
16
16
  end
17
17
  end
18
18
 
19
- def self.api_path
19
+ def self.api_path(api_url = nil)
20
20
  case ENV['ROLLOUT_MODE']
21
21
  when 'QA'
22
- 'https://qax.rollout.io/device/get_configuration'
22
+ 'https://qa-api.rollout.io/device/get_configuration'
23
23
  when 'LOCAL'
24
24
  'http://127.0.0.1:8557/device/get_configuration'
25
25
  else
26
- 'https://x-api.rollout.io/device/get_configuration'
26
+ api_url ||= 'https://x-api.rollout.io'
27
+ "#{api_url}/device/get_configuration"
27
28
  end
28
29
  end
29
30
 
@@ -38,25 +39,26 @@ module Rox
38
39
  end
39
40
  end
40
41
 
41
- def self.state_api_path
42
+ def self.state_api_path(api_url = nil)
42
43
  case ENV['ROLLOUT_MODE']
43
44
  when 'QA'
44
- 'https://qax.rollout.io/device/update_state_store'
45
+ 'https://qa-api.rollout.io/device/update_state_store'
45
46
  when 'LOCAL'
46
47
  'http://127.0.0.1:8557/device/update_state_store'
47
48
  else
48
- 'https://x-api.rollout.io/device/update_state_store'
49
+ api_url ||= 'https://x-api.rollout.io'
50
+ "#{api_url}/device/update_state_store"
49
51
  end
50
52
  end
51
53
 
52
- def self.analytics_path
54
+ def self.analytics_path(analytics_url = 'https://analytic.rollout.io')
53
55
  case ENV['ROLLOUT_MODE']
54
56
  when 'QA'
55
57
  'https://qaanalytic.rollout.io'
56
58
  when 'LOCAL'
57
59
  'http://127.0.0.1:8787'
58
60
  else
59
- 'https://analytic.rollout.io'
61
+ analytics_url
60
62
  end
61
63
  end
62
64
 
@@ -9,23 +9,22 @@ module Rox
9
9
  end
10
10
 
11
11
  CACHE_MISS_RELATIVE_URL = PropertyType.new(1, 'cache_miss_relative_url')
12
- PACKAGE_NAME = PropertyType.new(2, "package_name")
13
- VERSION_NAME = PropertyType.new(3, "version_name")
14
- LIB_VERSION = PropertyType.new(4, "lib_version")
15
- ROLLOUT_BUILD = PropertyType.new(5, "rollout_build")
16
- API_VERSION = PropertyType.new(6, "api_version")
17
- BUID = PropertyType.new(7, "buid")
18
- BUID_GENERATORS_LIST = PropertyType.new(8, "buid_generators_list")
19
- APP_VERSION = PropertyType.new(9, "app_version")
20
- APP_RELEASE = PropertyType.new(10, "app_release")
21
- DISTINCT_ID = PropertyType.new(11, "distinct_id")
22
- APP_KEY = PropertyType.new(12, "app_key")
23
- FEATURE_FLAGS = PropertyType.new(13, "feature_flags")
24
- REMOTE_VARIABLES = PropertyType.new(14, "remote_variables")
25
- CUSTOM_PROPERTIES = PropertyType.new(15, "custom_properties")
26
- PLATFORM = PropertyType.new(16, "platform")
27
- DEV_MODE_SECRET = PropertyType.new(17, "dev_mode_secret")
28
- STATE_MD5 = PropertyType.new(18, "state_md5")
12
+ PACKAGE_NAME = PropertyType.new(2, 'package_name')
13
+ VERSION_NAME = PropertyType.new(3, 'version_name')
14
+ LIB_VERSION = PropertyType.new(4, 'lib_version')
15
+ ROLLOUT_BUILD = PropertyType.new(5, 'rollout_build')
16
+ API_VERSION = PropertyType.new(6, 'api_version')
17
+ BUID = PropertyType.new(7, 'buid')
18
+ BUID_GENERATORS_LIST = PropertyType.new(8, 'buid_generators_list')
19
+ APP_VERSION = PropertyType.new(9, 'app_version')
20
+ APP_RELEASE = PropertyType.new(10, 'app_release')
21
+ DISTINCT_ID = PropertyType.new(11, 'distinct_id')
22
+ APP_KEY = PropertyType.new(12, 'app_key')
23
+ FEATURE_FLAGS = PropertyType.new(13, 'feature_flags')
24
+ CUSTOM_PROPERTIES = PropertyType.new(14, 'custom_properties')
25
+ PLATFORM = PropertyType.new(15, 'platform')
26
+ DEV_MODE_SECRET = PropertyType.new(16, 'dev_mode_secret')
27
+ STATE_MD5 = PropertyType.new(17, 'state_md5')
29
28
  end
30
29
  end
31
30
  end
@@ -9,8 +9,9 @@ module Rox
9
9
  def [](key)
10
10
  return @local_context[key] unless @local_context.nil? || @local_context[key].nil?
11
11
  return @global_context[key] unless @global_context.nil?
12
+
12
13
  nil
13
14
  end
14
15
  end
15
16
  end
16
- end
17
+ end