optimizely-sdk 3.9.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +202 -202
  3. data/lib/optimizely/audience.rb +127 -97
  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 +539 -508
  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 +330 -321
  10. data/lib/optimizely/config_manager/project_config_manager.rb +24 -24
  11. data/lib/optimizely/config_manager/static_project_config_manager.rb +53 -47
  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 -500
  16. data/lib/optimizely/error_handler.rb +39 -39
  17. data/lib/optimizely/event/batch_event_processor.rb +235 -234
  18. data/lib/optimizely/event/entity/conversion_event.rb +44 -43
  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 -47
  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 -35
  27. data/lib/optimizely/event/entity/visitor_attribute.rb +38 -37
  28. data/lib/optimizely/event/event_factory.rb +156 -155
  29. data/lib/optimizely/event/event_processor.rb +25 -25
  30. data/lib/optimizely/event/forwarding_event_processor.rb +44 -43
  31. data/lib/optimizely/event/user_event_factory.rb +88 -88
  32. data/lib/optimizely/event_builder.rb +221 -228
  33. data/lib/optimizely/event_dispatcher.rb +71 -71
  34. data/lib/optimizely/exceptions.rb +135 -139
  35. data/lib/optimizely/helpers/constants.rb +415 -397
  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 +65 -64
  40. data/lib/optimizely/helpers/validator.rb +183 -183
  41. data/lib/optimizely/helpers/variable_type.rb +67 -67
  42. data/lib/optimizely/logger.rb +46 -45
  43. data/lib/optimizely/notification_center.rb +174 -176
  44. data/lib/optimizely/optimizely_config.rb +271 -272
  45. data/lib/optimizely/optimizely_factory.rb +181 -181
  46. data/lib/optimizely/optimizely_user_context.rb +204 -107
  47. data/lib/optimizely/params.rb +31 -31
  48. data/lib/optimizely/project_config.rb +99 -91
  49. data/lib/optimizely/semantic_version.rb +166 -166
  50. data/lib/optimizely/{custom_attribute_condition_evaluator.rb → user_condition_evaluator.rb} +391 -369
  51. data/lib/optimizely/user_profile_service.rb +35 -35
  52. data/lib/optimizely/version.rb +21 -21
  53. data/lib/optimizely.rb +1130 -1117
  54. metadata +13 -13
