optimizely-sdk 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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