rox-rollout 4.7.3 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +34 -13
- data/.editorconfig +12 -0
- data/.github/workflows/ruby.yml +20 -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 +17 -19
- 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 +8 -8
- data/lib/rox/core/client/device_properties.rb +7 -1
- 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 +38 -37
- 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 +2 -2
- data/lib/rox/core/consts/environment.rb +10 -8
- data/lib/rox/core/consts/property_type.rb +16 -17
- data/lib/rox/core/context/merged_context.rb +2 -1
- data/lib/rox/core/core.rb +88 -38
- 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_fetcher.rb +2 -2
- data/lib/rox/core/network/configuration_fetcher_roxy.rb +2 -2
- 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 +1 -1
- data/lib/rox/core/network/request_configuration_builder.rb +5 -5
- data/lib/rox/core/network/request_data.rb +1 -1
- data/lib/rox/core/network/response.rb +6 -8
- data/lib/rox/core/network/state_sender.rb +61 -18
- 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/experiment_repository.rb +2 -4
- data/lib/rox/core/repositories/flag_repository.rb +7 -7
- 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 +35 -21
- 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/type_utils.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 +80 -59
- data/lib/rox/version.rb +1 -1
- data/rox.gemspec +11 -9
- metadata +66 -37
- data/CODEOWNERS +0 -1
- data/README_DEVELOP.md +0 -25
- data/_archive/.document +0 -5
- data/_archive/.rspec +0 -1
- data/_archive/Gemfile +0 -15
- 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
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'em-eventsource'
|
2
2
|
|
3
3
|
module Rox
|
4
4
|
module Core
|
@@ -15,7 +15,7 @@ module Rox
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def start
|
18
|
-
sse_url = @listen_url.chomp('/')
|
18
|
+
sse_url = "#{@listen_url.chomp('/')}/#{@app_key}"
|
19
19
|
@thread = Thread.new do
|
20
20
|
EM.run do
|
21
21
|
source = EventMachine::EventSource.new(sse_url)
|
@@ -37,9 +37,9 @@ module Rox
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def stop
|
40
|
-
@thread
|
40
|
+
@thread&.terminate
|
41
41
|
@thread = nil
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
45
|
-
end
|
45
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require 'rox/server/rox_options'
|
3
|
+
require 'rox/server/client/sdk_settings'
|
4
|
+
require 'rox/server/client/server_properties'
|
5
|
+
require 'rox/core/properties/device_property'
|
6
|
+
require 'rox/core/properties/custom_property'
|
7
|
+
require 'rox/core/properties/custom_property_type'
|
8
|
+
require 'rox/core/consts/property_type'
|
9
|
+
|
10
|
+
module Rox
|
11
|
+
module Core
|
12
|
+
# Consolidates creation of all the internal properties
|
13
|
+
class PropertyFactory
|
14
|
+
def initialize(server_properties)
|
15
|
+
@server_properties = server_properties
|
16
|
+
end
|
17
|
+
|
18
|
+
def platform
|
19
|
+
property = Rox::Core::PropertyType::PLATFORM
|
20
|
+
type = Rox::Core::CustomPropertyType::STRING
|
21
|
+
|
22
|
+
Rox::Core::DeviceProperty.new(
|
23
|
+
property.name,
|
24
|
+
type,
|
25
|
+
@server_properties.get(property)
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def app_release
|
30
|
+
property = Rox::Core::PropertyType::APP_RELEASE
|
31
|
+
type = Rox::Core::CustomPropertyType::SEMVER
|
32
|
+
|
33
|
+
Rox::Core::DeviceProperty.new(
|
34
|
+
property.name,
|
35
|
+
type,
|
36
|
+
@server_properties.get(property)
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
def distinct_id
|
41
|
+
property = Rox::Core::PropertyType::DISTINCT_ID
|
42
|
+
type = Rox::Core::CustomPropertyType::STRING
|
43
|
+
|
44
|
+
Rox::Core::DeviceProperty.new(
|
45
|
+
property.name,
|
46
|
+
type
|
47
|
+
) do |_|
|
48
|
+
SecureRandom.uuid
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def internal_real_platform
|
53
|
+
property = Rox::Core::PropertyType::PLATFORM
|
54
|
+
type = Rox::Core::CustomPropertyType::STRING
|
55
|
+
|
56
|
+
Rox::Core::DeviceProperty.new(
|
57
|
+
'internal.realPlatform',
|
58
|
+
type,
|
59
|
+
@server_properties.get(property)
|
60
|
+
)
|
61
|
+
end
|
62
|
+
|
63
|
+
def internal_custom_platform
|
64
|
+
property = Rox::Core::PropertyType::PLATFORM
|
65
|
+
type = Rox::Core::CustomPropertyType::STRING
|
66
|
+
|
67
|
+
Rox::Core::DeviceProperty.new(
|
68
|
+
'internal.customPlatform',
|
69
|
+
type,
|
70
|
+
@server_properties.get(property)
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
def internal_app_key
|
75
|
+
type = Rox::Core::CustomPropertyType::STRING
|
76
|
+
|
77
|
+
Rox::Core::DeviceProperty.new(
|
78
|
+
'internal.appKey',
|
79
|
+
type,
|
80
|
+
@server_properties.rollout_key
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
def internal_distinct_id
|
85
|
+
type = Rox::Core::CustomPropertyType::STRING
|
86
|
+
|
87
|
+
Rox::Core::DeviceProperty.new(
|
88
|
+
"internal.#{Rox::Core::PropertyType::DISTINCT_ID.name}",
|
89
|
+
type
|
90
|
+
) do
|
91
|
+
SecureRandom.uuid
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def internal_lib_version
|
96
|
+
type = Rox::Core::CustomPropertyType::SEMVER
|
97
|
+
|
98
|
+
Rox::Core::DeviceProperty.new(
|
99
|
+
'internal.lib_version',
|
100
|
+
type,
|
101
|
+
@server_properties.lib_version
|
102
|
+
)
|
103
|
+
end
|
104
|
+
|
105
|
+
def internal_api_version
|
106
|
+
property = Rox::Core::PropertyType::API_VERSION
|
107
|
+
type = Rox::Core::CustomPropertyType::SEMVER
|
108
|
+
|
109
|
+
Rox::Core::DeviceProperty.new(
|
110
|
+
'internal.api_version',
|
111
|
+
type,
|
112
|
+
property
|
113
|
+
)
|
114
|
+
end
|
115
|
+
|
116
|
+
# rubocop:disable Metrics/MethodLength
|
117
|
+
def all_properties
|
118
|
+
[
|
119
|
+
platform,
|
120
|
+
app_release,
|
121
|
+
distinct_id,
|
122
|
+
internal_real_platform,
|
123
|
+
internal_custom_platform,
|
124
|
+
internal_app_key,
|
125
|
+
internal_distinct_id,
|
126
|
+
internal_lib_version,
|
127
|
+
internal_api_version
|
128
|
+
]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -7,25 +7,26 @@ module Rox
|
|
7
7
|
@mutex = Mutex.new
|
8
8
|
end
|
9
9
|
|
10
|
-
def register_instance(container,
|
11
|
-
raise ArgumentError, 'A namespace cannot be null' if
|
10
|
+
def register_instance(container, namespace)
|
11
|
+
raise ArgumentError, 'A namespace cannot be null' if namespace.nil?
|
12
12
|
|
13
13
|
@mutex.synchronize do
|
14
|
-
|
14
|
+
if @namespaces.include?(namespace)
|
15
|
+
raise ArgumentError,
|
16
|
+
"A container with the given namespace (#{namespace}) has already been registered"
|
17
|
+
end
|
15
18
|
end
|
16
19
|
|
17
|
-
@namespaces <<
|
20
|
+
@namespaces << namespace
|
18
21
|
|
19
|
-
container.instance_variables
|
22
|
+
container.instance_variables.each do |attribute_name|
|
20
23
|
begin
|
21
24
|
value = container.instance_variable_get(attribute_name)
|
22
|
-
if value
|
23
|
-
var_name = attribute_name.to_s
|
24
|
-
|
25
|
-
if
|
26
|
-
|
27
|
-
end
|
28
|
-
@flag_repository.add_flag(value, ns == '' ? var_name : "#{ns}.#{var_name}")
|
25
|
+
if !value.nil? && value.is_a?(RoxString)
|
26
|
+
var_name = attribute_name.to_s
|
27
|
+
# removing the attribute starting @ (if [always] exists)
|
28
|
+
var_name[0] = '' if var_name[0] == '@'
|
29
|
+
@flag_repository.add_flag(value, namespace == '' ? var_name : "#{namespace}.#{var_name}")
|
29
30
|
end
|
30
31
|
rescue StandardError
|
31
32
|
next
|
@@ -13,6 +13,7 @@ module Rox
|
|
13
13
|
|
14
14
|
def report(message, ex)
|
15
15
|
return if @device_properties.rollout_environment == 'LOCAL'
|
16
|
+
return if @device_properties.rox_options.self_managed?
|
16
17
|
|
17
18
|
Logging.logger.error("Error report: #{message}", ex)
|
18
19
|
|
@@ -33,8 +34,8 @@ module Rox
|
|
33
34
|
begin
|
34
35
|
@request.send_post(ErrorReporter::BUGSNAG_NOTIFY_URL, payload)
|
35
36
|
Logging.logger.debug('Bugsnag error report was sent')
|
36
|
-
rescue StandardError =>
|
37
|
-
Logging.logger.error('Failed to send bugsnag error ',
|
37
|
+
rescue StandardError => e
|
38
|
+
Logging.logger.error('Failed to send bugsnag error ', e)
|
38
39
|
end
|
39
40
|
end
|
40
41
|
|
@@ -49,13 +50,13 @@ module Rox
|
|
49
50
|
|
50
51
|
def add_metadata(message, ev)
|
51
52
|
inner_data = {
|
52
|
-
|
53
|
-
|
54
|
-
|
53
|
+
'message' => message,
|
54
|
+
'deviceId' => @device_properties.distinct_id,
|
55
|
+
'buid' => @buid.to_s
|
55
56
|
}
|
56
57
|
|
57
58
|
metadata = {
|
58
|
-
|
59
|
+
'data' => inner_data
|
59
60
|
}
|
60
61
|
|
61
62
|
ev['metaData'] = metadata
|
@@ -88,15 +89,15 @@ module Rox
|
|
88
89
|
|
89
90
|
def add_notifier(payload)
|
90
91
|
notifier = {
|
91
|
-
|
92
|
-
|
92
|
+
'name' => 'Rollout Ruby SDK',
|
93
|
+
'version' => @device_properties.lib_version
|
93
94
|
}
|
94
95
|
payload['notifier'] = notifier
|
95
96
|
end
|
96
97
|
|
97
98
|
def add_user(id, rollout_key, ev)
|
98
99
|
user = {
|
99
|
-
|
100
|
+
id => rollout_key
|
100
101
|
}
|
101
102
|
ev['user'] = user
|
102
103
|
end
|
@@ -121,13 +122,13 @@ module Rox
|
|
121
122
|
|
122
123
|
def add_app(ev)
|
123
124
|
app = {
|
124
|
-
|
125
|
-
|
125
|
+
'releaseStage' => @device_properties.rollout_environment,
|
126
|
+
'version' => @device_properties.lib_version
|
126
127
|
}
|
127
128
|
ev['app'] = app
|
128
129
|
end
|
129
130
|
|
130
|
-
STACK_TRACE_LINE_REGEX = /^((?:[a-zA-Z]:)?[^:]+):(\d+)(?::in `([^']+)')
|
131
|
+
STACK_TRACE_LINE_REGEX = /^((?:[a-zA-Z]:)?[^:]+):(\d+)(?::in `([^']+)')?$/.freeze
|
131
132
|
|
132
133
|
def parse_stack_trace(stack_trace)
|
133
134
|
stack = []
|
@@ -149,4 +150,4 @@ module Rox
|
|
149
150
|
end
|
150
151
|
end
|
151
152
|
end
|
152
|
-
end
|
153
|
+
end
|
@@ -5,9 +5,7 @@ module Rox
|
|
5
5
|
@experiments = []
|
6
6
|
end
|
7
7
|
|
8
|
-
|
9
|
-
@experiments = experiments
|
10
|
-
end
|
8
|
+
attr_writer :experiments
|
11
9
|
|
12
10
|
def experiment_by_flag(flag_name)
|
13
11
|
@experiments.detect { |e| e.flags.include?(flag_name) }
|
@@ -18,4 +16,4 @@ module Rox
|
|
18
16
|
end
|
19
17
|
end
|
20
18
|
end
|
21
|
-
end
|
19
|
+
end
|
@@ -2,29 +2,29 @@ module Rox
|
|
2
2
|
module Core
|
3
3
|
class FlagRepository
|
4
4
|
def initialize
|
5
|
-
@
|
5
|
+
@strings = {}
|
6
6
|
@flag_added_handlers = []
|
7
7
|
@mutex = Mutex.new
|
8
8
|
@handlers_mutex = Mutex.new
|
9
9
|
end
|
10
10
|
|
11
|
-
def add_flag(
|
12
|
-
|
11
|
+
def add_flag(string, name)
|
12
|
+
string.name = name if string.name.nil? || string.name.empty?
|
13
13
|
@mutex.synchronize do
|
14
|
-
@
|
14
|
+
@strings[name] = string
|
15
15
|
end
|
16
|
-
raise_flag_added_event(
|
16
|
+
raise_flag_added_event(string)
|
17
17
|
end
|
18
18
|
|
19
19
|
def flag(name)
|
20
20
|
@mutex.synchronize do
|
21
|
-
return @
|
21
|
+
return @strings[name]
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
def all_flags
|
26
26
|
@mutex.synchronize do
|
27
|
-
return @
|
27
|
+
return @strings.values
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -11,13 +11,13 @@ module Rox
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def extend
|
14
|
-
@parser.add_operator('mergeSeed') do |
|
14
|
+
@parser.add_operator('mergeSeed') do |_parser, stack, _context|
|
15
15
|
seed1 = stack.pop
|
16
16
|
seed2 = stack.pop
|
17
17
|
stack.push("#{seed1}.#{seed2}")
|
18
18
|
end
|
19
19
|
|
20
|
-
@parser.add_operator('isInPercentage') do |
|
20
|
+
@parser.add_operator('isInPercentage') do |_parser, stack, _context|
|
21
21
|
percentage = stack.pop
|
22
22
|
seed = stack.pop
|
23
23
|
|
@@ -27,7 +27,7 @@ module Rox
|
|
27
27
|
stack.push(bucket <= percentage)
|
28
28
|
end
|
29
29
|
|
30
|
-
@parser.add_operator('isInPercentageRange') do |
|
30
|
+
@parser.add_operator('isInPercentageRange') do |_parser, stack, _context|
|
31
31
|
percentage_low = stack.pop
|
32
32
|
percentage_high = stack.pop
|
33
33
|
seed = stack.pop
|
@@ -42,17 +42,17 @@ module Rox
|
|
42
42
|
@parser.add_operator('flagValue') do |parser, stack, context|
|
43
43
|
feature_flag_identifier = stack.pop
|
44
44
|
result = Flag::FLAG_FALSE_VALUE
|
45
|
-
|
45
|
+
string = @flags_repository.flag(feature_flag_identifier)
|
46
46
|
|
47
|
-
if
|
48
|
-
result = variant.value(context)
|
49
|
-
else
|
47
|
+
if string.nil?
|
50
48
|
flags_experiment = @experiment_repository.experiment_by_flag(feature_flag_identifier)
|
51
49
|
|
52
50
|
if !flags_experiment.nil? && !flags_experiment.condition.nil? && !flags_experiment.condition.empty?
|
53
51
|
experiment_eval_result = parser.evaluate_expression(flags_experiment.condition, context).string_value
|
54
52
|
result = experiment_eval_result if !experiment_eval_result.nil? && !experiment_eval_result.empty?
|
55
53
|
end
|
54
|
+
else
|
55
|
+
result = string.value(context)
|
56
56
|
end
|
57
57
|
|
58
58
|
stack.push(result)
|
@@ -79,4 +79,4 @@ module Rox
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
end
|
82
|
-
end
|
82
|
+
end
|
@@ -1,26 +1,51 @@
|
|
1
1
|
require 'rox/core/roxx/token_type'
|
2
|
+
require 'rox/core/error_handling/exception_trigger'
|
3
|
+
require 'rox/core/error_handling/userspace_handler_exception'
|
2
4
|
|
3
5
|
module Rox
|
4
6
|
module Core
|
5
7
|
class PropertiesExtensions
|
6
|
-
def initialize(parser, properties_repository)
|
8
|
+
def initialize(parser, properties_repository, dynamic_property_rule_handler = nil)
|
7
9
|
@parser = parser
|
8
10
|
@properties_repository = properties_repository
|
11
|
+
@dynamic_property_rule_handler = dynamic_property_rule_handler
|
9
12
|
end
|
10
13
|
|
11
14
|
def extend
|
12
|
-
@parser.add_operator('property') do |
|
15
|
+
@parser.add_operator('property') do |_parser, stack, context|
|
13
16
|
prop_name = stack.pop.to_s
|
14
17
|
property = @properties_repository.custom_property(prop_name)
|
18
|
+
value = get_value(prop_name, property, context)
|
15
19
|
|
16
|
-
|
17
|
-
|
20
|
+
stack.push(value.nil? ? TokenType::UNDEFINED : value)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def get_value(prop_name, property, context)
|
27
|
+
if property.nil?
|
28
|
+
if @dynamic_property_rule_handler.nil?
|
29
|
+
TokenType::UNDEFINED
|
18
30
|
else
|
19
|
-
|
20
|
-
stack.push(value.nil? ? TokenType::UNDEFINED : value)
|
31
|
+
get_value_from_dynamic_property_rule_handler(prop_name, context)
|
21
32
|
end
|
33
|
+
else
|
34
|
+
get_value_from_property(property, context)
|
22
35
|
end
|
23
36
|
end
|
37
|
+
|
38
|
+
def get_value_from_dynamic_property_rule_handler(prop_name, context)
|
39
|
+
@dynamic_property_rule_handler.call(prop_name, context)
|
40
|
+
rescue StandardError => e
|
41
|
+
raise Rox::Core::UserspaceHandlerException, handler, ExceptionTrigger::DYNAMIC_PROPERTIES_RULE, e
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_value_from_property(property, context)
|
45
|
+
property.value(context)
|
46
|
+
rescue StandardError => e
|
47
|
+
raise Rox::Core::UserspaceHandlerException, handler, ExceptionTrigger::CUSTOM_PROPERTY_GENERATOR, e
|
48
|
+
end
|
24
49
|
end
|
25
50
|
end
|
26
|
-
end
|
51
|
+
end
|