@@ -1,176 +1,174 @@
1
- # frozen_string_literal: true
2
-
3
- #
4
- # Copyright 2017-2019, 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 NotificationCenter
20
- # @api no-doc
21
- attr_reader :notifications, :notification_id
22
-
23
- NOTIFICATION_TYPES = {
24
- # DEPRECATED: ACTIVATE notification type is deprecated since relase 3.1.0.
25
- ACTIVATE: 'ACTIVATE: experiment, user_id, attributes, variation, event',
26
- DECISION: 'DECISION: type, user_id, attributes, decision_info',
27
- LOG_EVENT: 'LOG_EVENT: type, log_event',
28
- OPTIMIZELY_CONFIG_UPDATE: 'optimizely_config_update',
29
- TRACK: 'TRACK: event_key, user_id, attributes, event_tags, event'
30
- }.freeze
31
-
32
- def initialize(logger, error_handler)
33
- @notification_id = 1
34
- @notifications = {}
35
- NOTIFICATION_TYPES.each_value { |value| @notifications[value] = [] }
36
- @logger = logger
37
- @error_handler = error_handler
38
- end
39
-
40
- # Adds notification callback to the notification center
41
- #
42
- # @param notification_type - One of the constants in NOTIFICATION_TYPES
43
- # @param notification_callback [lambda, Method, Callable] (default: block) - Called when the event is sent
44
- # @yield Block to be used as callback if callback omitted.
45
- #
46
- # @return [notification ID] Used to remove the notification
47
-
48
- def add_notification_listener(notification_type, notification_callback = nil, &block)
49
- return nil unless notification_type_valid?(notification_type)
50
-
51
- if notification_callback && block_given?
52
- @logger.log Logger::ERROR, 'Callback and block are mutually exclusive.'
53
- return nil
54
- end
55
-
56
- notification_callback ||= block
57
-
58
- unless notification_callback
59
- @logger.log Logger::ERROR, 'Callback can not be empty.'
60
- return nil
61
- end
62
-
63
- unless notification_callback.respond_to? :call
64
- @logger.log Logger::ERROR, 'Invalid notification callback given.'
65
- return nil
66
- end
67
-
68
- @notifications[notification_type].each do |notification|
69
- return -1 if notification[:callback] == notification_callback
70
- end
71
- @notifications[notification_type].push(notification_id: @notification_id, callback: notification_callback)
72
- notification_id = @notification_id
73
- @notification_id += 1
74
- notification_id
75
- end
76
-
77
- # Removes previously added notification callback
78
- #
79
- # @param notification_id
80
- #
81
- # @return [Boolean] true if found and removed, false otherwise
82
-
83
- def remove_notification_listener(notification_id)
84
- unless notification_id
85
- @logger.log Logger::ERROR, 'Notification ID can not be empty.'
86
- return nil
87
- end
88
- @notifications.each_key do |key|
89
- @notifications[key].each do |notification|
90
- if notification_id == notification[:notification_id]
91
- @notifications[key].delete(notification_id: notification_id, callback: notification[:callback])
92
- return true
93
- end
94
- end
95
- end
96
- false
97
- end
98
-
99
- # @deprecated Use {#clear_notification_listeners} instead.
100
- def clear_notifications(notification_type)
101
- @logger.log Logger::WARN, "'clear_notifications' is deprecated. Call 'clear_notification_listeners' instead."
102
- clear_notification_listeners(notification_type)
103
- end
104
-
105
- # Removes notifications for a certain notification type
106
- #
107
- # @param notification_type - one of the constants in NOTIFICATION_TYPES
108
-
109
- def clear_notification_listeners(notification_type)
110
- return nil unless notification_type_valid?(notification_type)
111
-
112
- @notifications[notification_type] = []
113
- @logger.log Logger::INFO, "All callbacks for notification type #{notification_type} have been removed."
114
- end
115
-
116
- # @deprecated Use {#clear_all_notification_listeners} instead.
117
- def clean_all_notifications
118
- @logger.log Logger::WARN, "'clean_all_notifications' is deprecated. Call 'clear_all_notification_listeners' instead."
119
- clear_all_notification_listeners
120
- end
121
-
122
- # Removes all notifications
123
- def clear_all_notification_listeners
124
- @notifications.each_key { |key| @notifications[key] = [] }
125
- end
126
-
127
- # Sends off the notification for the specific event. Uses var args to pass in a
128
- # arbitrary list of parameters according to which notification type was sent
129
- #
130
- # @param notification_type - one of the constants in NOTIFICATION_TYPES
131
- # @param args - list of arguments to the callback
132
- #
133
- # @api no-doc
134
- def send_notifications(notification_type, *args)
135
- return nil unless notification_type_valid?(notification_type)
136
-
137
- @notifications[notification_type].each do |notification|
138
- begin
139
- notification_callback = notification[:callback]
140
- notification_callback.call(*args)
141
- @logger.log Logger::INFO, "Notification #{notification_type} sent successfully."
142
- rescue => e
143
- @logger.log(Logger::ERROR, "Problem calling notify callback. Error: #{e}")
144
- return nil
145
- end
146
- end
147
- end
148
-
149
- def notification_count(notification_type)
150
- @notifications.include?(notification_type) ? @notifications[notification_type].count : 0
151
- end
152
-
153
- private
154
-
155
- def notification_type_valid?(notification_type)
156
- # Validates notification type
157
-
158
- # Args:
159
- # notification_type: one of the constants in NOTIFICATION_TYPES
160
-
161
- # Returns true if notification_type is valid, false otherwise
162
-
163
- unless notification_type
164
- @logger.log Logger::ERROR, 'Notification type can not be empty.'
165
- return false
166
- end
167
-
168
- unless @notifications.include?(notification_type)
169
- @logger.log Logger::ERROR, 'Invalid notification type.'
170
- @error_handler.handle_error InvalidNotificationType
171
- return false
172
- end
173
- true
174
- end
175
- end
176
- end
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright 2017-2019, 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
+ module Optimizely
19
+ class NotificationCenter
20
+ # @api no-doc
21
+ attr_reader :notifications, :notification_id
22
+
23
+ NOTIFICATION_TYPES = {
24
+ # DEPRECATED: ACTIVATE notification type is deprecated since relase 3.1.0.
25
+ ACTIVATE: 'ACTIVATE: experiment, user_id, attributes, variation, event',
26
+ DECISION: 'DECISION: type, user_id, attributes, decision_info',
27
+ LOG_EVENT: 'LOG_EVENT: type, log_event',
28
+ OPTIMIZELY_CONFIG_UPDATE: 'optimizely_config_update',
29
+ TRACK: 'TRACK: event_key, user_id, attributes, event_tags, event'
30
+ }.freeze
31
+
32
+ def initialize(logger, error_handler)
33
+ @notification_id = 1
34
+ @notifications = {}
35
+ NOTIFICATION_TYPES.each_value { |value| @notifications[value] = [] }
36
+ @logger = logger
37
+ @error_handler = error_handler
38
+ end
39
+
40
+ # Adds notification callback to the notification center
41
+ #
42
+ # @param notification_type - One of the constants in NOTIFICATION_TYPES
43
+ # @param notification_callback [lambda, Method, Callable] (default: block) - Called when the event is sent
44
+ # @yield Block to be used as callback if callback omitted.
45
+ #
46
+ # @return [notification ID] Used to remove the notification
47
+
48
+ def add_notification_listener(notification_type, notification_callback = nil, &block)
49
+ return nil unless notification_type_valid?(notification_type)
50
+
51
+ if notification_callback && block_given?
52
+ @logger.log Logger::ERROR, 'Callback and block are mutually exclusive.'
53
+ return nil
54
+ end
55
+
56
+ notification_callback ||= block
57
+
58
+ unless notification_callback
59
+ @logger.log Logger::ERROR, 'Callback can not be empty.'
60
+ return nil
61
+ end
62
+
63
+ unless notification_callback.respond_to? :call
64
+ @logger.log Logger::ERROR, 'Invalid notification callback given.'
65
+ return nil
66
+ end
67
+
68
+ @notifications[notification_type].each do |notification|
69
+ return -1 if notification[:callback] == notification_callback
70
+ end
71
+ @notifications[notification_type].push(notification_id: @notification_id, callback: notification_callback)
72
+ notification_id = @notification_id
73
+ @notification_id += 1
74
+ notification_id
75
+ end
76
+
77
+ # Removes previously added notification callback
78
+ #
79
+ # @param notification_id
80
+ #
81
+ # @return [Boolean] true if found and removed, false otherwise
82
+
83
+ def remove_notification_listener(notification_id)
84
+ unless notification_id
85
+ @logger.log Logger::ERROR, 'Notification ID can not be empty.'
86
+ return nil
87
+ end
88
+ @notifications.each_key do |key|
89
+ @notifications[key].each do |notification|
90
+ if notification_id == notification[:notification_id]
91
+ @notifications[key].delete(notification_id: notification_id, callback: notification[:callback])
92
+ return true
93
+ end
94
+ end
95
+ end
96
+ false
97
+ end
98
+
99
+ # @deprecated Use {#clear_notification_listeners} instead.
100
+ def clear_notifications(notification_type)
101
+ @logger.log Logger::WARN, "'clear_notifications' is deprecated. Call 'clear_notification_listeners' instead."
102
+ clear_notification_listeners(notification_type)
103
+ end
104
+
105
+ # Removes notifications for a certain notification type
106
+ #
107
+ # @param notification_type - one of the constants in NOTIFICATION_TYPES
108
+
109
+ def clear_notification_listeners(notification_type)
110
+ return nil unless notification_type_valid?(notification_type)
111
+
112
+ @notifications[notification_type] = []
113
+ @logger.log Logger::INFO, "All callbacks for notification type #{notification_type} have been removed."
114
+ end
115
+
116
+ # @deprecated Use {#clear_all_notification_listeners} instead.
117
+ def clean_all_notifications
118
+ @logger.log Logger::WARN, "'clean_all_notifications' is deprecated. Call 'clear_all_notification_listeners' instead."
119
+ clear_all_notification_listeners
120
+ end
121
+
122
+ # Removes all notifications
123
+ def clear_all_notification_listeners
124
+ @notifications.each_key { |key| @notifications[key] = [] }
125
+ end
126
+
127
+ # Sends off the notification for the specific event. Uses var args to pass in a
128
+ # arbitrary list of parameters according to which notification type was sent
129
+ #
130
+ # @param notification_type - one of the constants in NOTIFICATION_TYPES
131
+ # @param args - list of arguments to the callback
132
+ #
133
+ # @api no-doc
134
+ def send_notifications(notification_type, *args)
135
+ return nil unless notification_type_valid?(notification_type)
136
+
137
+ @notifications[notification_type].each do |notification|
138
+ notification_callback = notification[:callback]
139
+ notification_callback.call(*args)
140
+ @logger.log Logger::INFO, "Notification #{notification_type} sent successfully."
141
+ rescue => e
142
+ @logger.log(Logger::ERROR, "Problem calling notify callback. Error: #{e}")
143
+ return nil
144
+ end
145
+ end
146
+
147
+ def notification_count(notification_type)
148
+ @notifications.include?(notification_type) ? @notifications[notification_type].count : 0
149
+ end
150
+
151
+ private
152
+
153
+ def notification_type_valid?(notification_type)
154
+ # Validates notification type
155
+
156
+ # Args:
157
+ # notification_type: one of the constants in NOTIFICATION_TYPES
158
+
159
+ # Returns true if notification_type is valid, false otherwise
160
+
161
+ unless notification_type
162
+ @logger.log Logger::ERROR, 'Notification type can not be empty.'
163
+ return false
164
+ end
165
+
166
+ unless @notifications.include?(notification_type)
167
+ @logger.log Logger::ERROR, 'Invalid notification type.'
168
+ @error_handler.handle_error InvalidNotificationType
169
+ return false
170
+ end
171
+ true
172
+ end
173
+ end
174
+ end