hackle-ruby-sdk 1.0.0 → 2.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.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/lib/hackle/client.rb +186 -87
  3. data/lib/hackle/config.rb +59 -17
  4. data/lib/hackle/decision.rb +113 -0
  5. data/lib/hackle/event.rb +89 -0
  6. data/lib/hackle/internal/clock/clock.rb +47 -0
  7. data/lib/hackle/internal/concurrent/executors.rb +20 -0
  8. data/lib/hackle/internal/concurrent/schedule/scheduler.rb +12 -0
  9. data/lib/hackle/internal/concurrent/schedule/timer_scheduler.rb +30 -0
  10. data/lib/hackle/internal/config/parameter_config.rb +50 -0
  11. data/lib/hackle/internal/core/hackle_core.rb +182 -0
  12. data/lib/hackle/{decision → internal/evaluation/bucketer}/bucketer.rb +17 -15
  13. data/lib/hackle/internal/evaluation/evaluator/contextual/contextual_evaluator.rb +29 -0
  14. data/lib/hackle/internal/evaluation/evaluator/delegating/delegating_evaluator.rb +26 -0
  15. data/lib/hackle/internal/evaluation/evaluator/evaluator.rb +117 -0
  16. data/lib/hackle/internal/evaluation/evaluator/experiment/experiment_evaluation_flow_factory.rb +67 -0
  17. data/lib/hackle/internal/evaluation/evaluator/experiment/experiment_evaluator.rb +172 -0
  18. data/lib/hackle/internal/evaluation/evaluator/experiment/experiment_flow_evaluator.rb +241 -0
  19. data/lib/hackle/internal/evaluation/evaluator/experiment/experiment_resolver.rb +166 -0
  20. data/lib/hackle/internal/evaluation/evaluator/remoteconfig/remote_config_determiner.rb +48 -0
  21. data/lib/hackle/internal/evaluation/evaluator/remoteconfig/remote_config_evaluator.rb +174 -0
  22. data/lib/hackle/internal/evaluation/flow/evaluation_flow.rb +49 -0
  23. data/lib/hackle/internal/evaluation/flow/flow_evaluator.rb +11 -0
  24. data/lib/hackle/internal/evaluation/match/condition/condition_matcher.rb +11 -0
  25. data/lib/hackle/internal/evaluation/match/condition/condition_matcher_factory.rb +53 -0
  26. data/lib/hackle/internal/evaluation/match/condition/experiment/experiment_condition_matcher.rb +29 -0
  27. data/lib/hackle/internal/evaluation/match/condition/experiment/experiment_evaluator_matcher.rb +135 -0
  28. data/lib/hackle/internal/evaluation/match/condition/segment/segment_condition_matcher.rb +67 -0
  29. data/lib/hackle/internal/evaluation/match/condition/user/user_condition_matcher.rb +44 -0
  30. data/lib/hackle/internal/evaluation/match/operator/operator_matcher.rb +185 -0
  31. data/lib/hackle/internal/evaluation/match/operator/operator_matcher_factory.rb +31 -0
  32. data/lib/hackle/internal/evaluation/match/target/target_matcher.rb +31 -0
  33. data/lib/hackle/internal/evaluation/match/value/value_matcher.rb +96 -0
  34. data/lib/hackle/internal/evaluation/match/value/value_matcher_factory.rb +28 -0
  35. data/lib/hackle/internal/evaluation/match/value/value_operator_matcher.rb +59 -0
  36. data/lib/hackle/internal/event/user_event.rb +187 -0
  37. data/lib/hackle/internal/event/user_event_dispatcher.rb +156 -0
  38. data/lib/hackle/internal/event/user_event_factory.rb +58 -0
  39. data/lib/hackle/internal/event/user_event_processor.rb +181 -0
  40. data/lib/hackle/internal/http/http.rb +28 -0
  41. data/lib/hackle/internal/http/http_client.rb +48 -0
  42. data/lib/hackle/internal/identifiers/identifier_builder.rb +67 -0
  43. data/lib/hackle/internal/logger/logger.rb +31 -0
  44. data/lib/hackle/internal/model/action.rb +57 -0
  45. data/lib/hackle/internal/model/bucket.rb +58 -0
  46. data/lib/hackle/internal/model/container.rb +47 -0
  47. data/lib/hackle/internal/model/decision_reason.rb +31 -0
  48. data/lib/hackle/{models → internal/model}/event_type.rb +5 -8
  49. data/lib/hackle/internal/model/experiment.rb +194 -0
  50. data/lib/hackle/internal/model/parameter_configuration.rb +19 -0
  51. data/lib/hackle/internal/model/remote_config_parameter.rb +76 -0
  52. data/lib/hackle/internal/model/sdk.rb +23 -0
  53. data/lib/hackle/internal/model/segment.rb +61 -0
  54. data/lib/hackle/internal/model/target.rb +203 -0
  55. data/lib/hackle/internal/model/target_rule.rb +19 -0
  56. data/lib/hackle/internal/model/targeting.rb +45 -0
  57. data/lib/hackle/internal/model/value_type.rb +75 -0
  58. data/lib/hackle/internal/model/variation.rb +27 -0
  59. data/lib/hackle/internal/model/version.rb +153 -0
  60. data/lib/hackle/internal/properties/properties_builder.rb +101 -0
  61. data/lib/hackle/internal/user/hackle_user.rb +74 -0
  62. data/lib/hackle/internal/user/hackle_user_resolver.rb +27 -0
  63. data/lib/hackle/internal/workspace/http_workspace_fetcher.rb +50 -0
  64. data/lib/hackle/internal/workspace/polling_workspace_fetcher.rb +62 -0
  65. data/lib/hackle/internal/workspace/workspace.rb +353 -0
  66. data/lib/hackle/internal/workspace/workspace_fetcher.rb +18 -0
  67. data/lib/hackle/remote_config.rb +55 -0
  68. data/lib/hackle/user.rb +124 -0
  69. data/lib/hackle/version.rb +1 -11
  70. data/lib/hackle.rb +4 -69
  71. metadata +123 -53
  72. data/.gitignore +0 -11
  73. data/.rspec +0 -2
  74. data/.travis.yml +0 -7
  75. data/Gemfile +0 -6
  76. data/README.md +0 -33
  77. data/Rakefile +0 -6
  78. data/hackle-ruby-sdk.gemspec +0 -29
  79. data/lib/hackle/decision/decider.rb +0 -69
  80. data/lib/hackle/events/event_dispatcher.rb +0 -96
  81. data/lib/hackle/events/event_processor.rb +0 -126
  82. data/lib/hackle/events/user_event.rb +0 -61
  83. data/lib/hackle/http/http.rb +0 -37
  84. data/lib/hackle/models/bucket.rb +0 -26
  85. data/lib/hackle/models/event.rb +0 -26
  86. data/lib/hackle/models/experiment.rb +0 -69
  87. data/lib/hackle/models/slot.rb +0 -22
  88. data/lib/hackle/models/user.rb +0 -24
  89. data/lib/hackle/models/variation.rb +0 -21
  90. data/lib/hackle/workspaces/http_workspace_fetcher.rb +0 -24
  91. data/lib/hackle/workspaces/polling_workspace_fetcher.rb +0 -47
  92. data/lib/hackle/workspaces/workspace.rb +0 -100
@@ -0,0 +1,185 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hackle
4
+ module OperatorMatcher
5
+ # @param value [String]
6
+ # @param match_value [String]
7
+ # @return [boolean]
8
+ def string_matches(value, match_value) end
9
+
10
+ # @param value [Numeric]
11
+ # @param match_value [Numeric]
12
+ # @return [boolean]
13
+ def number_matches(value, match_value) end
14
+
15
+ # @param value [boolean]
16
+ # @param match_value [boolean]
17
+ # @return [boolean]
18
+ def boolean_matches(value, match_value) end
19
+
20
+ # @param value [Version]
21
+ # @param match_value [Version]
22
+ # @return [boolean]
23
+ def version_matches(value, match_value) end
24
+ end
25
+
26
+ class InMatcher
27
+ include OperatorMatcher
28
+
29
+ def string_matches(value, match_value)
30
+ value == match_value
31
+ end
32
+
33
+ def number_matches(value, match_value)
34
+ value == match_value
35
+ end
36
+
37
+ def boolean_matches(value, match_value)
38
+ value == match_value
39
+ end
40
+
41
+ def version_matches(value, match_value)
42
+ value == match_value
43
+ end
44
+ end
45
+
46
+ class ContainsMatcher
47
+ include OperatorMatcher
48
+
49
+ def string_matches(value, match_value)
50
+ value.include?(match_value)
51
+ end
52
+
53
+ def number_matches(_value, _match_value)
54
+ false
55
+ end
56
+
57
+ def boolean_matches(_value, _match_value)
58
+ false
59
+ end
60
+
61
+ def version_matches(_value, _match_value)
62
+ false
63
+ end
64
+ end
65
+
66
+ class StartsWithMatcher
67
+ include OperatorMatcher
68
+
69
+ def string_matches(value, match_value)
70
+ value.start_with?(match_value)
71
+ end
72
+
73
+ def number_matches(_value, _match_value)
74
+ false
75
+ end
76
+
77
+ def boolean_matches(_value, _match_value)
78
+ false
79
+ end
80
+
81
+ def version_matches(_value, _match_value)
82
+ false
83
+ end
84
+ end
85
+
86
+ class EndsWithMatcher
87
+ include OperatorMatcher
88
+
89
+ def string_matches(value, match_value)
90
+ value.end_with?(match_value)
91
+ end
92
+
93
+ def number_matches(_value, _match_value)
94
+ false
95
+ end
96
+
97
+ def boolean_matches(_value, _match_value)
98
+ false
99
+ end
100
+
101
+ def version_matches(_value, _match_value)
102
+ false
103
+ end
104
+ end
105
+
106
+ class GreaterThanMatcher
107
+ include OperatorMatcher
108
+
109
+ def string_matches(value, match_value)
110
+ value > match_value
111
+ end
112
+
113
+ def number_matches(value, match_value)
114
+ value > match_value
115
+ end
116
+
117
+ def boolean_matches(_value, _match_value)
118
+ false
119
+ end
120
+
121
+ def version_matches(value, match_value)
122
+ value > match_value
123
+ end
124
+ end
125
+
126
+ class GreaterThanOrEqualToMatcher
127
+ include OperatorMatcher
128
+
129
+ def string_matches(value, match_value)
130
+ value >= match_value
131
+ end
132
+
133
+ def number_matches(value, match_value)
134
+ value >= match_value
135
+ end
136
+
137
+ def boolean_matches(_value, _match_value)
138
+ false
139
+ end
140
+
141
+ def version_matches(value, match_value)
142
+ value >= match_value
143
+ end
144
+ end
145
+
146
+ class LessThanMatcher
147
+ include OperatorMatcher
148
+
149
+ def string_matches(value, match_value)
150
+ value < match_value
151
+ end
152
+
153
+ def number_matches(value, match_value)
154
+ value < match_value
155
+ end
156
+
157
+ def boolean_matches(_value, _match_value)
158
+ false
159
+ end
160
+
161
+ def version_matches(value, match_value)
162
+ value < match_value
163
+ end
164
+ end
165
+
166
+ class LessThanOrEqualToMatcher
167
+ include OperatorMatcher
168
+
169
+ def string_matches(value, match_value)
170
+ value <= match_value
171
+ end
172
+
173
+ def number_matches(value, match_value)
174
+ value <= match_value
175
+ end
176
+
177
+ def boolean_matches(_value, _match_value)
178
+ false
179
+ end
180
+
181
+ def version_matches(value, match_value)
182
+ value <= match_value
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'hackle/internal/model/target'
4
+ require 'hackle/internal/evaluation/match/operator/operator_matcher'
5
+
6
+ module Hackle
7
+ class OperatorMatcherFactory
8
+
9
+ def initialize
10
+ @matchers = {
11
+ TargetOperator::IN => InMatcher.new,
12
+ TargetOperator::CONTAINS => ContainsMatcher.new,
13
+ TargetOperator::STARTS_WITH => StartsWithMatcher.new,
14
+ TargetOperator::ENDS_WITH => EndsWithMatcher.new,
15
+ TargetOperator::GT => GreaterThanMatcher.new,
16
+ TargetOperator::GTE => GreaterThanOrEqualToMatcher.new,
17
+ TargetOperator::LT => LessThanMatcher.new,
18
+ TargetOperator::LTE => LessThanOrEqualToMatcher.new
19
+ }.freeze
20
+ end
21
+
22
+ # @param operator [TargetOperator]
23
+ # @return [OperatorMatcher]
24
+ def get(operator)
25
+ matcher = @matchers[operator]
26
+ raise ArgumentError, "Unsupported TargetOperator [#{operator}]" unless matcher
27
+
28
+ matcher
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hackle
4
+ class TargetMatcher
5
+
6
+ # @param condition_matcher_factory [ConditionMatcherFactory]
7
+ def initialize(condition_matcher_factory:)
8
+ # @type [ConditionMatcherFactory]
9
+ @condition_matcher_factory = condition_matcher_factory
10
+ end
11
+
12
+ # @param request [EvaluatorRequest]
13
+ # @param context [EvaluatorContext]
14
+ # @param target [Target]
15
+ # @return [boolean]
16
+ def matches(request, context, target)
17
+ target.conditions.all? { |it| condition_matches(request, context, it) }
18
+ end
19
+
20
+ private
21
+
22
+ # @param request [EvaluatorRequest]
23
+ # @param context [EvaluatorContext]
24
+ # @param condition [TargetCondition]
25
+ # @return [boolean]
26
+ def condition_matches(request, context, condition)
27
+ condition_matcher = @condition_matcher_factory.get(condition.key.type)
28
+ condition_matcher.matches(request, context, condition)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'hackle/internal/model/version'
4
+
5
+ module Hackle
6
+ module ValueMatcher
7
+ # @param operator_matcher [OperatorMatcher]
8
+ # @param value [Object]
9
+ # @param match_value [Object]
10
+ # @return [boolean]
11
+ def matches(operator_matcher, value, match_value) end
12
+ end
13
+
14
+ class StringMatcher
15
+ include ValueMatcher
16
+
17
+ def matches(operator_matcher, value, match_value)
18
+ type_value = as_string(value)
19
+ type_match_value = as_string(match_value)
20
+ return false if type_value.nil? || type_match_value.nil?
21
+
22
+ operator_matcher.string_matches(type_value, type_match_value)
23
+ end
24
+
25
+ private
26
+
27
+ # @param value [Object]
28
+ # @return [String, nil]
29
+ # noinspection RubyMismatchedReturnType
30
+ def as_string(value)
31
+ return value if value.is_a?(String)
32
+ return value.to_s if value.is_a?(Numeric)
33
+
34
+ nil
35
+ end
36
+ end
37
+
38
+ class NumberMatcher
39
+ include ValueMatcher
40
+
41
+ def matches(operator_matcher, value, match_value)
42
+ type_value = as_number(value)
43
+ type_match_value = as_number(match_value)
44
+ return false if type_value.nil? || type_match_value.nil?
45
+
46
+ operator_matcher.number_matches(type_value, type_match_value)
47
+ end
48
+
49
+ private
50
+
51
+ # @param value [Object]
52
+ # @return [Numeric, nil]
53
+ # noinspection RubyMismatchedReturnType
54
+ def as_number(value)
55
+ return value if value.is_a?(Numeric)
56
+ return Float(value, exception: false) if value.is_a?(String)
57
+
58
+ nil
59
+ end
60
+ end
61
+
62
+ class BooleanMatcher
63
+ include ValueMatcher
64
+
65
+ def matches(operator_matcher, value, match_value)
66
+ type_value = as_boolean(value)
67
+ type_match_value = as_boolean(match_value)
68
+ return false if type_value.nil? || type_match_value.nil?
69
+
70
+ operator_matcher.boolean_matches(type_value, type_match_value)
71
+ end
72
+
73
+ private
74
+
75
+ # @param value [Object]
76
+ # @return [boolean, nil]
77
+ def as_boolean(value)
78
+ return true if value.is_a?(TrueClass)
79
+ return false if value.is_a?(FalseClass)
80
+
81
+ nil
82
+ end
83
+ end
84
+
85
+ class VersionMatcher
86
+ include ValueMatcher
87
+
88
+ def matches(operator_matcher, value, match_value)
89
+ type_value = Version.parse_or_nil(value)
90
+ type_match_value = Version.parse_or_nil(match_value)
91
+ return false if type_value.nil? || type_match_value.nil?
92
+
93
+ operator_matcher.version_matches(type_value, type_match_value)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'hackle/internal/model/value_type'
4
+ require 'hackle/internal/evaluation/match/value/value_matcher'
5
+
6
+ module Hackle
7
+ class ValueMatcherFactory
8
+
9
+ def initialize
10
+ @matchers = {
11
+ ValueType::STRING => StringMatcher.new,
12
+ ValueType::NUMBER => NumberMatcher.new,
13
+ ValueType::BOOLEAN => BooleanMatcher.new,
14
+ ValueType::VERSION => VersionMatcher.new,
15
+ ValueType::JSON => StringMatcher.new
16
+ }.freeze
17
+ end
18
+
19
+ # @param value_type [ValueType]
20
+ # @return [ValueMatcher]
21
+ def get(value_type)
22
+ matcher = @matchers[value_type]
23
+ raise ArgumentError, "Unsupported ValueType [#{value_type}]" unless matcher
24
+
25
+ matcher
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'hackle/internal/model/target'
4
+
5
+ module Hackle
6
+ class ValueOperatorMatcher
7
+ # @param value_matcher_factory [ValueMatcherFactory]
8
+ # @param operator_matcher_factory [OperatorMatcherFactory]
9
+ def initialize(value_matcher_factory:, operator_matcher_factory:)
10
+ # @type [ValueMatcherFactory]
11
+ @value_matcher_factory = value_matcher_factory
12
+ # @type [OperatorMatcherFactory]
13
+ @operator_matcher_factory = operator_matcher_factory
14
+ end
15
+
16
+ # @param value [Object]
17
+ # @param match [TargetMatch]
18
+ # @return [boolean]
19
+ def matches(value, match)
20
+ value_matcher = @value_matcher_factory.get(match.value_type)
21
+ operator_matcher = @operator_matcher_factory.get(match.operator)
22
+
23
+ matches = internal_matches(value, match, value_matcher, operator_matcher)
24
+ TargetMatchType.matches(match.type, matches)
25
+ end
26
+
27
+ private
28
+
29
+ # @param value [Object]
30
+ # @param match [TargetMatch]
31
+ # @param value_matcher [ValueMatcher]
32
+ # @param operator_matcher [OperatorMatcher]
33
+ # @return [boolean]
34
+ def internal_matches(value, match, value_matcher, operator_matcher)
35
+ # noinspection RubyMismatchedArgumentType
36
+ return array_matches(value, match, value_matcher, operator_matcher) if value.is_a?(Array)
37
+
38
+ single_matches(value, match, value_matcher, operator_matcher)
39
+ end
40
+
41
+ # @param value [Object]
42
+ # @param match [TargetMatch]
43
+ # @param value_matcher [ValueMatcher]
44
+ # @param operator_matcher [OperatorMatcher]
45
+ # @return [boolean]
46
+ def single_matches(value, match, value_matcher, operator_matcher)
47
+ match.values.any? { |it| value_matcher.matches(operator_matcher, value, it) }
48
+ end
49
+
50
+ # @param values [Array<Object>]
51
+ # @param match [TargetMatch]
52
+ # @param value_matcher [ValueMatcher]
53
+ # @param operator_matcher [OperatorMatcher]
54
+ # @return [boolean]
55
+ def array_matches(values, match, value_matcher, operator_matcher)
56
+ values.any? { |it| single_matches(it, match, value_matcher, operator_matcher) }
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,187 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "securerandom"
4
+
5
+ module Hackle
6
+ class UserEvent
7
+
8
+ # @return [String]
9
+ attr_reader :insert_id
10
+
11
+ # @return [Integer]
12
+ attr_reader :timestamp
13
+
14
+ # @return [HackleUser]
15
+ attr_reader :user
16
+
17
+ # @param insert_id [String]
18
+ # @param timestamp [Integer]
19
+ # @param user [HackleUser]
20
+ def initialize(insert_id:, timestamp:, user:)
21
+ @insert_id = insert_id
22
+ @timestamp = timestamp
23
+ @user = user
24
+ end
25
+
26
+ class << self
27
+
28
+ # @param evaluation [ExperimentEvaluation]
29
+ # @param properties [Hash{String => Object}]
30
+ # @param user [HackleUser]
31
+ # @param timestamp [Integer]
32
+ # @return [Hackle::ExposureEvent]
33
+ def exposure(evaluation, properties, user, timestamp)
34
+ ExposureEvent.new(
35
+ insert_id: SecureRandom.uuid,
36
+ timestamp: timestamp,
37
+ user: user,
38
+ experiment: evaluation.experiment,
39
+ variation_id: evaluation.variation_id,
40
+ variation_key: evaluation.variation_key,
41
+ decision_reason: evaluation.reason,
42
+ properties: properties
43
+ )
44
+ end
45
+
46
+ # @param event_type [EventType]
47
+ # @param event [Event]
48
+ # @param user [HackleUser]
49
+ # @param timestamp [Integer]
50
+ # @return [Hackle::TrackEvent]
51
+ def track(event_type, event, user, timestamp)
52
+ TrackEvent.new(
53
+ insert_id: SecureRandom.uuid,
54
+ timestamp: timestamp,
55
+ user: user,
56
+ event_type: event_type,
57
+ event: event
58
+ )
59
+ end
60
+
61
+ # @param evaluation [RemoteConfigEvaluation]
62
+ # @param properties [Hash{String => Object}]
63
+ # @param user [HackleUser]
64
+ # @param timestamp [Integer]
65
+ # @return [Hackle::RemoteConfigEvent]
66
+ def remote_config(evaluation, properties, user, timestamp)
67
+ RemoteConfigEvent.new(
68
+ insert_id: SecureRandom.uuid,
69
+ timestamp: timestamp,
70
+ user: user,
71
+ parameter: evaluation.parameter,
72
+ value_id: evaluation.value_id,
73
+ decision_reason: evaluation.reason,
74
+ properties: properties
75
+ )
76
+ end
77
+ end
78
+ end
79
+
80
+ class ExposureEvent < UserEvent
81
+
82
+ # @return [Experiment]
83
+ attr_reader :experiment
84
+
85
+ # @return [Integer, nil]
86
+ attr_reader :variation_id
87
+
88
+ # @return [String]
89
+ attr_reader :variation_key
90
+
91
+ # @return [String]
92
+ attr_reader :decision_reason
93
+
94
+ # @return [Hash{String => Object}]
95
+ attr_reader :properties
96
+
97
+ # @param insert_id [String]
98
+ # @param timestamp [Integer]
99
+ # @param user [HackleUser]
100
+ # @param experiment [Experiment]
101
+ # @param variation_id [Integer, nil]
102
+ # @param variation_key [String]
103
+ # @param decision_reason [String]
104
+ # @param properties [Hash{String => Object}]
105
+ def initialize(
106
+ insert_id:,
107
+ timestamp:,
108
+ user:,
109
+ experiment:,
110
+ variation_id:,
111
+ variation_key:,
112
+ decision_reason:,
113
+ properties:
114
+ )
115
+ super(insert_id: insert_id, timestamp: timestamp, user: user)
116
+ @experiment = experiment
117
+ @variation_id = variation_id
118
+ @variation_key = variation_key
119
+ @decision_reason = decision_reason
120
+ @properties = properties
121
+ end
122
+ end
123
+
124
+ class TrackEvent < UserEvent
125
+
126
+ # @return [EventType]
127
+ attr_reader :event_type
128
+
129
+ # @return [Event]
130
+ attr_reader :event
131
+
132
+ # @param insert_id [String]
133
+ # @param timestamp [Integer]
134
+ # @param user [HackleUser]
135
+ # @param event_type [EventType]
136
+ # @param event [Event]
137
+ def initialize(
138
+ insert_id:,
139
+ timestamp:,
140
+ user:,
141
+ event_type:,
142
+ event:
143
+ )
144
+ super(insert_id: insert_id, timestamp: timestamp, user: user)
145
+ @event_type = event_type
146
+ @event = event
147
+ end
148
+ end
149
+
150
+ class RemoteConfigEvent < UserEvent
151
+
152
+ # @return [RemoteConfigParameter]
153
+ attr_reader :parameter
154
+
155
+ # @return [Integer, nil]
156
+ attr_reader :value_id
157
+
158
+ # @return [String]
159
+ attr_reader :decision_reason
160
+
161
+ # @return [Hash{String => Object}]
162
+ attr_reader :properties
163
+
164
+ # @param insert_id [String]
165
+ # @param timestamp [Integer]
166
+ # @param user [HackleUser]
167
+ # @param parameter [RemoteConfigParameter]
168
+ # @param value_id [Integer, nil]
169
+ # @param decision_reason [String]
170
+ # @param properties [Hash{String => Object}]
171
+ def initialize(
172
+ insert_id:,
173
+ timestamp:,
174
+ user:,
175
+ parameter:,
176
+ value_id:,
177
+ decision_reason:,
178
+ properties:
179
+ )
180
+ super(insert_id: insert_id, timestamp: timestamp, user: user)
181
+ @parameter = parameter
182
+ @value_id = value_id
183
+ @decision_reason = decision_reason
184
+ @properties = properties
185
+ end
186
+ end
187
+ end