optimizely-sdk 5.0.0 → 5.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +202 -202
  3. data/lib/optimizely/audience.rb +127 -127
  4. data/lib/optimizely/bucketer.rb +156 -156
  5. data/lib/optimizely/condition_tree_evaluator.rb +123 -123
  6. data/lib/optimizely/config/datafile_project_config.rb +558 -558
  7. data/lib/optimizely/config/proxy_config.rb +34 -34
  8. data/lib/optimizely/config_manager/async_scheduler.rb +95 -95
  9. data/lib/optimizely/config_manager/http_project_config_manager.rb +340 -340
  10. data/lib/optimizely/config_manager/project_config_manager.rb +25 -25
  11. data/lib/optimizely/config_manager/static_project_config_manager.rb +55 -55
  12. data/lib/optimizely/decide/optimizely_decide_option.rb +28 -28
  13. data/lib/optimizely/decide/optimizely_decision.rb +60 -60
  14. data/lib/optimizely/decide/optimizely_decision_message.rb +26 -26
  15. data/lib/optimizely/decision_service.rb +563 -563
  16. data/lib/optimizely/error_handler.rb +39 -39
  17. data/lib/optimizely/event/batch_event_processor.rb +235 -235
  18. data/lib/optimizely/event/entity/conversion_event.rb +44 -44
  19. data/lib/optimizely/event/entity/decision.rb +38 -38
  20. data/lib/optimizely/event/entity/event_batch.rb +86 -86
  21. data/lib/optimizely/event/entity/event_context.rb +50 -50
  22. data/lib/optimizely/event/entity/impression_event.rb +48 -48
  23. data/lib/optimizely/event/entity/snapshot.rb +33 -33
  24. data/lib/optimizely/event/entity/snapshot_event.rb +48 -48
  25. data/lib/optimizely/event/entity/user_event.rb +22 -22
  26. data/lib/optimizely/event/entity/visitor.rb +36 -36
  27. data/lib/optimizely/event/entity/visitor_attribute.rb +38 -38
  28. data/lib/optimizely/event/event_factory.rb +156 -156
  29. data/lib/optimizely/event/event_processor.rb +25 -25
  30. data/lib/optimizely/event/forwarding_event_processor.rb +44 -44
  31. data/lib/optimizely/event/user_event_factory.rb +88 -88
  32. data/lib/optimizely/event_builder.rb +221 -221
  33. data/lib/optimizely/event_dispatcher.rb +69 -69
  34. data/lib/optimizely/exceptions.rb +193 -193
  35. data/lib/optimizely/helpers/constants.rb +459 -459
  36. data/lib/optimizely/helpers/date_time_utils.rb +30 -30
  37. data/lib/optimizely/helpers/event_tag_utils.rb +132 -132
  38. data/lib/optimizely/helpers/group.rb +31 -31
  39. data/lib/optimizely/helpers/http_utils.rb +68 -68
  40. data/lib/optimizely/helpers/sdk_settings.rb +61 -61
  41. data/lib/optimizely/helpers/validator.rb +236 -236
  42. data/lib/optimizely/helpers/variable_type.rb +67 -67
  43. data/lib/optimizely/logger.rb +46 -46
  44. data/lib/optimizely/notification_center.rb +174 -174
  45. data/lib/optimizely/notification_center_registry.rb +71 -71
  46. data/lib/optimizely/odp/lru_cache.rb +114 -114
  47. data/lib/optimizely/odp/odp_config.rb +102 -102
  48. data/lib/optimizely/odp/odp_event.rb +75 -75
  49. data/lib/optimizely/odp/odp_event_api_manager.rb +70 -70
  50. data/lib/optimizely/odp/odp_event_manager.rb +286 -286
  51. data/lib/optimizely/odp/odp_manager.rb +159 -159
  52. data/lib/optimizely/odp/odp_segment_api_manager.rb +122 -122
  53. data/lib/optimizely/odp/odp_segment_manager.rb +97 -97
  54. data/lib/optimizely/optimizely_config.rb +273 -273
  55. data/lib/optimizely/optimizely_factory.rb +184 -184
  56. data/lib/optimizely/optimizely_user_context.rb +238 -238
  57. data/lib/optimizely/params.rb +31 -31
  58. data/lib/optimizely/project_config.rb +99 -99
  59. data/lib/optimizely/semantic_version.rb +166 -166
  60. data/lib/optimizely/user_condition_evaluator.rb +391 -391
  61. data/lib/optimizely/user_profile_service.rb +35 -35
  62. data/lib/optimizely/version.rb +21 -21
  63. data/lib/optimizely.rb +1262 -1262
  64. metadata +7 -5
