optimizely-sdk 3.0.0 → 3.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a6269e81defa38267703852ceb2e5d29de7ddad0
4
- data.tar.gz: 2bd5d9f48a01e25dea810ca7b42bfc1c63c2bf40
3
+ metadata.gz: a5bbc06065e5e4e126182cea9c01e801f3f6c3e2
4
+ data.tar.gz: a7be551c6fabb0e6f93d85e531d3d0e360403194
5
5
  SHA512:
6
- metadata.gz: a81f892eef13d1f9c28a17daf44dc320a6c075e43b24f89e70b7f5d58ef91a2db35013e86b5de2b9be90360dcf53fd8757e7c54652f30b5ded0c71e2fe2bb95d
7
- data.tar.gz: 77570a8ef7bb7dcfcbed470742686603cb361dc8fb593d737525e6b93e330084833d4c3b277c535a3c93131d1e10cf18296db70e9bb1246e915ead1456b78af9
6
+ metadata.gz: 4f24e739480c517e98df5cf98cb0412716683045e389fc253f7e4270226a235ade6f54c7a83647c5c0c4b645f84aa496a3edea70653fd4c2186e7c044c4da6e7
7
+ data.tar.gz: 702fb0aa34bd14ef60aaea54180b8a0b06772c85413574f3218c9e7b2729e8e41062da49cf2e9a3d78ae709fa1cc8ff1fc636a1aa98199b2b8bab7c0a46e82ec
data/lib/optimizely.rb CHANGED
@@ -137,18 +137,30 @@ module Optimizely
137
137
  }, @logger, Logger::ERROR
138
138
  )
139
139
 
140
+ experiment = @config.get_experiment_from_key(experiment_key)
141
+ return nil if experiment.nil?
142
+
140
143
  unless user_inputs_valid?(attributes)
141
144
  @logger.log(Logger::INFO, "Not activating user '#{user_id}.")
142
145
  return nil
143
146
  end
144
147
 
145
148
  variation_id = @decision_service.get_variation(experiment_key, user_id, attributes)
149
+ variation = @config.get_variation_from_id(experiment_key, variation_id) unless variation_id.nil?
150
+ variation_key = variation['key'] if variation
151
+ decision_notification_type = if @config.feature_experiment?(experiment['id'])
152
+ Helpers::Constants::DECISION_NOTIFICATION_TYPES['FEATURE_TEST']
153
+ else
154
+ Helpers::Constants::DECISION_NOTIFICATION_TYPES['AB_TEST']
155
+ end
156
+ @notification_center.send_notifications(
157
+ NotificationCenter::NOTIFICATION_TYPES[:DECISION],
158
+ decision_notification_type, user_id, (attributes || {}),
159
+ experiment_key: experiment_key,
160
+ variation_key: variation_key
161
+ )
146
162
 
147
- unless variation_id.nil?
148
- variation = @config.get_variation_from_id(experiment_key, variation_id)
149
- return variation['key'] if variation
150
- end
151
- nil
163
+ variation_key
152
164
  end
153
165
 
154
166
  # Force a user into a variation for a given experiment.
@@ -257,30 +269,45 @@ module Optimizely
257
269
  end
258
270
 
259
271
  decision = @decision_service.get_variation_for_feature(feature_flag, user_id, attributes)
260
- if decision.nil?
261
- @logger.log(Logger::INFO,
262
- "Feature '#{feature_flag_key}' is not enabled for user '#{user_id}'.")
263
- return false
264
- end
265
272
 
