optimizely-sdk 4.0.1 → 5.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.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/lib/optimizely/audience.rb +7 -7
- data/lib/optimizely/bucketer.rb +2 -2
- data/lib/optimizely/config/datafile_project_config.rb +58 -39
- data/lib/optimizely/config_manager/http_project_config_manager.rb +20 -10
- data/lib/optimizely/config_manager/project_config_manager.rb +2 -1
- data/lib/optimizely/config_manager/static_project_config_manager.rb +5 -3
- data/lib/optimizely/event/event_factory.rb +2 -2
- data/lib/optimizely/event_builder.rb +13 -13
- data/lib/optimizely/event_dispatcher.rb +2 -4
- data/lib/optimizely/exceptions.rb +69 -11
- data/lib/optimizely/helpers/constants.rb +45 -1
- data/lib/optimizely/helpers/http_utils.rb +3 -0
- data/lib/optimizely/helpers/sdk_settings.rb +61 -0
- data/lib/optimizely/helpers/validator.rb +54 -1
- data/lib/optimizely/notification_center_registry.rb +71 -0
- data/lib/optimizely/odp/lru_cache.rb +114 -0
- data/lib/optimizely/odp/odp_config.rb +102 -0
- data/lib/optimizely/odp/odp_event.rb +75 -0
- data/lib/optimizely/odp/odp_event_api_manager.rb +70 -0
- data/lib/optimizely/odp/odp_event_manager.rb +286 -0
- data/lib/optimizely/odp/odp_manager.rb +159 -0
- data/lib/optimizely/odp/odp_segment_api_manager.rb +122 -0
- data/lib/optimizely/odp/odp_segment_manager.rb +97 -0
- data/lib/optimizely/optimizely_config.rb +4 -2
- data/lib/optimizely/optimizely_factory.rb +17 -14
- data/lib/optimizely/optimizely_user_context.rb +40 -6
- data/lib/optimizely/user_condition_evaluator.rb +1 -1
- data/lib/optimizely/version.rb +2 -2
- data/lib/optimizely.rb +155 -23
- metadata +15 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7249ff9bec6f12c00a9a873df03e6f91c9692bcbe2388e87ea9a6a6f1472fbf5
|
4
|
+
data.tar.gz: 902fa025d32f1224833fa25f13158817ff3129244819a170ee3d907812290709
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b96a27927fd78a3d789b9edbb2c8488ba499c4f00220f08f9d9463691f38580db04f5dc6f7278873301a6c7217c54a9cf4f38d400b9feba196b7df70ec173e33
|
7
|
+
data.tar.gz: 368c9b5f096c8773c4bac487b8d6198ade424dde1ea6295449eaee3ecf5c0b4f7e2ab6b88a8bac4ab5ed2a2dce31f3ca24ef8c8596faae34cdae18aebfcdab79
|
data/LICENSE
CHANGED
@@ -187,7 +187,7 @@
|
|
187
187
|
same "printed page" as the copyright notice for easier
|
188
188
|
identification within third-party archives.
|
189
189
|
|
190
|
-
|
190
|
+
© Optimizely 2016
|
191
191
|
|
192
192
|
Licensed under the Apache License, Version 2.0 (the "License");
|
193
193
|
you may not use this file except in compliance with the License.
|
data/lib/optimizely/audience.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#
|
4
|
-
# Copyright 2016-2017, 2019-2020, Optimizely and contributors
|
4
|
+
# Copyright 2016-2017, 2019-2020, 2023, Optimizely and contributors
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -59,7 +59,7 @@ module Optimizely
|
|
59
59
|
user_condition_evaluator = UserConditionEvaluator.new(user_context, logger)
|
60
60
|
|
61
61
|
evaluate_user_conditions = lambda do |condition|
|
62
|
-
|
62
|
+
user_condition_evaluator.evaluate(condition)
|
63
63
|
end
|
64
64
|
|
65
65
|
evaluate_audience = lambda do |audience_id|
|
@@ -112,12 +112,12 @@ module Optimizely
|
|
112
112
|
# Returns array of segment names.
|
113
113
|
segments = []
|
114
114
|
|
115
|
-
conditions
|
116
|
-
|
117
|
-
|
115
|
+
case conditions
|
116
|
+
when Hash
|
117
|
+
segments.push(conditions['value']) if conditions.fetch('match', nil) == 'qualified'
|
118
|
+
when Array
|
119
|
+
conditions.each do |condition|
|
118
120
|
segments.concat @parse_segments.call(condition)
|
119
|
-
when Hash
|
120
|
-
segments.push(condition['value']) if condition.fetch('match', nil) == 'qualified'
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
data/lib/optimizely/bucketer.rb
CHANGED
@@ -110,8 +110,8 @@ module Optimizely
|
|
110
110
|
# parent_id - String entity ID to use for bucketing ID
|
111
111
|
# traffic_allocations - Array of traffic allocations
|
112
112
|
#
|
113
|
-
# Returns
|
114
|
-
# or nil if no match is found. The second value contains the array of reasons stating how the
|
113
|
+
# Returns an array of two values where first value is the entity ID corresponding to the provided bucket value
|
114
|
+
# or nil if no match is found. The second value contains the array of reasons stating how the decision was taken
|
115
115
|
decide_reasons = []
|
116
116
|
bucketing_key = format(BUCKETING_ID_TEMPLATE, bucketing_id: bucketing_id, entity_id: parent_id)
|
117
117
|
bucket_value = generate_bucket_value(bucketing_key)
|
@@ -93,7 +93,7 @@ module Optimizely
|
|
93
93
|
@experiment_key_map = generate_key_map(@experiments, 'key')
|
94
94
|
@experiment_id_map = generate_key_map(@experiments, 'id')
|
95
95
|
@audience_id_map = generate_key_map(@audiences, 'id')
|
96
|
-
@integration_key_map = generate_key_map(@integrations, 'key')
|
96
|
+
@integration_key_map = generate_key_map(@integrations, 'key', first_value: true)
|
97
97
|
@audience_id_map = @audience_id_map.merge(generate_key_map(@typed_audiences, 'id')) unless @typed_audiences.empty?
|
98
98
|
@variation_id_map = {}
|
99
99
|
@variation_key_map = {}
|
@@ -184,20 +184,19 @@ module Optimizely
|
|
184
184
|
# skip_json_validation - Optional boolean param which allows skipping JSON schema
|
185
185
|
# validation upon object invocation. By default JSON schema validation will be performed.
|
186
186
|
# Returns instance of DatafileProjectConfig, nil otherwise.
|
187
|
+
logger ||= SimpleLogger.new
|
187
188
|
if !skip_json_validation && !Helpers::Validator.datafile_valid?(datafile)
|
188
|
-
|
189
|
-
default_logger.log(Logger::ERROR, InvalidInputError.new('datafile').message)
|
189
|
+
logger.log(Logger::ERROR, InvalidInputError.new('datafile').message)
|
190
190
|
return nil
|
191
191
|
end
|
192
192
|
|
193
193
|
begin
|
194
194
|
config = new(datafile, logger, error_handler)
|
195
195
|
rescue StandardError => e
|
196
|
-
default_logger = SimpleLogger.new
|
197
196
|
error_to_handle = e.instance_of?(InvalidDatafileVersionError) ? e : InvalidInputError.new('datafile')
|
198
197
|
error_msg = error_to_handle.message
|
199
198
|
|
200
|
-
|
199
|
+
logger.log(Logger::ERROR, error_msg)
|
201
200
|
error_handler.handle_error error_to_handle
|
202
201
|
return nil
|
203
202
|
end
|
@@ -224,8 +223,9 @@ module Optimizely
|
|
224
223
|
experiment = @experiment_key_map[experiment_key]
|
225
224
|
return experiment if experiment
|
226
225
|
|
227
|
-
|
228
|
-
@
|
226
|
+
invalid_experiment_error = InvalidExperimentError.new(experiment_key: experiment_key)
|
227
|
+
@logger.log Logger::ERROR, invalid_experiment_error.message
|
228
|
+
@error_handler.handle_error invalid_experiment_error
|
229
229
|
nil
|
230
230
|
end
|
231
231
|
|
@@ -239,8 +239,9 @@ module Optimizely
|
|
239
239
|
experiment = @experiment_id_map[experiment_id]
|
240
240
|
return experiment if experiment
|
241
241
|
|
242
|
-
|
243
|
-
@
|
242
|
+
invalid_experiment_error = InvalidExperimentError.new(experiment_id: experiment_id)
|
243
|
+
@logger.log Logger::ERROR, invalid_experiment_error.message
|
244
|
+
@error_handler.handle_error invalid_experiment_error
|
244
245
|
nil
|
245
246
|
end
|
246
247
|
|
@@ -254,8 +255,9 @@ module Optimizely
|
|
254
255
|
experiment = @experiment_id_map[experiment_id]
|
255
256
|
return experiment['key'] unless experiment.nil?
|
256
257
|
|
257
|
-
|
258
|
-
@
|
258
|
+
invalid_experiment_error = InvalidExperimentError.new(experiment_id: experiment_id)
|
259
|
+
@logger.log Logger::ERROR, invalid_experiment_error.message
|
260
|
+
@error_handler.handle_error invalid_experiment_error
|
259
261
|
nil
|
260
262
|
end
|
261
263
|
|
@@ -269,8 +271,9 @@ module Optimizely
|
|
269
271
|
event = @event_key_map[event_key]
|
270
272
|
return event if event
|
271
273
|
|
272
|
-
|
273
|
-
@
|
274
|
+
invalid_event_error = InvalidEventError.new(event_key)
|
275
|
+
@logger.log Logger::ERROR, invalid_event_error.message
|
276
|
+
@error_handler.handle_error invalid_event_error
|
274
277
|
nil
|
275
278
|
end
|
276
279
|
|
@@ -284,8 +287,9 @@ module Optimizely
|
|
284
287
|
audience = @audience_id_map[audience_id]
|
285
288
|
return audience if audience
|
286
289
|
|
287
|
-
|
288
|
-
@
|
290
|
+
invalid_audience_error = InvalidAudienceError.new(audience_id)
|
291
|
+
@logger.log Logger::ERROR, invalid_audience_error.message
|
292
|
+
@error_handler.handle_error invalid_audience_error
|
289
293
|
nil
|
290
294
|
end
|
291
295
|
|
@@ -309,13 +313,15 @@ module Optimizely
|
|
309
313
|
variation = variation_id_map[variation_id]
|
310
314
|
return variation if variation
|
311
315
|
|
312
|
-
|
313
|
-
@
|
316
|
+
invalid_variation_error = InvalidVariationError.new(variation_id: variation_id)
|
317
|
+
@logger.log Logger::ERROR, invalid_variation_error.message
|
318
|
+
@error_handler.handle_error invalid_variation_error
|
314
319
|
return nil
|
315
320
|
end
|
316
321
|
|
317
|
-
|
318
|
-
@
|
322
|
+
invalid_experiment_error = InvalidExperimentError.new(experiment_key: experiment_key)
|
323
|
+
@logger.log Logger::ERROR, invalid_experiment_error.message
|
324
|
+
@error_handler.handle_error invalid_experiment_error
|
319
325
|
nil
|
320
326
|
end
|
321
327
|
|
@@ -332,13 +338,15 @@ module Optimizely
|
|
332
338
|
variation = variation_id_map_by_experiment_id[variation_id]
|
333
339
|
return variation if variation
|
334
340
|
|
335
|
-
|
336
|
-
@
|
341
|
+
invalid_variation_error = InvalidVariationError.new(variation_id: variation_id)
|
342
|
+
@logger.log Logger::ERROR, invalid_variation_error.message
|
343
|
+
@error_handler.handle_error invalid_variation_error
|
337
344
|
return nil
|
338
345
|
end
|
339
346
|
|
340
|
-
|
341
|
-
@
|
347
|
+
invalid_experiment_error = InvalidExperimentError.new(experiment_id: experiment_id)
|
348
|
+
@logger.log Logger::ERROR, invalid_experiment_error.message
|
349
|
+
@error_handler.handle_error invalid_experiment_error
|
342
350
|
nil
|
343
351
|
end
|
344
352
|
|
@@ -355,13 +363,15 @@ module Optimizely
|
|
355
363
|
variation = variation_key_map[variation_key]
|
356
364
|
return variation['id'] if variation
|
357
365
|
|
358
|
-
|
359
|
-
@
|
366
|
+
invalid_variation_error = InvalidVariationError.new(variation_key: variation_key)
|
367
|
+
@logger.log Logger::ERROR, invalid_variation_error.message
|
368
|
+
@error_handler.handle_error invalid_variation_error
|
360
369
|
return nil
|
361
370
|
end
|
362
371
|
|
363
|
-
|
364
|
-
@
|
372
|
+
invalid_experiment_error = InvalidExperimentError.new(experiment_id: experiment_id)
|
373
|
+
@logger.log Logger::ERROR, invalid_experiment_error.message
|
374
|
+
@error_handler.handle_error invalid_experiment_error
|
365
375
|
nil
|
366
376
|
end
|
367
377
|
|
@@ -378,13 +388,15 @@ module Optimizely
|
|
378
388
|
variation = variation_key_map[variation_key]
|
379
389
|
return variation['id'] if variation
|
380
390
|
|
381
|
-
|
382
|
-
@
|
391
|
+
invalid_variation_error = InvalidVariationError.new(variation_key: variation_key)
|
392
|
+
@logger.log Logger::ERROR, invalid_variation_error.message
|
393
|
+
@error_handler.handle_error invalid_variation_error
|
383
394
|
return nil
|
384
395
|
end
|
385
396
|
|
386
|
-
|
387
|
-
@
|
397
|
+
invalid_experiment_error = InvalidExperimentError.new(experiment_key: experiment_key)
|
398
|
+
@logger.log Logger::ERROR, invalid_experiment_error.message
|
399
|
+
@error_handler.handle_error invalid_experiment_error
|
388
400
|
nil
|
389
401
|
end
|
390
402
|
|
@@ -398,8 +410,9 @@ module Optimizely
|
|
398
410
|
experiment = @experiment_id_map[experiment_id]
|
399
411
|
return experiment['forcedVariations'] if experiment
|
400
412
|
|
401
|
-
|
402
|
-
@
|
413
|
+
invalid_experiment_error = InvalidExperimentError.new(experiment_id: experiment_id)
|
414
|
+
@logger.log Logger::ERROR, invalid_experiment_error.message
|
415
|
+
@error_handler.handle_error invalid_experiment_error
|
403
416
|
end
|
404
417
|
|
405
418
|
def get_attribute_id(attribute_key)
|
@@ -421,8 +434,9 @@ module Optimizely
|
|
421
434
|
end
|
422
435
|
return attribute_key if has_reserved_prefix
|
423
436
|
|
424
|
-
|
425
|
-
@
|
437
|
+
invalid_attribute_error = InvalidAttributeError.new(attribute_key)
|
438
|
+
@logger.log Logger::ERROR, invalid_attribute_error.message
|
439
|
+
@error_handler.handle_error invalid_attribute_error
|
426
440
|
nil
|
427
441
|
end
|
428
442
|
|
@@ -440,8 +454,9 @@ module Optimizely
|
|
440
454
|
variation = variation_id_map[variation_id]
|
441
455
|
return true if variation
|
442
456
|
|
443
|
-
|
444
|
-
@
|
457
|
+
invalid_variation_error = InvalidVariationError.new(variation_id: variation_id)
|
458
|
+
@logger.log Logger::ERROR, invalid_variation_error.message
|
459
|
+
@error_handler.handle_error invalid_variation_error
|
445
460
|
end
|
446
461
|
|
447
462
|
false
|
@@ -525,15 +540,19 @@ module Optimizely
|
|
525
540
|
flag_variation_map
|
526
541
|
end
|
527
542
|
|
528
|
-
def generate_key_map(array, key)
|
543
|
+
def generate_key_map(array, key, first_value: false)
|
529
544
|
# Helper method to generate map from key to hash in array of hashes
|
530
545
|
#
|
531
546
|
# array - Array consisting of hash
|
532
547
|
# key - Key in each hash which will be key in the map
|
548
|
+
# first_value - Determines which value to save if there are duplicate keys. By default the last instance of the key
|
549
|
+
# will be saved. Set to true to save the first key/value encountered.
|
533
550
|
#
|
534
551
|
# Returns map mapping key to hash
|
535
552
|
|
536
|
-
|
553
|
+
array
|
554
|
+
.group_by { |obj| obj[key] }
|
555
|
+
.transform_values { |group| first_value ? group.first : group.last }
|
537
556
|
end
|
538
557
|
end
|
539
558
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#
|
4
|
-
# Copyright 2019-2020, 2022, Optimizely and contributors
|
4
|
+
# Copyright 2019-2020, 2022-2023, Optimizely and contributors
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -33,12 +33,12 @@ module Optimizely
|
|
33
33
|
class HTTPProjectConfigManager < ProjectConfigManager
|
34
34
|
# Config manager that polls for the datafile and updated ProjectConfig based on an update interval.
|
35
35
|
|
36
|
-
attr_reader :stopped
|
36
|
+
attr_reader :stopped, :sdk_key
|
37
37
|
|
38
38
|
# Initialize config manager. One of sdk_key or url has to be set to be able to use.
|
39
39
|
#
|
40
|
-
# sdk_key - Optional string uniquely identifying the datafile. It's required unless a
|
41
|
-
# datafile
|
40
|
+
# sdk_key - Optional string uniquely identifying the datafile. It's required unless a datafile with sdk_key is passed in.
|
41
|
+
# datafile - Optional JSON string representing the project. If nil, sdk_key is required.
|
42
42
|
# polling_interval - Optional floating point number representing time interval in seconds
|
43
43
|
# at which to request datafile and set ProjectConfig.
|
44
44
|
# blocking_timeout - Optional Time in seconds to block the config call until config object has been initialized.
|
@@ -83,6 +83,10 @@ module Optimizely
|
|
83
83
|
@notification_center = notification_center.is_a?(Optimizely::NotificationCenter) ? notification_center : NotificationCenter.new(@logger, @error_handler)
|
84
84
|
@optimizely_config = nil
|
85
85
|
@config = datafile.nil? ? nil : DatafileProjectConfig.create(datafile, @logger, @error_handler, @skip_json_validation)
|
86
|
+
@sdk_key = sdk_key || @config&.sdk_key
|
87
|
+
|
88
|
+
raise MissingSdkKeyError if @sdk_key.nil?
|
89
|
+
|
86
90
|
@mutex = Mutex.new
|
87
91
|
@resource = ConditionVariable.new
|
88
92
|
@async_scheduler = AsyncScheduler.new(method(:fetch_datafile_config), @polling_interval, auto_update, @logger)
|
@@ -98,11 +102,6 @@ module Optimizely
|
|
98
102
|
end
|
99
103
|
|
100
104
|
def start!
|
101
|
-
if @stopped
|
102
|
-
@logger.log(Logger::WARN, 'Not starting. Already stopped.')
|
103
|
-
return
|
104
|
-
end
|
105
|
-
|
106
105
|
@async_scheduler.start!
|
107
106
|
@stopped = false
|
108
107
|
end
|
@@ -142,7 +141,7 @@ module Optimizely
|
|
142
141
|
end
|
143
142
|
|
144
143
|
def optimizely_config
|
145
|
-
@optimizely_config = OptimizelyConfig.new(@config).config if @optimizely_config.nil?
|
144
|
+
@optimizely_config = OptimizelyConfig.new(@config, @logger).config if @optimizely_config.nil?
|
146
145
|
|
147
146
|
@optimizely_config
|
148
147
|
end
|
@@ -222,6 +221,10 @@ module Optimizely
|
|
222
221
|
|
223
222
|
@notification_center.send_notifications(NotificationCenter::NOTIFICATION_TYPES[:OPTIMIZELY_CONFIG_UPDATE])
|
224
223
|
|
224
|
+
NotificationCenterRegistry
|
225
|
+
.get_notification_center(@sdk_key, @logger)
|
226
|
+
&.send_notifications(NotificationCenter::NOTIFICATION_TYPES[:OPTIMIZELY_CONFIG_UPDATE])
|
227
|
+
|
225
228
|
@logger.log(Logger::DEBUG, 'Received new datafile and updated config. ' \
|
226
229
|
"Old revision number: #{previous_revision}. New revision number: #{@config.revision}.")
|
227
230
|
end
|
@@ -260,6 +263,13 @@ module Optimizely
|
|
260
263
|
return
|
261
264
|
end
|
262
265
|
|
266
|
+
if polling_interval < 30
|
267
|
+
@logger.log(
|
268
|
+
Logger::WARN,
|
269
|
+
'Polling intervals below 30 seconds are not recommended.'
|
270
|
+
)
|
271
|
+
end
|
272
|
+
|
263
273
|
@polling_interval = polling_interval
|
264
274
|
end
|
265
275
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#
|
4
|
-
# Copyright 2019, Optimizely and contributors
|
4
|
+
# Copyright 2019, 2023, Optimizely and contributors
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -20,5 +20,6 @@ module Optimizely
|
|
20
20
|
# Interface for fetching ProjectConfig instance.
|
21
21
|
|
22
22
|
def config; end
|
23
|
+
def sdk_key; end
|
23
24
|
end
|
24
25
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#
|
4
|
-
# Copyright 2019-2020, 2022, Optimizely and contributors
|
4
|
+
# Copyright 2019-2020, 2022-2023, Optimizely and contributors
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -23,7 +23,7 @@ require_relative 'project_config_manager'
|
|
23
23
|
module Optimizely
|
24
24
|
class StaticProjectConfigManager < ProjectConfigManager
|
25
25
|
# Implementation of ProjectConfigManager interface.
|
26
|
-
attr_reader :config
|
26
|
+
attr_reader :config, :sdk_key
|
27
27
|
|
28
28
|
def initialize(datafile, logger, error_handler, skip_json_validation)
|
29
29
|
# Looks up and sets datafile and config based on response body.
|
@@ -41,11 +41,13 @@ module Optimizely
|
|
41
41
|
error_handler,
|
42
42
|
skip_json_validation
|
43
43
|
)
|
44
|
+
@logger = logger
|
45
|
+
@sdk_key = @config&.sdk_key
|
44
46
|
@optimizely_config = nil
|
45
47
|
end
|
46
48
|
|
47
49
|
def optimizely_config
|
48
|
-
@optimizely_config = OptimizelyConfig.new(@config).config if @optimizely_config.nil?
|
50
|
+
@optimizely_config = OptimizelyConfig.new(@config, @logger).config if @optimizely_config.nil?
|
49
51
|
|
50
52
|
@optimizely_config
|
51
53
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#
|
4
|
-
# Copyright 2019-2020, 2022, Optimizely and contributors
|
4
|
+
# Copyright 2019-2020, 2022-2023, Optimizely and contributors
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -72,7 +72,7 @@ module Optimizely
|
|
72
72
|
|
73
73
|
def build_attribute_list(user_attributes, project_config)
|
74
74
|
visitor_attributes = []
|
75
|
-
user_attributes&.
|
75
|
+
user_attributes&.each_key do |attribute_key|
|
76
76
|
# Omit attribute values that are not supported by the log endpoint.
|
77
77
|
attribute_value = user_attributes[attribute_key]
|
78
78
|
next unless Helpers::Validator.attribute_valid?(attribute_key, attribute_value)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#
|
4
|
-
# Copyright 2016-2019, 2022, Optimizely and contributors
|
4
|
+
# Copyright 2016-2019, 2022-2023, Optimizely and contributors
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -62,20 +62,20 @@ module Optimizely
|
|
62
62
|
|
63
63
|
visitor_attributes = []
|
64
64
|
|
65
|
-
attributes&.
|
65
|
+
attributes&.each_key do |attribute_key|
|
66
66
|
# Omit attribute values that are not supported by the log endpoint.
|
67
67
|
attribute_value = attributes[attribute_key]
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
68
|
+
next unless Helpers::Validator.attribute_valid?(attribute_key, attribute_value)
|
69
|
+
|
70
|
+
attribute_id = project_config.get_attribute_id attribute_key
|
71
|
+
next unless attribute_id
|
72
|
+
|
73
|
+
visitor_attributes.push(
|
74
|
+
entity_id: attribute_id,
|
75
|
+
key: attribute_key,
|
76
|
+
type: CUSTOM_ATTRIBUTE_FEATURE_TYPE,
|
77
|
+
value: attribute_value
|
78
|
+
)
|
79
79
|
end
|
80
80
|
# Append Bot Filtering Attribute
|
81
81
|
if project_config.bot_filtering == true || project_config.bot_filtering == false
|
@@ -17,6 +17,7 @@
|
|
17
17
|
#
|
18
18
|
require_relative 'exceptions'
|
19
19
|
require_relative 'helpers/http_utils'
|
20
|
+
require_relative 'helpers/constants'
|
20
21
|
|
21
22
|
module Optimizely
|
22
23
|
class NoOpEventDispatcher
|
@@ -26,9 +27,6 @@ module Optimizely
|
|
26
27
|
end
|
27
28
|
|
28
29
|
class EventDispatcher
|
29
|
-
# @api constants
|
30
|
-
REQUEST_TIMEOUT = 10
|
31
|
-
|
32
30
|
def initialize(logger: nil, error_handler: nil, proxy_config: nil)
|
33
31
|
@logger = logger || NoOpLogger.new
|
34
32
|
@error_handler = error_handler || NoOpErrorHandler.new
|
@@ -40,7 +38,7 @@ module Optimizely
|
|
40
38
|
# @param event - Event object
|
41
39
|
def dispatch_event(event)
|
42
40
|
response = Helpers::HttpUtils.make_request(
|
43
|
-
event.url, event.http_verb, event.params.to_json, event.headers, REQUEST_TIMEOUT, @proxy_config
|
41
|
+
event.url, event.http_verb, event.params.to_json, event.headers, Helpers::Constants::EVENT_DISPATCH_CONFIG[:REQUEST_TIMEOUT], @proxy_config
|
44
42
|
)
|
45
43
|
|
46
44
|
error_msg = "Event failed to dispatch with response code: #{response.code}"
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#
|
4
|
-
# Copyright 2016-2020, 2022, Optimizely and contributors
|
4
|
+
# Copyright 2016-2020, 2022-2023, Optimizely and contributors
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -25,19 +25,45 @@ module Optimizely
|
|
25
25
|
end
|
26
26
|
end
|
27
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
|
+
|
28
42
|
class InvalidAudienceError < Error
|
29
43
|
# Raised when an invalid audience is provided
|
30
44
|
|
31
|
-
|
32
|
-
|
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
|
33
53
|
end
|
34
54
|
end
|
35
55
|
|
36
56
|
class InvalidAttributeError < Error
|
37
57
|
# Raised when an invalid attribute is provided
|
38
58
|
|
39
|
-
|
40
|
-
|
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
|
41
67
|
end
|
42
68
|
end
|
43
69
|
|
@@ -60,24 +86,56 @@ module Optimizely
|
|
60
86
|
class InvalidExperimentError < Error
|
61
87
|
# Raised when an invalid experiment key is provided
|
62
88
|
|
63
|
-
|
64
|
-
|
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.")
|
65
104
|
end
|
66
105
|
end
|
67
106
|
|
68
107
|
class InvalidEventError < Error
|
69
108
|
# Raised when an invalid event key is provided
|
70
109
|
|
71
|
-
|
72
|
-
|
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
|
73
118
|
end
|
74
119
|
end
|
75
120
|
|
76
121
|
class InvalidVariationError < Error
|
77
122
|
# Raised when an invalid variation key or ID is provided
|
78
123
|
|
79
|
-
|
80
|
-
|
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.")
|
81
139
|
end
|
82
140
|
end
|
83
141
|
|