@@ -1,69 +1,69 @@
1
- # frozen_string_literal: true
2
-
3
- #
4
- # Copyright 2016-2017, 2019-2020, 2022 Optimizely and contributors
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
- require_relative 'exceptions'
19
- require_relative 'helpers/http_utils'
20
- require_relative 'helpers/constants'
21
-
22
- module Optimizely
23
- class NoOpEventDispatcher
24
- # Class providing dispatch_event method which does nothing.
25
-
26
- def dispatch_event(event); end
27
- end
28
-
29
- class EventDispatcher
30
- def initialize(logger: nil, error_handler: nil, proxy_config: nil)
31
- @logger = logger || NoOpLogger.new
32
- @error_handler = error_handler || NoOpErrorHandler.new
33
- @proxy_config = proxy_config
34
- end
35
-
36
- # Dispatch the event being represented by the Event object.
37
- #
38
- # @param event - Event object
39
- def dispatch_event(event)
40
- response = Helpers::HttpUtils.make_request(
41
- event.url, event.http_verb, event.params.to_json, event.headers, Helpers::Constants::EVENT_DISPATCH_CONFIG[:REQUEST_TIMEOUT], @proxy_config
42
- )
43
-
44
- error_msg = "Event failed to dispatch with response code: #{response.code}"
45
-
46
- case response.code.to_i
47
- when 400...500
48
- @logger.log(Logger::ERROR, error_msg)
49
- @error_handler.handle_error(HTTPCallError.new("HTTP Client Error: #{response.code}"))
50
-
51
- when 500...600
52
- @logger.log(Logger::ERROR, error_msg)
53
- @error_handler.handle_error(HTTPCallError.new("HTTP Server Error: #{response.code}"))
54
- else
55
- @logger.log(Logger::DEBUG, "event successfully sent with response code #{response.code}")
56
- end
57
- rescue Timeout::Error => e
58
- @logger.log(Logger::ERROR, "Request Timed out. Error: #{e}")
59
- @error_handler.handle_error(e)
60
-
61
- # Returning Timeout error to retain existing behavior.
62
- e
63
- rescue StandardError => e
64
- @logger.log(Logger::ERROR, "Event failed to dispatch. Error: #{e}")
65
- @error_handler.handle_error(e)
66
- nil
67
- end
68
- end
69
- end
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright 2016-2017, 2019-2020, 2022 Optimizely and contributors
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ require_relative 'exceptions'
19
+ require_relative 'helpers/http_utils'
20
+ require_relative 'helpers/constants'
21
+
22
+ module Optimizely
23
+ class NoOpEventDispatcher
24
+ # Class providing dispatch_event method which does nothing.
25
+
26
+ def dispatch_event(event); end
27
+ end
28
+
29
+ class EventDispatcher
30
+ def initialize(logger: nil, error_handler: nil, proxy_config: nil)
31
+ @logger = logger || NoOpLogger.new
32
+ @error_handler = error_handler || NoOpErrorHandler.new
33
+ @proxy_config = proxy_config
34
+ end
35
+
36
+ # Dispatch the event being represented by the Event object.
37
+ #
38
+ # @param event - Event object
39
+ def dispatch_event(event)
40
+ response = Helpers::HttpUtils.make_request(
41
+ event.url, event.http_verb, event.params.to_json, event.headers, Helpers::Constants::EVENT_DISPATCH_CONFIG[:REQUEST_TIMEOUT], @proxy_config
42
+ )
43
+
44
+ error_msg = "Event failed to dispatch with response code: #{response.code}"
45
+
46
+ case response.code.to_i
47
+ when 400...500
48
+ @logger.log(Logger::ERROR, error_msg)
49
+ @error_handler.handle_error(HTTPCallError.new("HTTP Client Error: #{response.code}"))
50
+
51
+ when 500...600
52
+ @logger.log(Logger::ERROR, error_msg)
53
+ @error_handler.handle_error(HTTPCallError.new("HTTP Server Error: #{response.code}"))
54
+ else
55
+ @logger.log(Logger::DEBUG, "event successfully sent with response code #{response.code}")
56
+ end
57
+ rescue Timeout::Error => e
58
+ @logger.log(Logger::ERROR, "Request Timed out. Error: #{e}")
59
+ @error_handler.handle_error(e)
60
+
61
+ # Returning Timeout error to retain existing behavior.
62
+ e
63
+ rescue StandardError => e
64
+ @logger.log(Logger::ERROR, "Event failed to dispatch. Error: #{e}")
65
+ @error_handler.handle_error(e)
66
+ nil
67
+ end
68
+ end
69
+ end
@@ -1,193 +1,193 @@
1
- # frozen_string_literal: true
2
-
3
- #
4
- # Copyright 2016-2020, 2022-2023, Optimizely and contributors
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
- module Optimizely
19
- class Error < StandardError; end
20
-
21
- class HTTPCallError < Error
22
- # Raised when a 4xx or 5xx response code is recieved.
23
- def initialize(msg = 'HTTP call resulted in a response with an error code.')
24
- super
25
- end
26
- end
27
-
28
- class HTTPUriError < Error
29
- # Raised when a provided URI is invalid.
30
- def initialize(msg = 'Provided URI was invalid.')
31
- super
32
- end
33
- end
34
-
35
- class MissingSdkKeyError < Error
36
- # Raised when a provided URI is invalid.
37
- def initialize(msg = 'SDK key not provided/cannot be found in the datafile.')
38
- super
39
- end
40
- end
41
-
42
- class InvalidAudienceError < Error
43
- # Raised when an invalid audience is provided
44
-
45
- attr_reader :audience_id
46
-
47
- def initialize(audience_id)
48
- raise ArgumentError, 'audience_id must be provided' if audience_id.nil?
49
-
50
- super("Audience id '#{audience_id}' is not in datafile.")
51
-
52
- @audience_id = audience_id
53
- end
54
- end
55
-
56
- class InvalidAttributeError < Error
57
- # Raised when an invalid attribute is provided
58
-
59
- attr_reader :attribute_key
60
-
61
- def initialize(attribute_key)
62
- raise ArgumentError, 'attribute_key must be provided' if attribute_key.nil?
63
-
64
- super("Attribute key '#{attribute_key}' is not in datafile.")
65
-
66
- @attribute_key = attribute_key
67
- end
68
- end
69
-
70
- class InvalidAttributeFormatError < Error
71
- # Raised when attributes are provided in an invalid format (e.g. not a Hash)
72
-
73
- def initialize(msg = 'Attributes provided are in an invalid format.')
74
- super
75
- end
76
- end
77
-
78
- class InvalidEventTagFormatError < Error
79
- # Raised when attributes are provided in an invalid format (e.g. not a Hash)
80
-
81
- def initialize(msg = 'Event tags provided are in an invalid format.')
82
- super
83
- end
84
- end
85
-
86
- class InvalidExperimentError < Error
87
- # Raised when an invalid experiment key is provided
88
-
89
- attr_reader :experiment_id, :experiment_key
90
-
91
- def initialize(experiment_id: nil, experiment_key: nil)
92
- raise ArgumentError, 'Either experiment_id or experiment_key must be provided.' if experiment_id.nil? && experiment_key.nil?
93
- raise ArgumentError, 'Cannot provide both experiment_id and experiment_key.' if !experiment_id.nil? && !experiment_key.nil?
94
-
95
- if experiment_id.nil?
96
- @experiment_key = experiment_key
97
- identifier = "key '#{@experiment_key}'"
98
- else
99
- @experiment_id = experiment_id
100
- identifier = "id '#{@experiment_id}'"
101
- end
102
-
103
- super("Experiment #{identifier} is not in datafile.")
104
- end
105
- end
106
-
107
- class InvalidEventError < Error
108
- # Raised when an invalid event key is provided
109
-
110
- attr_reader :event_key
111
-
112
- def initialize(event_key)
113
- raise ArgumentError, 'event_key must be provided.' if event_key.nil?
114
-
115
- super("Event key '#{event_key}' is not in datafile.")
116
-
117
- @event_key = event_key
118
- end
119
- end
120
-
121
- class InvalidVariationError < Error
122
- # Raised when an invalid variation key or ID is provided
123
-
124
- attr_reader :variation_id, :variation_key
125
-
126
- def initialize(variation_id: nil, variation_key: nil)
127
- raise ArgumentError, 'Either variation_id or variation_key must be provided.' if variation_id.nil? && variation_key.nil?
128
- raise ArgumentError, 'Cannot provide both variation_id and variation_key.' if !variation_id.nil? && !variation_key.nil?
129
-
130
- if variation_id.nil?
131
- identifier = "key '#{variation_key}'"
132
- @variation_key = variation_key
133
- else
134
- identifier = "id '#{variation_id}'"
135
- @variation_id = variation_id
136
- end
137
-
138
- super("Variation #{identifier} is not in datafile.")
139
- end
140
- end
141
-
142
- class InvalidDatafileVersionError < Error
143
- # Raised when a datafile with an unsupported version is provided
144
-
145
- def initialize(version)
146
- super("This version of the Ruby SDK does not support the given datafile version: #{version}.")
147
- end
148
- end
149
-
150
- class InvalidInputError < Error
151
- # Abstract error raised when an invalid input is provided during Project instantiation
152
-
153
- def initialize(type)
154
- super("Provided #{type} is in an invalid format.")
155
- end
156
- end
157
-
158
- class InvalidNotificationType < Error
159
- # Raised when an invalid notification type is provided
160
-
161
- def initialize(msg = 'Provided notification type is invalid.')
162
- super
163
- end
164
- end
165
-
166
- class InvalidInputsError < Error
167
- # Raised when an invalid inputs are provided during Project instantiation
168
- end
169
-
170
- class InvalidProjectConfigError < Error
171
- # Raised when a public method fails due to an invalid datafile
172
-
173
- def initialize(aborted_method)
174
- super("Optimizely instance is not valid. Failing '#{aborted_method}'.")
175
- end
176
- end
177
-
178
- class InvalidAttributeType < Error
179
- # Raised when an attribute is not provided in expected type.
180
-
181
- def initialize(msg = 'Provided attribute value is not in the expected data type.')
182
- super
183
- end
184
- end
185
-
186
- class InvalidSemanticVersion < Error
187
- # Raised when an invalid value is provided as semantic version.
188
-
189
- def initialize(msg = 'Provided semantic version is invalid.')
190
- super
191
- end
192
- end
193
- end
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright 2016-2020, 2022-2023, Optimizely and contributors
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ module Optimizely
19
+ class Error < StandardError; end
20
+
21
+ class HTTPCallError < Error
22
+ # Raised when a 4xx or 5xx response code is recieved.
23
+ def initialize(msg = 'HTTP call resulted in a response with an error code.')
24
+ super
25
+ end
26
+ end
27
+
28
+ class HTTPUriError < Error
29
+ # Raised when a provided URI is invalid.
30
+ def initialize(msg = 'Provided URI was invalid.')
31
+ super
32
+ end
33
+ end
34
+
35
+ class MissingSdkKeyError < Error
36
+ # Raised when a provided URI is invalid.
37
+ def initialize(msg = 'SDK key not provided/cannot be found in the datafile.')
38
+ super
39
+ end
40
+ end
41
+
42
+ class InvalidAudienceError < Error
43
+ # Raised when an invalid audience is provided
44
+
45
+ attr_reader :audience_id
46
+
47
+ def initialize(audience_id)
48
+ raise ArgumentError, 'audience_id must be provided' if audience_id.nil?
49
+
50
+ super("Audience id '#{audience_id}' is not in datafile.")
51
+
52
+ @audience_id = audience_id
53
+ end
54
+ end
55
+
56
+ class InvalidAttributeError < Error
57
+ # Raised when an invalid attribute is provided
58
+
59
+ attr_reader :attribute_key
60
+
61
+ def initialize(attribute_key)
62
+ raise ArgumentError, 'attribute_key must be provided' if attribute_key.nil?
63
+
64
+ super("Attribute key '#{attribute_key}' is not in datafile.")
65
+
66
+ @attribute_key = attribute_key
67
+ end
68
+ end
69
+
70
+ class InvalidAttributeFormatError < Error
71
+ # Raised when attributes are provided in an invalid format (e.g. not a Hash)
72
+
73
+ def initialize(msg = 'Attributes provided are in an invalid format.')
74
+ super
75
+ end
76
+ end
77
+
78
+ class InvalidEventTagFormatError < Error
79
+ # Raised when attributes are provided in an invalid format (e.g. not a Hash)
80
+
81
+ def initialize(msg = 'Event tags provided are in an invalid format.')
82
+ super
83
+ end
84
+ end
85
+
86
+ class InvalidExperimentError < Error
87
+ # Raised when an invalid experiment key is provided
88
+
89
+ attr_reader :experiment_id, :experiment_key
90
+
91
+ def initialize(experiment_id: nil, experiment_key: nil)
92
+ raise ArgumentError, 'Either experiment_id or experiment_key must be provided.' if experiment_id.nil? && experiment_key.nil?
93
+ raise ArgumentError, 'Cannot provide both experiment_id and experiment_key.' if !experiment_id.nil? && !experiment_key.nil?
94
+
95
+ if experiment_id.nil?
96
+ @experiment_key = experiment_key
97
+ identifier = "key '#{@experiment_key}'"
98
+ else
99
+ @experiment_id = experiment_id
100
+ identifier = "id '#{@experiment_id}'"
101
+ end
102
+
103
+ super("Experiment #{identifier} is not in datafile.")
104
+ end
105
+ end
106
+
107
+ class InvalidEventError < Error
108
+ # Raised when an invalid event key is provided
109
+
110
+ attr_reader :event_key
111
+
112
+ def initialize(event_key)
113
+ raise ArgumentError, 'event_key must be provided.' if event_key.nil?
114
+
115
+ super("Event key '#{event_key}' is not in datafile.")
116
+
117
+ @event_key = event_key
118
+ end
119
+ end
120
+
121
+ class InvalidVariationError < Error
122
+ # Raised when an invalid variation key or ID is provided
123
+
124
+ attr_reader :variation_id, :variation_key
125
+
126
+ def initialize(variation_id: nil, variation_key: nil)
127
+ raise ArgumentError, 'Either variation_id or variation_key must be provided.' if variation_id.nil? && variation_key.nil?
128
+ raise ArgumentError, 'Cannot provide both variation_id and variation_key.' if !variation_id.nil? && !variation_key.nil?
129
+
130
+ if variation_id.nil?
131
+ identifier = "key '#{variation_key}'"
132
+ @variation_key = variation_key
133
+ else
134
+ identifier = "id '#{variation_id}'"
135
+ @variation_id = variation_id
136
+ end
137
+
138
+ super("Variation #{identifier} is not in datafile.")
139
+ end
140
+ end
141
+
142
+ class InvalidDatafileVersionError < Error
143
+ # Raised when a datafile with an unsupported version is provided
144
+
145
+ def initialize(version)
146
+ super("This version of the Ruby SDK does not support the given datafile version: #{version}.")
147
+ end
148
+ end
149
+
150
+ class InvalidInputError < Error
151
+ # Abstract error raised when an invalid input is provided during Project instantiation
152
+
153
+ def initialize(type)
154
+ super("Provided #{type} is in an invalid format.")
155
+ end
156
+ end
157
+
158
+ class InvalidNotificationType < Error
159
+ # Raised when an invalid notification type is provided
160
+
161
+ def initialize(msg = 'Provided notification type is invalid.')
162
+ super
163
+ end
164
+ end
165
+
166
+ class InvalidInputsError < Error
167
+ # Raised when an invalid inputs are provided during Project instantiation
168
+ end
169
+
170
+ class InvalidProjectConfigError < Error
171
+ # Raised when a public method fails due to an invalid datafile
172
+
173
+ def initialize(aborted_method)
174
+ super("Optimizely instance is not valid. Failing '#{aborted_method}'.")
175
+ end
176
+ end
177
+
178
+ class InvalidAttributeType < Error
179
+ # Raised when an attribute is not provided in expected type.
180
+
181
+ def initialize(msg = 'Provided attribute value is not in the expected data type.')
182
+ super
183
+ end
184
+ end
185
+
186
+ class InvalidSemanticVersion < Error
187
+ # Raised when an invalid value is provided as semantic version.
188
+
189
+ def initialize(msg = 'Provided semantic version is invalid.')
190
+ super
191
+ end
192
+ end
193
+ end