266
- variation = decision['variation']
267
- if decision.source == Optimizely::DecisionService::DECISION_SOURCE_EXPERIMENT
268
- # Send event if Decision came from an experiment.
269
- send_impression(decision.experiment, variation['key'], user_id, attributes)
270
- else
271
- @logger.log(Logger::DEBUG,
272
- "The user '#{user_id}' is not being experimented on in feature '#{feature_flag_key}'.")
273
+ feature_enabled = false
274
+ source_string = Optimizely::DecisionService::DECISION_SOURCES['ROLLOUT']
275
+ if decision.is_a?(Optimizely::DecisionService::Decision)
276
+ variation = decision['variation']
277
+ feature_enabled = variation['featureEnabled']
278
+ if decision.source == Optimizely::DecisionService::DECISION_SOURCES['FEATURE_TEST']
279
+ source_string = Optimizely::DecisionService::DECISION_SOURCES['FEATURE_TEST']
280
+ source_info = {
281
+ experiment_key: decision.experiment['key'],
282
+ variation_key: variation['key']
283
+ }
284
+ # Send event if Decision came from an experiment.
285
+ send_impression(decision.experiment, variation['key'], user_id, attributes)
286
+ else
287
+ @logger.log(Logger::DEBUG,
288
+ "The user '#{user_id}' is not being experimented on in feature '#{feature_flag_key}'.")
289
+ end
273
290
  end
274
291
 
275
- if variation['featureEnabled'] == true
292
+ @notification_center.send_notifications(
293
+ NotificationCenter::NOTIFICATION_TYPES[:DECISION],
294
+ Helpers::Constants::DECISION_NOTIFICATION_TYPES['FEATURE'],
295
+ user_id, (attributes || {}),
296
+ feature_key: feature_flag_key,
297
+ feature_enabled: feature_enabled,
298
+ source: source_string,
299
+ source_info: source_info || {}
300
+ )
301
+
302
+ if feature_enabled == true
276
303
  @logger.log(Logger::INFO,
277
304
  "Feature '#{feature_flag_key}' is enabled for user '#{user_id}'.")
278
305
  return true
279
- else
280
- @logger.log(Logger::INFO,
281
- "Feature '#{feature_flag_key}' is not enabled for user '#{user_id}'.")
282
- return false
283
306
  end
307
+
308
+ @logger.log(Logger::INFO,
309
+ "Feature '#{feature_flag_key}' is not enabled for user '#{user_id}'.")
310
+ false
284
311
  end
285
312
 
286
313
  # Gets keys of all feature flags which are enabled for the user.
@@ -461,25 +488,40 @@ module Optimizely
461
488
  # Error message logged in ProjectConfig- get_feature_flag_from_key
462
489
  return nil if variable.nil?
463
490
 
491
+ feature_enabled = false
464
492
  # Returns nil if type differs
465
493
  if variable['type'] != variable_type
466
494
  @logger.log(Logger::WARN,
467
495
  "Requested variable as type '#{variable_type}' but variable '#{variable_key}' is of type '#{variable['type']}'.")
468
496
  return nil
469
497
  else
498
+ source_string = Optimizely::DecisionService::DECISION_SOURCES['ROLLOUT']
470
499
  decision = @decision_service.get_variation_for_feature(feature_flag, user_id, attributes)
471
500
  variable_value = variable['defaultValue']
472
501
  if decision
473
502
  variation = decision['variation']
474
- variation_variable_usages = @config.variation_id_to_variable_usage_map[variation['id']]
475
- variable_id = variable['id']
476
- if variation_variable_usages&.key?(variable_id)
477
- variable_value = variation_variable_usages[variable_id]['value']
478
- @logger.log(Logger::INFO,
479
- "Got variable value '#{variable_value}' for variable '#{variable_key}' of feature flag '#{feature_flag_key}'.")
503
+ if decision['source'] == Optimizely::DecisionService::DECISION_SOURCES['FEATURE_TEST']
504
+ source_info = {
505
+ experiment_key: decision.experiment['key'],
506
+ variation_key: variation['key']
507
+ }
508
+ source_string = Optimizely::DecisionService::DECISION_SOURCES['FEATURE_TEST']
509
+ end
510
+ feature_enabled = variation['featureEnabled']
511
+ if feature_enabled == true
512
+ variation_variable_usages = @config.variation_id_to_variable_usage_map[variation['id']]
513
+ variable_id = variable['id']
514
+ if variation_variable_usages&.key?(variable_id)
515
+ variable_value = variation_variable_usages[variable_id]['value']
516
+ @logger.log(Logger::INFO,
517
+ "Got variable value '#{variable_value}' for variable '#{variable_key}' of feature flag '#{feature_flag_key}'.")
518
+ else
519
+ @logger.log(Logger::DEBUG,
520
+ "Variable '#{variable_key}' is not used in variation '#{variation['key']}'. Returning the default variable value '#{variable_value}'.")
521
+ end
480
522
  else
