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.
@@ -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&.keys&.each do |attribute_key|
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&.keys&.each do |attribute_key|
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
- if Helpers::Validator.attribute_valid?(attribute_key, attribute_value)
69
- attribute_id = project_config.get_attribute_id attribute_key
70
- if attribute_id
71
- visitor_attributes.push(
72
- entity_id: attribute_id,
73
- key: attribute_key,
74
- type: CUSTOM_ATTRIBUTE_FEATURE_TYPE,
75
- value: attribute_value
76
- )
77
- end
78
- end
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
- def initialize(msg = 'Provided audience is not in datafile.')
46
- super
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
- def initialize(msg = 'Provided attribute is not in datafile.')
54
- super
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
- def initialize(msg = 'Provided experiment is not in datafile.')
78
- super
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
- def initialize(msg = 'Provided event is not in datafile.')
86
- super
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
- def initialize(msg = 'Provided variation is not in datafile.')
94
- super
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
- segments_cache.respond_to?(:reset) &&
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
- segment_manager.respond_to?(:odp_config) &&
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, nil, logger, error_handler, nil, nil, sdk_key, config_manager, notification_center
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(nil, nil, nil, nil, nil, nil, nil, config_manager)
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
@@ -17,5 +17,5 @@
17
17
  #
18
18
  module Optimizely
19
19
  CLIENT_ENGINE = 'ruby-sdk'
20
- VERSION = '5.0.0-beta'
20
+ VERSION = '5.0.0'
21
21
  end
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( # rubocop:disable Metrics/ParameterLists
74
- datafile = nil,
75
- event_dispatcher = nil,
76
- logger = nil,
77
- error_handler = nil,
78
- skip_json_validation = false, # rubocop:disable Style/OptionalBooleanParameter
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
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.pre.beta
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: 2023-04-28 00:00:00.000000000 Z
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: '2.7'
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: 1.3.1
212
+ version: '0'
213
213
  requirements: []
214
214
  rubygems_version: 3.3.7
215
215
  signing_key: