optimizely-sdk 5.0.0.pre.beta → 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/LICENSE +1 -1
- data/lib/optimizely/audience.rb +2 -2
- data/lib/optimizely/bucketer.rb +2 -2
- data/lib/optimizely/config/datafile_project_config.rb +558 -542
- data/lib/optimizely/config_manager/http_project_config_manager.rb +8 -6
- data/lib/optimizely/config_manager/static_project_config_manager.rb +2 -1
- data/lib/optimizely/event/event_factory.rb +2 -2
- data/lib/optimizely/event_builder.rb +13 -13
- data/lib/optimizely/exceptions.rb +54 -10
- data/lib/optimizely/helpers/validator.rb +5 -7
- data/lib/optimizely/optimizely_config.rb +3 -1
- data/lib/optimizely/optimizely_factory.rb +14 -16
- data/lib/optimizely/version.rb +1 -1
- data/lib/optimizely.rb +15 -15
- metadata +7 -7
@@ -102,11 +102,6 @@ module Optimizely
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def start!
|
105
|
-
if @stopped
|
106
|
-
@logger.log(Logger::WARN, 'Not starting. Already stopped.')
|
107
|
-
return
|
108
|
-
end
|
109
|
-
|
110
105
|
@async_scheduler.start!
|
111
106
|
@stopped = false
|
112
107
|
end
|
@@ -146,7 +141,7 @@ module Optimizely
|
|
146
141
|
end
|
147
142
|
|
148
143
|
def optimizely_config
|
149
|
-
@optimizely_config = OptimizelyConfig.new(@config).config if @optimizely_config.nil?
|
144
|
+
@optimizely_config = OptimizelyConfig.new(@config, @logger).config if @optimizely_config.nil?
|
150
145
|
|
151
146
|
@optimizely_config
|
152
147
|
end
|
@@ -268,6 +263,13 @@ module Optimizely
|
|
268
263
|
return
|
269
264
|
end
|
270
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
|
+
|
271
273
|
@polling_interval = polling_interval
|
272
274
|
end
|
273
275
|
|
@@ -41,12 +41,13 @@ module Optimizely
|
|
41
41
|
error_handler,
|
42
42
|
skip_json_validation
|
43
43
|
)
|
44
|
+
@logger = logger
|
44
45
|
@sdk_key = @config&.sdk_key
|
45
46
|
@optimizely_config = nil
|
46
47
|
end
|
47
48
|
|
48
49
|
def optimizely_config
|
49
|
-
@optimizely_config = OptimizelyConfig.new(@config).config if @optimizely_config.nil?
|
50
|
+
@optimizely_config = OptimizelyConfig.new(@config, @logger).config if @optimizely_config.nil?
|
50
51
|
|
51
52
|
@optimizely_config
|
52
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
|
@@ -42,16 +42,28 @@ module Optimizely
|
|
42
42
|
class InvalidAudienceError < Error
|
43
43
|
# Raised when an invalid audience is provided
|
44
44
|
|
45
|
-
|
46
|
-
|
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
|
47
53
|
end
|
48
54
|
end
|
49
55
|
|
50
56
|
class InvalidAttributeError < Error
|
51
57
|
# Raised when an invalid attribute is provided
|
52
58
|
|
53
|
-
|
54
|
-
|
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
|
55
67
|
end
|
56
68
|
end
|
57
69
|
|
@@ -74,24 +86,56 @@ module Optimizely
|
|
74
86
|
class InvalidExperimentError < Error
|
75
87
|
# Raised when an invalid experiment key is provided
|
76
88
|
|
77
|
-
|
78
|
-
|
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.")
|
79
104
|
end
|
80
105
|
end
|
81
106
|
|
82
107
|
class InvalidEventError < Error
|
83
108
|
# Raised when an invalid event key is provided
|
84
109
|
|
85
|
-
|
86
|
-
|
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
|
87
118
|
end
|
88
119
|
end
|
89
120
|
|
90
121
|
class InvalidVariationError < Error
|
91
122
|
# Raised when an invalid variation key or ID is provided
|
92
123
|
|
93
|
-
|
94
|
-
|
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.")
|
95
139
|
end
|
96
140
|
end
|
97
141
|
|
@@ -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.
|
@@ -190,14 +190,13 @@ module Optimizely
|
|
190
190
|
# segments_cache - custom cache to be validated.
|
191
191
|
#
|
192
192
|
# Returns boolean depending on whether cache has required methods.
|
193
|
-
|
194
|
-
|
193
|
+
|
194
|
+
segments_cache.respond_to?(:reset) &&
|
195
195
|
segments_cache.method(:reset)&.parameters&.empty? &&
|
196
196
|
segments_cache.respond_to?(:lookup) &&
|
197
197
|
segments_cache.method(:lookup)&.parameters&.length&.positive? &&
|
198
198
|
segments_cache.respond_to?(:save) &&
|
199
199
|
segments_cache.method(:save)&.parameters&.length&.positive?
|
200
|
-
)
|
201
200
|
end
|
202
201
|
|
203
202
|
def segment_manager_valid?(segment_manager)
|
@@ -206,13 +205,12 @@ module Optimizely
|
|
206
205
|
# segment_manager - custom manager to be validated.
|
207
206
|
#
|
208
207
|
# Returns boolean depending on whether manager has required methods.
|
209
|
-
|
210
|
-
|
208
|
+
|
209
|
+
segment_manager.respond_to?(:odp_config) &&
|
211
210
|
segment_manager.respond_to?(:reset) &&
|
212
211
|
segment_manager.method(:reset)&.parameters&.empty? &&
|
213
212
|
segment_manager.respond_to?(:fetch_qualified_segments) &&
|
214
213
|
(segment_manager.method(:fetch_qualified_segments)&.parameters&.length || 0) >= 3
|
215
|
-
)
|
216
214
|
end
|
217
215
|
|
218
216
|
def event_manager_valid?(event_manager)
|
@@ -19,8 +19,9 @@ module Optimizely
|
|
19
19
|
require 'json'
|
20
20
|
class OptimizelyConfig
|
21
21
|
include Optimizely::ConditionTreeEvaluator
|
22
|
-
def initialize(project_config)
|
22
|
+
def initialize(project_config, logger = nil)
|
23
23
|
@project_config = project_config
|
24
|
+
@logger = logger || NoOpLogger.new
|
24
25
|
@rollouts = @project_config.rollouts
|
25
26
|
@audiences = []
|
26
27
|
audience_id_lookup_dict = {}
|
@@ -91,6 +92,7 @@ module Optimizely
|
|
91
92
|
|
92
93
|
def experiments_map
|
93
94
|
experiments_id_map.values.reduce({}) do |experiments_key_map, experiment|
|
95
|
+
@logger.log(Logger::WARN, "Duplicate experiment keys found in datafile: #{experiment['key']}") if experiments_key_map.key? experiment['key']
|
94
96
|
experiments_key_map.update(experiment['key'] => experiment)
|
95
97
|
end
|
96
98
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#
|
4
|
-
# Copyright 2019, 2022, Optimizely and contributors
|
4
|
+
# Copyright 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.
|
@@ -103,7 +103,7 @@ module Optimizely
|
|
103
103
|
)
|
104
104
|
|
105
105
|
Optimizely::Project.new(
|
106
|
-
datafile
|
106
|
+
datafile: datafile, logger: logger, error_handler: error_handler, sdk_key: sdk_key, config_manager: config_manager, notification_center: notification_center
|
107
107
|
)
|
108
108
|
end
|
109
109
|
|
@@ -111,7 +111,7 @@ module Optimizely
|
|
111
111
|
#
|
112
112
|
# @param config_manager - Required ConfigManagerInterface Responds to 'config' method.
|
113
113
|
def self.default_instance_with_config_manager(config_manager)
|
114
|
-
Optimizely::Project.new(
|
114
|
+
Optimizely::Project.new(config_manager: config_manager)
|
115
115
|
end
|
116
116
|
|
117
117
|
# Returns a new optimizely instance.
|
@@ -167,19 +167,17 @@ module Optimizely
|
|
167
167
|
)
|
168
168
|
|
169
169
|
Optimizely::Project.new(
|
170
|
-
datafile,
|
171
|
-
event_dispatcher,
|
172
|
-
logger,
|
173
|
-
error_handler,
|
174
|
-
skip_json_validation,
|
175
|
-
user_profile_service,
|
176
|
-
sdk_key,
|
177
|
-
config_manager,
|
178
|
-
notification_center,
|
179
|
-
event_processor,
|
180
|
-
|
181
|
-
{},
|
182
|
-
settings
|
170
|
+
datafile: datafile,
|
171
|
+
event_dispatcher: event_dispatcher,
|
172
|
+
logger: logger,
|
173
|
+
error_handler: error_handler,
|
174
|
+
skip_json_validation: skip_json_validation,
|
175
|
+
user_profile_service: user_profile_service,
|
176
|
+
sdk_key: sdk_key,
|
177
|
+
config_manager: config_manager,
|
178
|
+
notification_center: notification_center,
|
179
|
+
event_processor: event_processor,
|
180
|
+
settings: settings
|
183
181
|
)
|
184
182
|
end
|
185
183
|
end
|
data/lib/optimizely/version.rb
CHANGED
data/lib/optimizely.rb
CHANGED
@@ -70,20 +70,20 @@ module Optimizely
|
|
70
70
|
# @param event_processor_options: Optional hash of options to be passed to the default batch event processor.
|
71
71
|
# @param settings: Optional instance of OptimizelySdkSettings for sdk configuration.
|
72
72
|
|
73
|
-
def initialize(
|
74
|
-
datafile
|
75
|
-
event_dispatcher
|
76
|
-
logger
|
77
|
-
error_handler
|
78
|
-
skip_json_validation
|
79
|
-
user_profile_service
|
80
|
-
sdk_key
|
81
|
-
config_manager
|
82
|
-
notification_center
|
83
|
-
event_processor
|
84
|
-
default_decide_options
|
85
|
-
event_processor_options
|
86
|
-
settings
|
73
|
+
def initialize(
|
74
|
+
datafile: nil,
|
75
|
+
event_dispatcher: nil,
|
76
|
+
logger: nil,
|
77
|
+
error_handler: nil,
|
78
|
+
skip_json_validation: false,
|
79
|
+
user_profile_service: nil,
|
80
|
+
sdk_key: nil,
|
81
|
+
config_manager: nil,
|
82
|
+
notification_center: nil,
|
83
|
+
event_processor: nil,
|
84
|
+
default_decide_options: [],
|
85
|
+
event_processor_options: {},
|
86
|
+
settings: nil
|
87
87
|
)
|
88
88
|
@logger = logger || NoOpLogger.new
|
89
89
|
@error_handler = error_handler || NoOpErrorHandler.new
|
@@ -889,7 +889,7 @@ module Optimizely
|
|
889
889
|
if @config_manager.respond_to?(:optimizely_config)
|
890
890
|
@config_manager.optimizely_config
|
891
891
|
else
|
892
|
-
OptimizelyConfig.new(project_config).config
|
892
|
+
OptimizelyConfig.new(project_config, @logger).config
|
893
893
|
end
|
894
894
|
end
|
895
895
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: optimizely-sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0.0
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Optimizely
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -98,14 +98,14 @@ dependencies:
|
|
98
98
|
name: json-schema
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - "
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '2.6'
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - "
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '2.6'
|
111
111
|
- !ruby/object:Gem::Dependency
|
@@ -204,12 +204,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
204
204
|
requirements:
|
205
205
|
- - ">="
|
206
206
|
- !ruby/object:Gem::Version
|
207
|
-
version: '
|
207
|
+
version: '3.0'
|
208
208
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
209
209
|
requirements:
|
210
|
-
- - "
|
210
|
+
- - ">="
|
211
211
|
- !ruby/object:Gem::Version
|
212
|
-
version:
|
212
|
+
version: '0'
|
213
213
|
requirements: []
|
214
214
|
rubygems_version: 3.3.7
|
215
215
|
signing_key:
|