481
523
  @logger.log(Logger::DEBUG,
482
- "Variable '#{variable_key}' is not used in variation '#{variation['key']}'. Returning the default variable value '#{variable_value}'.")
524
+ "Feature '#{feature_flag_key}' for variation '#{variation['key']}' is not enabled. Returning the default variable value '#{variable_value}'.")
483
525
  end
484
526
  else
485
527
  @logger.log(Logger::INFO,
@@ -489,6 +531,18 @@ module Optimizely
489
531
 
490
532
  variable_value = Helpers::VariableType.cast_value_to_type(variable_value, variable_type, @logger)
491
533
 
534
+ @notification_center.send_notifications(
535
+ NotificationCenter::NOTIFICATION_TYPES[:DECISION],
536
+ Helpers::Constants::DECISION_NOTIFICATION_TYPES['FEATURE_VARIABLE'], user_id, (attributes || {}),
537
+ feature_key: feature_flag_key,
538
+ feature_enabled: feature_enabled,
539
+ source: source_string,
540
+ variable_key: variable_key,
541
+ variable_type: variable_type,
542
+ variable_value: variable_value,
543
+ source_info: source_info || {}
544
+ )
545
+
492
546
  variable_value
493
547
  end
494
548
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #
4
- # Copyright 2017-2018, Optimizely and contributors
4
+ # Copyright 2017-2019, 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.
@@ -35,8 +35,11 @@ module Optimizely
35
35
  attr_reader :config
36
36
 
37
37
  Decision = Struct.new(:experiment, :variation, :source)
38
- DECISION_SOURCE_EXPERIMENT = 'experiment'
39
- DECISION_SOURCE_ROLLOUT = 'rollout'
38
+
39
+ DECISION_SOURCES = {
40
+ 'FEATURE_TEST' => 'feature-test',
41
+ 'ROLLOUT' => 'rollout'
42
+ }.freeze
40
43
 
41
44
  def initialize(config, user_profile_service = nil)
42
45
  @config = config
@@ -172,7 +175,7 @@ module Optimizely
172
175
  Logger::INFO,
173
176
  "The user '#{user_id}' is bucketed into experiment '#{experiment_key}' of feature '#{feature_flag_key}'."
174
177
  )
175
- return Decision.new(experiment, variation, DECISION_SOURCE_EXPERIMENT)
178
+ return Decision.new(experiment, variation, DECISION_SOURCES['FEATURE_TEST'])
176
179
  end
177
180
 
178
181
  @config.logger.log(
@@ -236,7 +239,7 @@ module Optimizely
236
239
 
237
240
  # Evaluate if user satisfies the traffic allocation for this rollout rule
238
241
  variation = @bucketer.bucket(rollout_rule, bucketing_id, user_id)
239
- return Decision.new(rollout_rule, variation, DECISION_SOURCE_ROLLOUT) unless variation.nil?
242
+ return Decision.new(rollout_rule, variation, DECISION_SOURCES['ROLLOUT']) unless variation.nil?
240
243
 
241
244
  break
242
245
  end
@@ -255,7 +258,7 @@ module Optimizely
255
258
  return nil
256
259
  end
257
260
  variation = @bucketer.bucket(everyone_else_experiment, bucketing_id, user_id)
258
- return Decision.new(everyone_else_experiment, variation, DECISION_SOURCE_ROLLOUT) unless variation.nil?
261
+ return Decision.new(everyone_else_experiment, variation, DECISION_SOURCES['ROLLOUT']) unless variation.nil?
259
262
 
260
263
  nil
261
264
  end
@@ -352,6 +352,13 @@ module Optimizely
352
352
  'UNKNOWN_MATCH_TYPE' => 'Audience condition %s uses an unknown match type. You may need ' \
353
353
  'to upgrade to a newer release of the Optimizely SDK.'
354
354
  }.freeze
355
+
356
+ DECISION_NOTIFICATION_TYPES = {
357
+ 'AB_TEST' => 'ab-test',
358
+ 'FEATURE' => 'feature',
359
+ 'FEATURE_TEST' => 'feature-test',
360
+ 'FEATURE_VARIABLE' => 'feature-variable'
361
+ }.freeze
355
362
  end
356
363
  end
357
364
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #
4
- # Copyright 2017-2018, Optimizely and contributors
4
+ # Copyright 2017-2019, 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.
@@ -21,7 +21,9 @@ module Optimizely
21
21
  attr_reader :notifications, :notification_id
22
22
 
23
23
  NOTIFICATION_TYPES = {
24
+ # DEPRECATED: ACTIVATE notification type is deprecated since relase 3.1.0.
24
25
  ACTIVATE: 'ACTIVATE: experiment, user_id, attributes, variation, event',
26
+ DECISION: 'DECISION: type, user_id, attributes, decision_info',
25
27
  TRACK: 'TRACK: event_key, user_id, attributes, event_tags, event'
26
28
  }.freeze
27
29
 
@@ -47,6 +47,7 @@ module Optimizely
47
47
  attr_reader :attribute_key_map
48
48
  attr_reader :audience_id_map
49
49
  attr_reader :event_key_map
50
+ attr_reader :experiment_feature_map
50
51
  attr_reader :experiment_id_map
51
52
  attr_reader :experiment_key_map
52
53
  attr_reader :feature_flag_key_map
@@ -140,9 +141,13 @@ module Optimizely
140
141
  @variation_key_map[key] = generate_key_map(variations, 'key')
141
142
  end
142
143
  @feature_flag_key_map = generate_key_map(@feature_flags, 'key')
144
+ @experiment_feature_map = {}
143
145
  @feature_variable_key_map = {}
144
146
  @feature_flag_key_map.each do |key, feature_flag|
145
147
  @feature_variable_key_map[key] = generate_key_map(feature_flag['variables'], 'key')
148
+ feature_flag['experimentIds'].each do |experiment_id|
149
+ @experiment_feature_map[experiment_id] = [feature_flag['id']]
150
+ end
146
151
  end
147
152
  end
148
153
 
@@ -451,6 +456,16 @@ module Optimizely
451
456
  nil
452
457
  end
453
458
 
459
+ def feature_experiment?(experiment_id)
460
+ # Determines if given experiment is a feature test.
461
+ #
462
+ # experiment_id - String experiment ID
463
+ #
464
+ # Returns true if experiment belongs to any feature,
465
+ # false otherwise.
466
+ @experiment_feature_map.key?(experiment_id)
467
+ end
468
+
454
469
  private
455
470
 
456
471
  def generate_key_map(array, key)
@@ -17,5 +17,5 @@
17
17
  #
18
18
  module Optimizely
19
19
  CLIENT_ENGINE = 'ruby-sdk'
20
- VERSION = '3.0.0'
20
+ VERSION = '3.1.0'
21
21
  end
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: 3.0.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Optimizely
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-08 00:00:00.000000000 Z
11
+ date: 2019-05-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -184,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
184
184
  version: '0'
185
185
  requirements: []
186
186
  rubyforge_project:
187
- rubygems_version: 2.6.14
187
+ rubygems_version: 2.5.1
188
188
  signing_key:
189
189
  specification_version: 4
190
190
  summary: Ruby SDK for Optimizely's testing framework